OSDN Git Service

gcc/ChangeLog:
[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")
1967         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
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_SSEMOV:
1975       if (get_attr_mode (insn) == MODE_TI)
1976           return "movdqa\t{%1, %0|%0, %1}";
1977       /* FALLTHRU */
1978     case TYPE_MMXMOV:
1979       /* Moves from and into integer register is done using movd opcode with
1980          REX prefix.  */
1981       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1982           return "movd\t{%1, %0|%0, %1}";
1983       return "movq\t{%1, %0|%0, %1}";
1984     case TYPE_MULTI:
1985       return "#";
1986     case TYPE_LEA:
1987       return "lea{q}\t{%a1, %0|%0, %a1}";
1988     default:
1989       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1990         abort ();
1991       if (get_attr_mode (insn) == MODE_SI)
1992         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1993       else if (which_alternative == 2)
1994         return "movabs{q}\t{%1, %0|%0, %1}";
1995       else
1996         return "mov{q}\t{%1, %0|%0, %1}";
1997     }
1998 }
1999   [(set (attr "type")
2000      (cond [(eq_attr "alternative" "5,6,7")
2001               (const_string "mmxmov")
2002             (eq_attr "alternative" "8,9,10")
2003               (const_string "ssemov")
2004             (eq_attr "alternative" "4")
2005               (const_string "multi")
2006             (and (ne (symbol_ref "flag_pic") (const_int 0))
2007                  (match_operand:DI 1 "symbolic_operand" ""))
2008               (const_string "lea")
2009            ]
2010            (const_string "imov")))
2011    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2012    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2013    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2014
2015 (define_insn "*movdi_1_rex64_nointerunit"
2016   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2017         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2018   "TARGET_64BIT
2019    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2020    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2021 {
2022   switch (get_attr_type (insn))
2023     {
2024     case TYPE_SSEMOV:
2025       if (get_attr_mode (insn) == MODE_TI)
2026           return "movdqa\t{%1, %0|%0, %1}";
2027       /* FALLTHRU */
2028     case TYPE_MMXMOV:
2029       return "movq\t{%1, %0|%0, %1}";
2030     case TYPE_MULTI:
2031       return "#";
2032     case TYPE_LEA:
2033       return "lea{q}\t{%a1, %0|%0, %a1}";
2034     default:
2035       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2036         abort ();
2037       if (get_attr_mode (insn) == MODE_SI)
2038         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2039       else if (which_alternative == 2)
2040         return "movabs{q}\t{%1, %0|%0, %1}";
2041       else
2042         return "mov{q}\t{%1, %0|%0, %1}";
2043     }
2044 }
2045   [(set (attr "type")
2046      (cond [(eq_attr "alternative" "5,6,7")
2047               (const_string "mmxmov")
2048             (eq_attr "alternative" "8,9,10")
2049               (const_string "ssemov")
2050             (eq_attr "alternative" "4")
2051               (const_string "multi")
2052             (and (ne (symbol_ref "flag_pic") (const_int 0))
2053                  (match_operand:DI 1 "symbolic_operand" ""))
2054               (const_string "lea")
2055            ]
2056            (const_string "imov")))
2057    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2058    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2059    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2060
2061 ;; Stores and loads of ax to arbitrary constant address.
2062 ;; We fake an second form of instruction to force reload to load address
2063 ;; into register when rax is not available
2064 (define_insn "*movabsdi_1_rex64"
2065   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2066         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2067   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2068   "@
2069    movabs{q}\t{%1, %P0|%P0, %1}
2070    mov{q}\t{%1, %a0|%a0, %1}"
2071   [(set_attr "type" "imov")
2072    (set_attr "modrm" "0,*")
2073    (set_attr "length_address" "8,0")
2074    (set_attr "length_immediate" "0,*")
2075    (set_attr "memory" "store")
2076    (set_attr "mode" "DI")])
2077
2078 (define_insn "*movabsdi_2_rex64"
2079   [(set (match_operand:DI 0 "register_operand" "=a,r")
2080         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2081   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2082   "@
2083    movabs{q}\t{%P1, %0|%0, %P1}
2084    mov{q}\t{%a1, %0|%0, %a1}"
2085   [(set_attr "type" "imov")
2086    (set_attr "modrm" "0,*")
2087    (set_attr "length_address" "8,0")
2088    (set_attr "length_immediate" "0")
2089    (set_attr "memory" "load")
2090    (set_attr "mode" "DI")])
2091
2092 ;; Convert impossible stores of immediate to existing instructions.
2093 ;; First try to get scratch register and go through it.  In case this
2094 ;; fails, move by 32bit parts.
2095 (define_peephole2
2096   [(match_scratch:DI 2 "r")
2097    (set (match_operand:DI 0 "memory_operand" "")
2098         (match_operand:DI 1 "immediate_operand" ""))]
2099   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2100    && !x86_64_immediate_operand (operands[1], DImode)"
2101   [(set (match_dup 2) (match_dup 1))
2102    (set (match_dup 0) (match_dup 2))]
2103   "")
2104
2105 ;; We need to define this as both peepholer and splitter for case
2106 ;; peephole2 pass is not run.
2107 (define_peephole2
2108   [(set (match_operand:DI 0 "memory_operand" "")
2109         (match_operand:DI 1 "immediate_operand" ""))]
2110   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2111    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2112   [(set (match_dup 2) (match_dup 3))
2113    (set (match_dup 4) (match_dup 5))]
2114   "split_di (operands, 2, operands + 2, operands + 4);")
2115
2116 (define_split
2117   [(set (match_operand:DI 0 "memory_operand" "")
2118         (match_operand:DI 1 "immediate_operand" ""))]
2119   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2120    && !symbolic_operand (operands[1], DImode)
2121    && !x86_64_immediate_operand (operands[1], DImode)"
2122   [(set (match_dup 2) (match_dup 3))
2123    (set (match_dup 4) (match_dup 5))]
2124   "split_di (operands, 2, operands + 2, operands + 4);")
2125
2126 (define_insn "*swapdi_rex64"
2127   [(set (match_operand:DI 0 "register_operand" "+r")
2128         (match_operand:DI 1 "register_operand" "+r"))
2129    (set (match_dup 1)
2130         (match_dup 0))]
2131   "TARGET_64BIT"
2132   "xchg{q}\t%1, %0"
2133   [(set_attr "type" "imov")
2134    (set_attr "pent_pair" "np")
2135    (set_attr "athlon_decode" "vector")
2136    (set_attr "mode" "DI")
2137    (set_attr "modrm" "0")])
2138
2139   
2140 (define_expand "movsf"
2141   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2142         (match_operand:SF 1 "general_operand" ""))]
2143   ""
2144   "ix86_expand_move (SFmode, operands); DONE;")
2145
2146 (define_insn "*pushsf"
2147   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2148         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2149   "!TARGET_64BIT"
2150 {
2151   switch (which_alternative)
2152     {
2153     case 1:
2154       return "push{l}\t%1";
2155
2156     default:
2157       /* This insn should be already split before reg-stack.  */
2158       abort ();
2159     }
2160 }
2161   [(set_attr "type" "multi,push,multi")
2162    (set_attr "mode" "SF,SI,SF")])
2163
2164 (define_insn "*pushsf_rex64"
2165   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2166         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2167   "TARGET_64BIT"
2168 {
2169   switch (which_alternative)
2170     {
2171     case 1:
2172       return "push{q}\t%q1";
2173
2174     default:
2175       /* This insn should be already split before reg-stack.  */
2176       abort ();
2177     }
2178 }
2179   [(set_attr "type" "multi,push,multi")
2180    (set_attr "mode" "SF,DI,SF")])
2181
2182 (define_split
2183   [(set (match_operand:SF 0 "push_operand" "")
2184         (match_operand:SF 1 "memory_operand" ""))]
2185   "reload_completed
2186    && GET_CODE (operands[1]) == MEM
2187    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2188    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2189   [(set (match_dup 0)
2190         (match_dup 1))]
2191   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2192
2193
2194 ;; %%% Kill this when call knows how to work this out.
2195 (define_split
2196   [(set (match_operand:SF 0 "push_operand" "")
2197         (match_operand:SF 1 "any_fp_register_operand" ""))]
2198   "!TARGET_64BIT"
2199   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2200    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2201
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:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2207    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2208
2209 (define_insn "*movsf_1"
2210   [(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")
2211         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2212   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2213    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2214    && (reload_in_progress || reload_completed
2215        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2216        || GET_CODE (operands[1]) != CONST_DOUBLE
2217        || memory_operand (operands[0], SFmode))" 
2218 {
2219   switch (which_alternative)
2220     {
2221     case 0:
2222       return output_387_reg_move (insn, operands);
2223
2224     case 1:
2225       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2226         return "fstp%z0\t%y0";
2227       else
2228         return "fst%z0\t%y0";
2229
2230     case 2:
2231       return standard_80387_constant_opcode (operands[1]);
2232
2233     case 3:
2234     case 4:
2235       return "mov{l}\t{%1, %0|%0, %1}";
2236     case 5:
2237       if (get_attr_mode (insn) == MODE_TI)
2238         return "pxor\t%0, %0";
2239       else
2240         return "xorps\t%0, %0";
2241     case 6:
2242       if (get_attr_mode (insn) == MODE_V4SF)
2243         return "movaps\t{%1, %0|%0, %1}";
2244       else
2245         return "movss\t{%1, %0|%0, %1}";
2246     case 7:
2247     case 8:
2248       return "movss\t{%1, %0|%0, %1}";
2249
2250     case 9:
2251     case 10:
2252       return "movd\t{%1, %0|%0, %1}";
2253
2254     case 11:
2255       return "movq\t{%1, %0|%0, %1}";
2256
2257     default:
2258       abort();
2259     }
2260 }
2261   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2262    (set (attr "mode")
2263         (cond [(eq_attr "alternative" "3,4,9,10")
2264                  (const_string "SI")
2265                (eq_attr "alternative" "5")
2266                  (if_then_else
2267                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2268                                  (const_int 0))
2269                              (ne (symbol_ref "TARGET_SSE2")
2270                                  (const_int 0)))
2271                         (eq (symbol_ref "optimize_size")
2272                             (const_int 0)))
2273                    (const_string "TI")
2274                    (const_string "V4SF"))
2275                /* For architectures resolving dependencies on
2276                   whole SSE registers use APS move to break dependency
2277                   chains, otherwise use short move to avoid extra work. 
2278
2279                   Do the same for architectures resolving dependencies on
2280                   the parts.  While in DF mode it is better to always handle
2281                   just register parts, the SF mode is different due to lack
2282                   of instructions to load just part of the register.  It is
2283                   better to maintain the whole registers in single format
2284                   to avoid problems on using packed logical operations.  */
2285                (eq_attr "alternative" "6")
2286                  (if_then_else
2287                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2288                             (const_int 0))
2289                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2290                             (const_int 0)))
2291                    (const_string "V4SF")
2292                    (const_string "SF"))
2293                (eq_attr "alternative" "11")
2294                  (const_string "DI")]
2295                (const_string "SF")))])
2296
2297 (define_insn "*movsf_1_nointerunit"
2298   [(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")
2299         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2300   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2301    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2302    && (reload_in_progress || reload_completed
2303        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2304        || GET_CODE (operands[1]) != CONST_DOUBLE
2305        || memory_operand (operands[0], SFmode))" 
2306 {
2307   switch (which_alternative)
2308     {
2309     case 0:
2310       return output_387_reg_move (insn, operands);
2311
2312     case 1:
2313       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2314         return "fstp%z0\t%y0";
2315       else
2316         return "fst%z0\t%y0";
2317
2318     case 2:
2319       return standard_80387_constant_opcode (operands[1]);
2320
2321     case 3:
2322     case 4:
2323       return "mov{l}\t{%1, %0|%0, %1}";
2324     case 5:
2325       if (get_attr_mode (insn) == MODE_TI)
2326         return "pxor\t%0, %0";
2327       else
2328         return "xorps\t%0, %0";
2329     case 6:
2330       if (get_attr_mode (insn) == MODE_V4SF)
2331         return "movaps\t{%1, %0|%0, %1}";
2332       else
2333         return "movss\t{%1, %0|%0, %1}";
2334     case 7:
2335     case 8:
2336       return "movss\t{%1, %0|%0, %1}";
2337
2338     case 9:
2339     case 10:
2340       return "movd\t{%1, %0|%0, %1}";
2341
2342     case 11:
2343       return "movq\t{%1, %0|%0, %1}";
2344
2345     default:
2346       abort();
2347     }
2348 }
2349   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2350    (set (attr "mode")
2351         (cond [(eq_attr "alternative" "3,4,9,10")
2352                  (const_string "SI")
2353                (eq_attr "alternative" "5")
2354                  (if_then_else
2355                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2356                                  (const_int 0))
2357                              (ne (symbol_ref "TARGET_SSE2")
2358                                  (const_int 0)))
2359                         (eq (symbol_ref "optimize_size")
2360                             (const_int 0)))
2361                    (const_string "TI")
2362                    (const_string "V4SF"))
2363                /* For architectures resolving dependencies on
2364                   whole SSE registers use APS move to break dependency
2365                   chains, otherwise use short move to avoid extra work. 
2366
2367                   Do the same for architectures resolving dependencies on
2368                   the parts.  While in DF mode it is better to always handle
2369                   just register parts, the SF mode is different due to lack
2370                   of instructions to load just part of the register.  It is
2371                   better to maintain the whole registers in single format
2372                   to avoid problems on using packed logical operations.  */
2373                (eq_attr "alternative" "6")
2374                  (if_then_else
2375                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2376                             (const_int 0))
2377                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2378                             (const_int 0)))
2379                    (const_string "V4SF")
2380                    (const_string "SF"))
2381                (eq_attr "alternative" "11")
2382                  (const_string "DI")]
2383                (const_string "SF")))])
2384
2385 (define_insn "*swapsf"
2386   [(set (match_operand:SF 0 "register_operand" "+f")
2387         (match_operand:SF 1 "register_operand" "+f"))
2388    (set (match_dup 1)
2389         (match_dup 0))]
2390   "reload_completed || !TARGET_SSE"
2391 {
2392   if (STACK_TOP_P (operands[0]))
2393     return "fxch\t%1";
2394   else
2395     return "fxch\t%0";
2396 }
2397   [(set_attr "type" "fxch")
2398    (set_attr "mode" "SF")])
2399
2400 (define_expand "movdf"
2401   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2402         (match_operand:DF 1 "general_operand" ""))]
2403   ""
2404   "ix86_expand_move (DFmode, operands); DONE;")
2405
2406 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2407 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2408 ;; On the average, pushdf using integers can be still shorter.  Allow this
2409 ;; pattern for optimize_size too.
2410
2411 (define_insn "*pushdf_nointeger"
2412   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2413         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2414   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2415 {
2416   /* This insn should be already split before reg-stack.  */
2417   abort ();
2418 }
2419   [(set_attr "type" "multi")
2420    (set_attr "mode" "DF,SI,SI,DF")])
2421
2422 (define_insn "*pushdf_integer"
2423   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2424         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2425   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2426 {
2427   /* This insn should be already split before reg-stack.  */
2428   abort ();
2429 }
2430   [(set_attr "type" "multi")
2431    (set_attr "mode" "DF,SI,DF")])
2432
2433 ;; %%% Kill this when call knows how to work this out.
2434 (define_split
2435   [(set (match_operand:DF 0 "push_operand" "")
2436         (match_operand:DF 1 "any_fp_register_operand" ""))]
2437   "!TARGET_64BIT && reload_completed"
2438   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2439    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2440   "")
2441
2442 (define_split
2443   [(set (match_operand:DF 0 "push_operand" "")
2444         (match_operand:DF 1 "any_fp_register_operand" ""))]
2445   "TARGET_64BIT && reload_completed"
2446   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2447    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2448   "")
2449
2450 (define_split
2451   [(set (match_operand:DF 0 "push_operand" "")
2452         (match_operand:DF 1 "general_operand" ""))]
2453   "reload_completed"
2454   [(const_int 0)]
2455   "ix86_split_long_move (operands); DONE;")
2456
2457 ;; Moving is usually shorter when only FP registers are used. This separate
2458 ;; movdf pattern avoids the use of integer registers for FP operations
2459 ;; when optimizing for size.
2460
2461 (define_insn "*movdf_nointeger"
2462   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2463         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2464   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2465    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2466    && (reload_in_progress || reload_completed
2467        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2468        || GET_CODE (operands[1]) != CONST_DOUBLE
2469        || memory_operand (operands[0], DFmode))" 
2470 {
2471   switch (which_alternative)
2472     {
2473     case 0:
2474       return output_387_reg_move (insn, operands);
2475
2476     case 1:
2477       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2478         return "fstp%z0\t%y0";
2479       else
2480         return "fst%z0\t%y0";
2481
2482     case 2:
2483       return standard_80387_constant_opcode (operands[1]);
2484
2485     case 3:
2486     case 4:
2487       return "#";
2488     case 5:
2489       switch (get_attr_mode (insn))
2490         {
2491         case MODE_V4SF:
2492           return "xorps\t%0, %0";
2493         case MODE_V2DF:
2494           return "xorpd\t%0, %0";
2495         case MODE_TI:
2496           return "pxor\t%0, %0";
2497         default:
2498           abort ();
2499         }
2500     case 6:
2501       switch (get_attr_mode (insn))
2502         {
2503         case MODE_V4SF:
2504           return "movaps\t{%1, %0|%0, %1}";
2505         case MODE_V2DF:
2506           return "movapd\t{%1, %0|%0, %1}";
2507         case MODE_DF:
2508           return "movsd\t{%1, %0|%0, %1}";
2509         default:
2510           abort ();
2511         }
2512     case 7:
2513       if (get_attr_mode (insn) == MODE_V2DF)
2514         return "movlpd\t{%1, %0|%0, %1}";
2515       else
2516         return "movsd\t{%1, %0|%0, %1}";
2517     case 8:
2518       return "movsd\t{%1, %0|%0, %1}";
2519
2520     default:
2521       abort();
2522     }
2523 }
2524   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2525    (set (attr "mode")
2526         (cond [(eq_attr "alternative" "3,4")
2527                  (const_string "SI")
2528                /* xorps is one byte shorter.  */
2529                (eq_attr "alternative" "5")
2530                  (cond [(ne (symbol_ref "optimize_size")
2531                             (const_int 0))
2532                           (const_string "V4SF")
2533                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2534                             (const_int 0))
2535                           (const_string "TI")]
2536                        (const_string "V2DF"))
2537                /* For architectures resolving dependencies on
2538                   whole SSE registers use APD move to break dependency
2539                   chains, otherwise use short move to avoid extra work.
2540
2541                   movaps encodes one byte shorter.  */
2542                (eq_attr "alternative" "6")
2543                  (cond
2544                   [(ne (symbol_ref "optimize_size")
2545                        (const_int 0))
2546                      (const_string "V4SF")
2547                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2548                        (const_int 0))
2549                      (const_string "V2DF")]
2550                    (const_string "DF"))
2551                /* For architectures resolving dependencies on register
2552                   parts we may avoid extra work to zero out upper part
2553                   of register.  */
2554                (eq_attr "alternative" "7")
2555                  (if_then_else
2556                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2557                        (const_int 0))
2558                    (const_string "V2DF")
2559                    (const_string "DF"))]
2560                (const_string "DF")))])
2561
2562 (define_insn "*movdf_integer"
2563   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2564         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2565   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2566    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2567    && (reload_in_progress || reload_completed
2568        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2569        || GET_CODE (operands[1]) != CONST_DOUBLE
2570        || memory_operand (operands[0], DFmode))" 
2571 {
2572   switch (which_alternative)
2573     {
2574     case 0:
2575       return output_387_reg_move (insn, operands);
2576
2577     case 1:
2578       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2579         return "fstp%z0\t%y0";
2580       else
2581         return "fst%z0\t%y0";
2582
2583     case 2:
2584       return standard_80387_constant_opcode (operands[1]);
2585
2586     case 3:
2587     case 4:
2588       return "#";
2589
2590     case 5:
2591       switch (get_attr_mode (insn))
2592         {
2593         case MODE_V4SF:
2594           return "xorps\t%0, %0";
2595         case MODE_V2DF:
2596           return "xorpd\t%0, %0";
2597         case MODE_TI:
2598           return "pxor\t%0, %0";
2599         default:
2600           abort ();
2601         }
2602     case 6:
2603       switch (get_attr_mode (insn))
2604         {
2605         case MODE_V4SF:
2606           return "movaps\t{%1, %0|%0, %1}";
2607         case MODE_V2DF:
2608           return "movapd\t{%1, %0|%0, %1}";
2609         case MODE_DF:
2610           return "movsd\t{%1, %0|%0, %1}";
2611         default:
2612           abort ();
2613         }
2614     case 7:
2615       if (get_attr_mode (insn) == MODE_V2DF)
2616         return "movlpd\t{%1, %0|%0, %1}";
2617       else
2618         return "movsd\t{%1, %0|%0, %1}";
2619     case 8:
2620       return "movsd\t{%1, %0|%0, %1}";
2621
2622     default:
2623       abort();
2624     }
2625 }
2626   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2627    (set (attr "mode")
2628         (cond [(eq_attr "alternative" "3,4")
2629                  (const_string "SI")
2630                /* xorps is one byte shorter.  */
2631                (eq_attr "alternative" "5")
2632                  (cond [(ne (symbol_ref "optimize_size")
2633                             (const_int 0))
2634                           (const_string "V4SF")
2635                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2636                             (const_int 0))
2637                           (const_string "TI")]
2638                        (const_string "V2DF"))
2639                /* For architectures resolving dependencies on
2640                   whole SSE registers use APD move to break dependency
2641                   chains, otherwise use short move to avoid extra work.  
2642
2643                   movaps encodes one byte shorter.  */
2644                (eq_attr "alternative" "6")
2645                  (cond
2646                   [(ne (symbol_ref "optimize_size")
2647                        (const_int 0))
2648                      (const_string "V4SF")
2649                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2650                        (const_int 0))
2651                      (const_string "V2DF")]
2652                    (const_string "DF"))
2653                /* For architectures resolving dependencies on register
2654                   parts we may avoid extra work to zero out upper part
2655                   of register.  */
2656                (eq_attr "alternative" "7")
2657                  (if_then_else
2658                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2659                        (const_int 0))
2660                    (const_string "V2DF")
2661                    (const_string "DF"))]
2662                (const_string "DF")))])
2663
2664 (define_split
2665   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2666         (match_operand:DF 1 "general_operand" ""))]
2667   "reload_completed
2668    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2669    && ! (ANY_FP_REG_P (operands[0]) || 
2670          (GET_CODE (operands[0]) == SUBREG
2671           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2672    && ! (ANY_FP_REG_P (operands[1]) || 
2673          (GET_CODE (operands[1]) == SUBREG
2674           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2675   [(const_int 0)]
2676   "ix86_split_long_move (operands); DONE;")
2677
2678 (define_insn "*swapdf"
2679   [(set (match_operand:DF 0 "register_operand" "+f")
2680         (match_operand:DF 1 "register_operand" "+f"))
2681    (set (match_dup 1)
2682         (match_dup 0))]
2683   "reload_completed || !TARGET_SSE2"
2684 {
2685   if (STACK_TOP_P (operands[0]))
2686     return "fxch\t%1";
2687   else
2688     return "fxch\t%0";
2689 }
2690   [(set_attr "type" "fxch")
2691    (set_attr "mode" "DF")])
2692
2693 (define_expand "movxf"
2694   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2695         (match_operand:XF 1 "general_operand" ""))]
2696   ""
2697   "ix86_expand_move (XFmode, operands); DONE;")
2698
2699 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2700 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2701 ;; Pushing using integer instructions is longer except for constants
2702 ;; and direct memory references.
2703 ;; (assuming that any given constant is pushed only once, but this ought to be
2704 ;;  handled elsewhere).
2705
2706 (define_insn "*pushxf_nointeger"
2707   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2708         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2709   "optimize_size"
2710 {
2711   /* This insn should be already split before reg-stack.  */
2712   abort ();
2713 }
2714   [(set_attr "type" "multi")
2715    (set_attr "mode" "XF,SI,SI")])
2716
2717 (define_insn "*pushxf_integer"
2718   [(set (match_operand:XF 0 "push_operand" "=<,<")
2719         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2720   "!optimize_size"
2721 {
2722   /* This insn should be already split before reg-stack.  */
2723   abort ();
2724 }
2725   [(set_attr "type" "multi")
2726    (set_attr "mode" "XF,SI")])
2727
2728 (define_split
2729   [(set (match_operand 0 "push_operand" "")
2730         (match_operand 1 "general_operand" ""))]
2731   "reload_completed
2732    && (GET_MODE (operands[0]) == XFmode
2733        || GET_MODE (operands[0]) == DFmode)
2734    && !ANY_FP_REG_P (operands[1])"
2735   [(const_int 0)]
2736   "ix86_split_long_move (operands); DONE;")
2737
2738 (define_split
2739   [(set (match_operand:XF 0 "push_operand" "")
2740         (match_operand:XF 1 "any_fp_register_operand" ""))]
2741   "!TARGET_64BIT"
2742   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2743    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2744   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2745
2746 (define_split
2747   [(set (match_operand:XF 0 "push_operand" "")
2748         (match_operand:XF 1 "any_fp_register_operand" ""))]
2749   "TARGET_64BIT"
2750   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2751    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2752   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2753
2754 ;; Do not use integer registers when optimizing for size
2755 (define_insn "*movxf_nointeger"
2756   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2757         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2758   "optimize_size
2759    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2760    && (reload_in_progress || reload_completed
2761        || GET_CODE (operands[1]) != CONST_DOUBLE
2762        || memory_operand (operands[0], XFmode))" 
2763 {
2764   switch (which_alternative)
2765     {
2766     case 0:
2767       return output_387_reg_move (insn, operands);
2768
2769     case 1:
2770       /* There is no non-popping store to memory for XFmode.  So if
2771          we need one, follow the store with a load.  */
2772       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2773         return "fstp%z0\t%y0\;fld%z0\t%y0";
2774       else
2775         return "fstp%z0\t%y0";
2776
2777     case 2:
2778       return standard_80387_constant_opcode (operands[1]);
2779
2780     case 3: case 4:
2781       return "#";
2782     }
2783   abort();
2784 }
2785   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2786    (set_attr "mode" "XF,XF,XF,SI,SI")])
2787
2788 (define_insn "*movxf_integer"
2789   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2790         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2791   "!optimize_size
2792    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2793    && (reload_in_progress || reload_completed
2794        || GET_CODE (operands[1]) != CONST_DOUBLE
2795        || memory_operand (operands[0], XFmode))" 
2796 {
2797   switch (which_alternative)
2798     {
2799     case 0:
2800       return output_387_reg_move (insn, operands);
2801
2802     case 1:
2803       /* There is no non-popping store to memory for XFmode.  So if
2804          we need one, follow the store with a load.  */
2805       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2806         return "fstp%z0\t%y0\;fld%z0\t%y0";
2807       else
2808         return "fstp%z0\t%y0";
2809
2810     case 2:
2811       return standard_80387_constant_opcode (operands[1]);
2812
2813     case 3: case 4:
2814       return "#";
2815     }
2816   abort();
2817 }
2818   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2819    (set_attr "mode" "XF,XF,XF,SI,SI")])
2820
2821 (define_split
2822   [(set (match_operand 0 "nonimmediate_operand" "")
2823         (match_operand 1 "general_operand" ""))]
2824   "reload_completed
2825    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2826    && GET_MODE (operands[0]) == XFmode
2827    && ! (ANY_FP_REG_P (operands[0]) || 
2828          (GET_CODE (operands[0]) == SUBREG
2829           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2830    && ! (ANY_FP_REG_P (operands[1]) || 
2831          (GET_CODE (operands[1]) == SUBREG
2832           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2833   [(const_int 0)]
2834   "ix86_split_long_move (operands); DONE;")
2835
2836 (define_split
2837   [(set (match_operand 0 "register_operand" "")
2838         (match_operand 1 "memory_operand" ""))]
2839   "reload_completed
2840    && GET_CODE (operands[1]) == MEM
2841    && (GET_MODE (operands[0]) == XFmode
2842        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2843    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2844    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2845   [(set (match_dup 0) (match_dup 1))]
2846 {
2847   rtx c = get_pool_constant (XEXP (operands[1], 0));
2848   rtx r = operands[0];
2849
2850   if (GET_CODE (r) == SUBREG)
2851     r = SUBREG_REG (r);
2852
2853   if (SSE_REG_P (r))
2854     {
2855       if (!standard_sse_constant_p (c))
2856         FAIL;
2857     }
2858   else if (FP_REG_P (r))
2859     {
2860       if (!standard_80387_constant_p (c))
2861         FAIL;
2862     }
2863   else if (MMX_REG_P (r))
2864     FAIL;
2865
2866   operands[1] = c;
2867 })
2868
2869 (define_insn "swapxf"
2870   [(set (match_operand:XF 0 "register_operand" "+f")
2871         (match_operand:XF 1 "register_operand" "+f"))
2872    (set (match_dup 1)
2873         (match_dup 0))]
2874   ""
2875 {
2876   if (STACK_TOP_P (operands[0]))
2877     return "fxch\t%1";
2878   else
2879     return "fxch\t%0";
2880 }
2881   [(set_attr "type" "fxch")
2882    (set_attr "mode" "XF")])
2883 \f
2884 ;; Zero extension instructions
2885
2886 (define_expand "zero_extendhisi2"
2887   [(set (match_operand:SI 0 "register_operand" "")
2888      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2889   ""
2890 {
2891   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2892     {
2893       operands[1] = force_reg (HImode, operands[1]);
2894       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2895       DONE;
2896     }
2897 })
2898
2899 (define_insn "zero_extendhisi2_and"
2900   [(set (match_operand:SI 0 "register_operand" "=r")
2901      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2902    (clobber (reg:CC FLAGS_REG))]
2903   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2904   "#"
2905   [(set_attr "type" "alu1")
2906    (set_attr "mode" "SI")])
2907
2908 (define_split
2909   [(set (match_operand:SI 0 "register_operand" "")
2910         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2911    (clobber (reg:CC FLAGS_REG))]
2912   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2913   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2914               (clobber (reg:CC FLAGS_REG))])]
2915   "")
2916
2917 (define_insn "*zero_extendhisi2_movzwl"
2918   [(set (match_operand:SI 0 "register_operand" "=r")
2919      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2920   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2921   "movz{wl|x}\t{%1, %0|%0, %1}"
2922   [(set_attr "type" "imovx")
2923    (set_attr "mode" "SI")])
2924
2925 (define_expand "zero_extendqihi2"
2926   [(parallel
2927     [(set (match_operand:HI 0 "register_operand" "")
2928        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2929      (clobber (reg:CC FLAGS_REG))])]
2930   ""
2931   "")
2932
2933 (define_insn "*zero_extendqihi2_and"
2934   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2935      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2936    (clobber (reg:CC FLAGS_REG))]
2937   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2938   "#"
2939   [(set_attr "type" "alu1")
2940    (set_attr "mode" "HI")])
2941
2942 (define_insn "*zero_extendqihi2_movzbw_and"
2943   [(set (match_operand:HI 0 "register_operand" "=r,r")
2944      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2945    (clobber (reg:CC FLAGS_REG))]
2946   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2947   "#"
2948   [(set_attr "type" "imovx,alu1")
2949    (set_attr "mode" "HI")])
2950
2951 (define_insn "*zero_extendqihi2_movzbw"
2952   [(set (match_operand:HI 0 "register_operand" "=r")
2953      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2954   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2955   "movz{bw|x}\t{%1, %0|%0, %1}"
2956   [(set_attr "type" "imovx")
2957    (set_attr "mode" "HI")])
2958
2959 ;; For the movzbw case strip only the clobber
2960 (define_split
2961   [(set (match_operand:HI 0 "register_operand" "")
2962         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2963    (clobber (reg:CC FLAGS_REG))]
2964   "reload_completed 
2965    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2966    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2967   [(set (match_operand:HI 0 "register_operand" "")
2968         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2969
2970 ;; When source and destination does not overlap, clear destination
2971 ;; first and then do the movb
2972 (define_split
2973   [(set (match_operand:HI 0 "register_operand" "")
2974         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2975    (clobber (reg:CC FLAGS_REG))]
2976   "reload_completed
2977    && ANY_QI_REG_P (operands[0])
2978    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2979    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2980   [(set (match_dup 0) (const_int 0))
2981    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2982   "operands[2] = gen_lowpart (QImode, operands[0]);")
2983
2984 ;; Rest is handled by single and.
2985 (define_split
2986   [(set (match_operand:HI 0 "register_operand" "")
2987         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2988    (clobber (reg:CC FLAGS_REG))]
2989   "reload_completed
2990    && true_regnum (operands[0]) == true_regnum (operands[1])"
2991   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2992               (clobber (reg:CC FLAGS_REG))])]
2993   "")
2994
2995 (define_expand "zero_extendqisi2"
2996   [(parallel
2997     [(set (match_operand:SI 0 "register_operand" "")
2998        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2999      (clobber (reg:CC FLAGS_REG))])]
3000   ""
3001   "")
3002
3003 (define_insn "*zero_extendqisi2_and"
3004   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3005      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3006    (clobber (reg:CC FLAGS_REG))]
3007   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3008   "#"
3009   [(set_attr "type" "alu1")
3010    (set_attr "mode" "SI")])
3011
3012 (define_insn "*zero_extendqisi2_movzbw_and"
3013   [(set (match_operand:SI 0 "register_operand" "=r,r")
3014      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3015    (clobber (reg:CC FLAGS_REG))]
3016   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3017   "#"
3018   [(set_attr "type" "imovx,alu1")
3019    (set_attr "mode" "SI")])
3020
3021 (define_insn "*zero_extendqisi2_movzbw"
3022   [(set (match_operand:SI 0 "register_operand" "=r")
3023      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3024   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3025   "movz{bl|x}\t{%1, %0|%0, %1}"
3026   [(set_attr "type" "imovx")
3027    (set_attr "mode" "SI")])
3028
3029 ;; For the movzbl case strip only the clobber
3030 (define_split
3031   [(set (match_operand:SI 0 "register_operand" "")
3032         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3033    (clobber (reg:CC FLAGS_REG))]
3034   "reload_completed 
3035    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3036    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3037   [(set (match_dup 0)
3038         (zero_extend:SI (match_dup 1)))])
3039
3040 ;; When source and destination does not overlap, clear destination
3041 ;; first and then do the movb
3042 (define_split
3043   [(set (match_operand:SI 0 "register_operand" "")
3044         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3045    (clobber (reg:CC FLAGS_REG))]
3046   "reload_completed
3047    && ANY_QI_REG_P (operands[0])
3048    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3049    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3050    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3051   [(set (match_dup 0) (const_int 0))
3052    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3053   "operands[2] = gen_lowpart (QImode, operands[0]);")
3054
3055 ;; Rest is handled by single and.
3056 (define_split
3057   [(set (match_operand:SI 0 "register_operand" "")
3058         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3059    (clobber (reg:CC FLAGS_REG))]
3060   "reload_completed
3061    && true_regnum (operands[0]) == true_regnum (operands[1])"
3062   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3063               (clobber (reg:CC FLAGS_REG))])]
3064   "")
3065
3066 ;; %%% Kill me once multi-word ops are sane.
3067 (define_expand "zero_extendsidi2"
3068   [(set (match_operand:DI 0 "register_operand" "=r")
3069      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3070   ""
3071   "if (!TARGET_64BIT)
3072      {
3073        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3074        DONE;
3075      }
3076   ")
3077
3078 (define_insn "zero_extendsidi2_32"
3079   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3080         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3081    (clobber (reg:CC FLAGS_REG))]
3082   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3083   "@
3084    #
3085    #
3086    #
3087    movd\t{%1, %0|%0, %1}
3088    movd\t{%1, %0|%0, %1}"
3089   [(set_attr "mode" "SI,SI,SI,DI,TI")
3090    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3091
3092 (define_insn "*zero_extendsidi2_32_1"
3093   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3094         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3095    (clobber (reg:CC FLAGS_REG))]
3096   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3097   "@
3098    #
3099    #
3100    #
3101    movd\t{%1, %0|%0, %1}
3102    movd\t{%1, %0|%0, %1}"
3103   [(set_attr "mode" "SI,SI,SI,DI,TI")
3104    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3105
3106 (define_insn "zero_extendsidi2_rex64"
3107   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3108      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3109   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3110   "@
3111    mov\t{%k1, %k0|%k0, %k1}
3112    #
3113    movd\t{%1, %0|%0, %1}
3114    movd\t{%1, %0|%0, %1}"
3115   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3116    (set_attr "mode" "SI,DI,DI,TI")])
3117
3118 (define_insn "*zero_extendsidi2_rex64_1"
3119   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3120      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3121   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3122   "@
3123    mov\t{%k1, %k0|%k0, %k1}
3124    #
3125    movd\t{%1, %0|%0, %1}
3126    movd\t{%1, %0|%0, %1}"
3127   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3128    (set_attr "mode" "SI,DI,SI,SI")])
3129
3130 (define_split
3131   [(set (match_operand:DI 0 "memory_operand" "")
3132      (zero_extend:DI (match_dup 0)))]
3133   "TARGET_64BIT"
3134   [(set (match_dup 4) (const_int 0))]
3135   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3136
3137 (define_split 
3138   [(set (match_operand:DI 0 "register_operand" "")
3139         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3140    (clobber (reg:CC FLAGS_REG))]
3141   "!TARGET_64BIT && reload_completed
3142    && true_regnum (operands[0]) == true_regnum (operands[1])"
3143   [(set (match_dup 4) (const_int 0))]
3144   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3145
3146 (define_split 
3147   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3148         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3149    (clobber (reg:CC FLAGS_REG))]
3150   "!TARGET_64BIT && reload_completed
3151    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3152   [(set (match_dup 3) (match_dup 1))
3153    (set (match_dup 4) (const_int 0))]
3154   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3155
3156 (define_insn "zero_extendhidi2"
3157   [(set (match_operand:DI 0 "register_operand" "=r,r")
3158      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3159   "TARGET_64BIT"
3160   "@
3161    movz{wl|x}\t{%1, %k0|%k0, %1}
3162    movz{wq|x}\t{%1, %0|%0, %1}"
3163   [(set_attr "type" "imovx")
3164    (set_attr "mode" "SI,DI")])
3165
3166 (define_insn "zero_extendqidi2"
3167   [(set (match_operand:DI 0 "register_operand" "=r,r")
3168      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3169   "TARGET_64BIT"
3170   "@
3171    movz{bl|x}\t{%1, %k0|%k0, %1}
3172    movz{bq|x}\t{%1, %0|%0, %1}"
3173   [(set_attr "type" "imovx")
3174    (set_attr "mode" "SI,DI")])
3175 \f
3176 ;; Sign extension instructions
3177
3178 (define_expand "extendsidi2"
3179   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3180                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3181               (clobber (reg:CC FLAGS_REG))
3182               (clobber (match_scratch:SI 2 ""))])]
3183   ""
3184 {
3185   if (TARGET_64BIT)
3186     {
3187       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3188       DONE;
3189     }
3190 })
3191
3192 (define_insn "*extendsidi2_1"
3193   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3194         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3195    (clobber (reg:CC FLAGS_REG))
3196    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3197   "!TARGET_64BIT"
3198   "#")
3199
3200 (define_insn "extendsidi2_rex64"
3201   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3202         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3203   "TARGET_64BIT"
3204   "@
3205    {cltq|cdqe}
3206    movs{lq|x}\t{%1,%0|%0, %1}"
3207   [(set_attr "type" "imovx")
3208    (set_attr "mode" "DI")
3209    (set_attr "prefix_0f" "0")
3210    (set_attr "modrm" "0,1")])
3211
3212 (define_insn "extendhidi2"
3213   [(set (match_operand:DI 0 "register_operand" "=r")
3214         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3215   "TARGET_64BIT"
3216   "movs{wq|x}\t{%1,%0|%0, %1}"
3217   [(set_attr "type" "imovx")
3218    (set_attr "mode" "DI")])
3219
3220 (define_insn "extendqidi2"
3221   [(set (match_operand:DI 0 "register_operand" "=r")
3222         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3223   "TARGET_64BIT"
3224   "movs{bq|x}\t{%1,%0|%0, %1}"
3225    [(set_attr "type" "imovx")
3226     (set_attr "mode" "DI")])
3227
3228 ;; Extend to memory case when source register does die.
3229 (define_split 
3230   [(set (match_operand:DI 0 "memory_operand" "")
3231         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3232    (clobber (reg:CC FLAGS_REG))
3233    (clobber (match_operand:SI 2 "register_operand" ""))]
3234   "(reload_completed
3235     && dead_or_set_p (insn, operands[1])
3236     && !reg_mentioned_p (operands[1], operands[0]))"
3237   [(set (match_dup 3) (match_dup 1))
3238    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3239               (clobber (reg:CC FLAGS_REG))])
3240    (set (match_dup 4) (match_dup 1))]
3241   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3242
3243 ;; Extend to memory case when source register does not die.
3244 (define_split 
3245   [(set (match_operand:DI 0 "memory_operand" "")
3246         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3247    (clobber (reg:CC FLAGS_REG))
3248    (clobber (match_operand:SI 2 "register_operand" ""))]
3249   "reload_completed"
3250   [(const_int 0)]
3251 {
3252   split_di (&operands[0], 1, &operands[3], &operands[4]);
3253
3254   emit_move_insn (operands[3], operands[1]);
3255
3256   /* Generate a cltd if possible and doing so it profitable.  */
3257   if (true_regnum (operands[1]) == 0
3258       && true_regnum (operands[2]) == 1
3259       && (optimize_size || TARGET_USE_CLTD))
3260     {
3261       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3262     }
3263   else
3264     {
3265       emit_move_insn (operands[2], operands[1]);
3266       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3267     }
3268   emit_move_insn (operands[4], operands[2]);
3269   DONE;
3270 })
3271
3272 ;; Extend to register case.  Optimize case where source and destination
3273 ;; registers match and cases where we can use cltd.
3274 (define_split 
3275   [(set (match_operand:DI 0 "register_operand" "")
3276         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3277    (clobber (reg:CC FLAGS_REG))
3278    (clobber (match_scratch:SI 2 ""))]
3279   "reload_completed"
3280   [(const_int 0)]
3281 {
3282   split_di (&operands[0], 1, &operands[3], &operands[4]);
3283
3284   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3285     emit_move_insn (operands[3], operands[1]);
3286
3287   /* Generate a cltd if possible and doing so it profitable.  */
3288   if (true_regnum (operands[3]) == 0
3289       && (optimize_size || TARGET_USE_CLTD))
3290     {
3291       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3292       DONE;
3293     }
3294
3295   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3296     emit_move_insn (operands[4], operands[1]);
3297
3298   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3299   DONE;
3300 })
3301
3302 (define_insn "extendhisi2"
3303   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3304         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3305   ""
3306 {
3307   switch (get_attr_prefix_0f (insn))
3308     {
3309     case 0:
3310       return "{cwtl|cwde}";
3311     default:
3312       return "movs{wl|x}\t{%1,%0|%0, %1}";
3313     }
3314 }
3315   [(set_attr "type" "imovx")
3316    (set_attr "mode" "SI")
3317    (set (attr "prefix_0f")
3318      ;; movsx is short decodable while cwtl is vector decoded.
3319      (if_then_else (and (eq_attr "cpu" "!k6")
3320                         (eq_attr "alternative" "0"))
3321         (const_string "0")
3322         (const_string "1")))
3323    (set (attr "modrm")
3324      (if_then_else (eq_attr "prefix_0f" "0")
3325         (const_string "0")
3326         (const_string "1")))])
3327
3328 (define_insn "*extendhisi2_zext"
3329   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3330         (zero_extend:DI
3331           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3332   "TARGET_64BIT"
3333 {
3334   switch (get_attr_prefix_0f (insn))
3335     {
3336     case 0:
3337       return "{cwtl|cwde}";
3338     default:
3339       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3340     }
3341 }
3342   [(set_attr "type" "imovx")
3343    (set_attr "mode" "SI")
3344    (set (attr "prefix_0f")
3345      ;; movsx is short decodable while cwtl is vector decoded.
3346      (if_then_else (and (eq_attr "cpu" "!k6")
3347                         (eq_attr "alternative" "0"))
3348         (const_string "0")
3349         (const_string "1")))
3350    (set (attr "modrm")
3351      (if_then_else (eq_attr "prefix_0f" "0")
3352         (const_string "0")
3353         (const_string "1")))])
3354
3355 (define_insn "extendqihi2"
3356   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3357         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3358   ""
3359 {
3360   switch (get_attr_prefix_0f (insn))
3361     {
3362     case 0:
3363       return "{cbtw|cbw}";
3364     default:
3365       return "movs{bw|x}\t{%1,%0|%0, %1}";
3366     }
3367 }
3368   [(set_attr "type" "imovx")
3369    (set_attr "mode" "HI")
3370    (set (attr "prefix_0f")
3371      ;; movsx is short decodable while cwtl is vector decoded.
3372      (if_then_else (and (eq_attr "cpu" "!k6")
3373                         (eq_attr "alternative" "0"))
3374         (const_string "0")
3375         (const_string "1")))
3376    (set (attr "modrm")
3377      (if_then_else (eq_attr "prefix_0f" "0")
3378         (const_string "0")
3379         (const_string "1")))])
3380
3381 (define_insn "extendqisi2"
3382   [(set (match_operand:SI 0 "register_operand" "=r")
3383         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3384   ""
3385   "movs{bl|x}\t{%1,%0|%0, %1}"
3386    [(set_attr "type" "imovx")
3387     (set_attr "mode" "SI")])
3388
3389 (define_insn "*extendqisi2_zext"
3390   [(set (match_operand:DI 0 "register_operand" "=r")
3391         (zero_extend:DI
3392           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3393   "TARGET_64BIT"
3394   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3395    [(set_attr "type" "imovx")
3396     (set_attr "mode" "SI")])
3397 \f
3398 ;; Conversions between float and double.
3399
3400 ;; These are all no-ops in the model used for the 80387.  So just
3401 ;; emit moves.
3402
3403 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3404 (define_insn "*dummy_extendsfdf2"
3405   [(set (match_operand:DF 0 "push_operand" "=<")
3406         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3407   "0"
3408   "#")
3409
3410 (define_split
3411   [(set (match_operand:DF 0 "push_operand" "")
3412         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3413   "!TARGET_64BIT"
3414   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3415    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
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:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3422    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3423
3424 (define_insn "*dummy_extendsfxf2"
3425   [(set (match_operand:XF 0 "push_operand" "=<")
3426         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3427   "0"
3428   "#")
3429
3430 (define_split
3431   [(set (match_operand:XF 0 "push_operand" "")
3432         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3433   ""
3434   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3435    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3436   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3437
3438 (define_split
3439   [(set (match_operand:XF 0 "push_operand" "")
3440         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3441   "TARGET_64BIT"
3442   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3443    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3444   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3445
3446 (define_split
3447   [(set (match_operand:XF 0 "push_operand" "")
3448         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3449   ""
3450   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3451    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3452   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3453
3454 (define_split
3455   [(set (match_operand:XF 0 "push_operand" "")
3456         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3457   "TARGET_64BIT"
3458   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3459    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3460   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3461
3462 (define_expand "extendsfdf2"
3463   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3464         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3465   "TARGET_80387 || TARGET_SSE2"
3466 {
3467   /* ??? Needed for compress_float_constant since all fp constants
3468      are LEGITIMATE_CONSTANT_P.  */
3469   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3470     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3471   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3472     operands[1] = force_reg (SFmode, operands[1]);
3473 })
3474
3475 (define_insn "*extendsfdf2_1"
3476   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3477         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3478   "(TARGET_80387 || TARGET_SSE2)
3479    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3480 {
3481   switch (which_alternative)
3482     {
3483     case 0:
3484       return output_387_reg_move (insn, operands);
3485
3486     case 1:
3487       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3488         return "fstp%z0\t%y0";
3489       else
3490         return "fst%z0\t%y0";
3491
3492     case 2:
3493       return "cvtss2sd\t{%1, %0|%0, %1}";
3494
3495     default:
3496       abort ();
3497     }
3498 }
3499   [(set_attr "type" "fmov,fmov,ssecvt")
3500    (set_attr "mode" "SF,XF,DF")])
3501
3502 (define_insn "*extendsfdf2_1_sse_only"
3503   [(set (match_operand:DF 0 "register_operand" "=Y")
3504         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3505   "!TARGET_80387 && TARGET_SSE2
3506    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3507   "cvtss2sd\t{%1, %0|%0, %1}"
3508   [(set_attr "type" "ssecvt")
3509    (set_attr "mode" "DF")])
3510
3511 (define_expand "extendsfxf2"
3512   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3513         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3514   "TARGET_80387"
3515 {
3516   /* ??? Needed for compress_float_constant since all fp constants
3517      are LEGITIMATE_CONSTANT_P.  */
3518   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3519     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3520   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3521     operands[1] = force_reg (SFmode, operands[1]);
3522 })
3523
3524 (define_insn "*extendsfxf2_1"
3525   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3526         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3527   "TARGET_80387
3528    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3529 {
3530   switch (which_alternative)
3531     {
3532     case 0:
3533       return output_387_reg_move (insn, operands);
3534
3535     case 1:
3536       /* There is no non-popping store to memory for XFmode.  So if
3537          we need one, follow the store with a load.  */
3538       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3539         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3540       else
3541         return "fstp%z0\t%y0";
3542
3543     default:
3544       abort ();
3545     }
3546 }
3547   [(set_attr "type" "fmov")
3548    (set_attr "mode" "SF,XF")])
3549
3550 (define_expand "extenddfxf2"
3551   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3552         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3553   "TARGET_80387"
3554 {
3555   /* ??? Needed for compress_float_constant since all fp constants
3556      are LEGITIMATE_CONSTANT_P.  */
3557   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3558     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3559   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3560     operands[1] = force_reg (DFmode, operands[1]);
3561 })
3562
3563 (define_insn "*extenddfxf2_1"
3564   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3565         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3566   "TARGET_80387
3567    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3568 {
3569   switch (which_alternative)
3570     {
3571     case 0:
3572       return output_387_reg_move (insn, operands);
3573
3574     case 1:
3575       /* There is no non-popping store to memory for XFmode.  So if
3576          we need one, follow the store with a load.  */
3577       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3578         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3579       else
3580         return "fstp%z0\t%y0";
3581
3582     default:
3583       abort ();
3584     }
3585 }
3586   [(set_attr "type" "fmov")
3587    (set_attr "mode" "DF,XF")])
3588
3589 ;; %%% This seems bad bad news.
3590 ;; This cannot output into an f-reg because there is no way to be sure
3591 ;; of truncating in that case.  Otherwise this is just like a simple move
3592 ;; insn.  So we pretend we can output to a reg in order to get better
3593 ;; register preferencing, but we really use a stack slot.
3594
3595 (define_expand "truncdfsf2"
3596   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3597                    (float_truncate:SF
3598                     (match_operand:DF 1 "register_operand" "")))
3599               (clobber (match_dup 2))])]
3600   "TARGET_80387 || TARGET_SSE2"
3601   "
3602    if (!TARGET_80387)
3603      {
3604         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3605         DONE;
3606      }
3607    else if (flag_unsafe_math_optimizations)
3608      {
3609         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3610         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3611         if (reg != operands[0])
3612           emit_move_insn (operands[0], reg);
3613         DONE;
3614      }
3615    else
3616      operands[2] = assign_386_stack_local (SFmode, 0);
3617 ")
3618
3619 (define_insn "truncdfsf2_noop"
3620   [(set (match_operand:SF 0 "register_operand" "=f")
3621         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3622   "TARGET_80387 && flag_unsafe_math_optimizations"
3623 {
3624   return output_387_reg_move (insn, operands);
3625 }
3626   [(set_attr "type" "fmov")
3627    (set_attr "mode" "SF")])
3628
3629 (define_insn "*truncdfsf2_1"
3630   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3631         (float_truncate:SF
3632          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3633    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3634   "TARGET_80387 && !TARGET_SSE2"
3635 {
3636   switch (which_alternative)
3637     {
3638     case 0:
3639       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3640         return "fstp%z0\t%y0";
3641       else
3642         return "fst%z0\t%y0";
3643     default:
3644       abort ();
3645     }
3646 }
3647   [(set_attr "type" "fmov,multi,multi,multi")
3648    (set_attr "mode" "SF,SF,SF,SF")])
3649
3650 (define_insn "*truncdfsf2_1_sse"
3651   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3652         (float_truncate:SF
3653          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3654    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3655   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3656 {
3657   switch (which_alternative)
3658     {
3659     case 0:
3660       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3661         return "fstp%z0\t%y0";
3662       else
3663         return "fst%z0\t%y0";
3664     case 4:
3665       return "#";
3666     default:
3667       abort ();
3668     }
3669 }
3670   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3671    (set_attr "mode" "SF,SF,SF,SF,DF")])
3672
3673 (define_insn "*truncdfsf2_1_sse_nooverlap"
3674   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3675         (float_truncate:SF
3676          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3677    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3678   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3679 {
3680   switch (which_alternative)
3681     {
3682     case 0:
3683       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3684         return "fstp%z0\t%y0";
3685       else
3686         return "fst%z0\t%y0";
3687     case 4:
3688       return "#";
3689     default:
3690       abort ();
3691     }
3692 }
3693   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3694    (set_attr "mode" "SF,SF,SF,SF,DF")])
3695
3696 (define_insn "*truncdfsf2_2"
3697   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3698         (float_truncate:SF
3699          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3700   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3701    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3702 {
3703   switch (which_alternative)
3704     {
3705     case 0:
3706     case 1:
3707       return "cvtsd2ss\t{%1, %0|%0, %1}";
3708     case 2:
3709       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3710         return "fstp%z0\t%y0";
3711       else
3712         return "fst%z0\t%y0";
3713     default:
3714       abort ();
3715     }
3716 }
3717   [(set_attr "type" "ssecvt,ssecvt,fmov")
3718    (set_attr "athlon_decode" "vector,double,*")
3719    (set_attr "mode" "SF,SF,SF")])
3720
3721 (define_insn "*truncdfsf2_2_nooverlap"
3722   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3723         (float_truncate:SF
3724          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3725   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3726    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3727 {
3728   switch (which_alternative)
3729     {
3730     case 0:
3731       return "#";
3732     case 1:
3733       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3734         return "fstp%z0\t%y0";
3735       else
3736         return "fst%z0\t%y0";
3737     default:
3738       abort ();
3739     }
3740 }
3741   [(set_attr "type" "ssecvt,fmov")
3742    (set_attr "mode" "DF,SF")])
3743
3744 (define_insn "*truncdfsf2_3"
3745   [(set (match_operand:SF 0 "memory_operand" "=m")
3746         (float_truncate:SF
3747          (match_operand:DF 1 "register_operand" "f")))]
3748   "TARGET_80387"
3749 {
3750   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3751     return "fstp%z0\t%y0";
3752   else
3753     return "fst%z0\t%y0";
3754 }
3755   [(set_attr "type" "fmov")
3756    (set_attr "mode" "SF")])
3757
3758 (define_insn "truncdfsf2_sse_only"
3759   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3760         (float_truncate:SF
3761          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3762   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3763   "cvtsd2ss\t{%1, %0|%0, %1}"
3764   [(set_attr "type" "ssecvt")
3765    (set_attr "athlon_decode" "vector,double")
3766    (set_attr "mode" "SF")])
3767
3768 (define_insn "*truncdfsf2_sse_only_nooverlap"
3769   [(set (match_operand:SF 0 "register_operand" "=&Y")
3770         (float_truncate:SF
3771          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3772   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3773   "#"
3774   [(set_attr "type" "ssecvt")
3775    (set_attr "mode" "DF")])
3776
3777 (define_split
3778   [(set (match_operand:SF 0 "memory_operand" "")
3779         (float_truncate:SF
3780          (match_operand:DF 1 "register_operand" "")))
3781    (clobber (match_operand:SF 2 "memory_operand" ""))]
3782   "TARGET_80387"
3783   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3784   "")
3785
3786 ; Avoid possible reformatting penalty on the destination by first
3787 ; zeroing it out
3788 (define_split
3789   [(set (match_operand:SF 0 "register_operand" "")
3790         (float_truncate:SF
3791          (match_operand:DF 1 "nonimmediate_operand" "")))
3792    (clobber (match_operand 2 "" ""))]
3793   "TARGET_80387 && reload_completed
3794    && SSE_REG_P (operands[0])
3795    && !STACK_REG_P (operands[1])"
3796   [(const_int 0)]
3797 {
3798   rtx src, dest;
3799   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3800     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3801   else
3802     {
3803       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3804       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3805       /* simplify_gen_subreg refuses to widen memory references.  */
3806       if (GET_CODE (src) == SUBREG)
3807         alter_subreg (&src);
3808       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3809         abort ();
3810       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3811       emit_insn (gen_cvtsd2ss (dest, dest, src));
3812     }
3813   DONE;
3814 })
3815
3816 (define_split
3817   [(set (match_operand:SF 0 "register_operand" "")
3818         (float_truncate:SF
3819          (match_operand:DF 1 "nonimmediate_operand" "")))]
3820   "TARGET_80387 && reload_completed
3821    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3822   [(const_int 0)]
3823 {
3824   rtx src, dest;
3825   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3826   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3827   /* simplify_gen_subreg refuses to widen memory references.  */
3828   if (GET_CODE (src) == SUBREG)
3829     alter_subreg (&src);
3830   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3831     abort ();
3832   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3833   emit_insn (gen_cvtsd2ss (dest, dest, src));
3834   DONE;
3835 })
3836
3837 (define_split
3838   [(set (match_operand:SF 0 "register_operand" "")
3839         (float_truncate:SF
3840          (match_operand:DF 1 "fp_register_operand" "")))
3841    (clobber (match_operand:SF 2 "memory_operand" ""))]
3842   "TARGET_80387 && reload_completed"
3843   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3844    (set (match_dup 0) (match_dup 2))]
3845   "")
3846
3847 (define_expand "truncxfsf2"
3848   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3849                    (float_truncate:SF
3850                     (match_operand:XF 1 "register_operand" "")))
3851               (clobber (match_dup 2))])]
3852   "TARGET_80387"
3853   "
3854   if (flag_unsafe_math_optimizations)
3855     {
3856       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3857       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3858       if (reg != operands[0])
3859         emit_move_insn (operands[0], reg);
3860       DONE;
3861     }
3862   else
3863     operands[2] = assign_386_stack_local (SFmode, 0);
3864   ")
3865
3866 (define_insn "truncxfsf2_noop"
3867   [(set (match_operand:SF 0 "register_operand" "=f")
3868         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3869   "TARGET_80387 && flag_unsafe_math_optimizations"
3870 {
3871   return output_387_reg_move (insn, operands);
3872 }
3873   [(set_attr "type" "fmov")
3874    (set_attr "mode" "SF")])
3875
3876 (define_insn "*truncxfsf2_1"
3877   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3878         (float_truncate:SF
3879          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3880    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3881   "TARGET_80387"
3882 {
3883   switch (which_alternative)
3884     {
3885     case 0:
3886       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3887         return "fstp%z0\t%y0";
3888       else
3889         return "fst%z0\t%y0";
3890     default:
3891       abort();
3892     }
3893 }
3894   [(set_attr "type" "fmov,multi,multi,multi")
3895    (set_attr "mode" "SF")])
3896
3897 (define_insn "*truncxfsf2_2"
3898   [(set (match_operand:SF 0 "memory_operand" "=m")
3899         (float_truncate:SF
3900          (match_operand:XF 1 "register_operand" "f")))]
3901   "TARGET_80387"
3902 {
3903   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3904     return "fstp%z0\t%y0";
3905   else
3906     return "fst%z0\t%y0";
3907 }
3908   [(set_attr "type" "fmov")
3909    (set_attr "mode" "SF")])
3910
3911 (define_split
3912   [(set (match_operand:SF 0 "memory_operand" "")
3913         (float_truncate:SF
3914          (match_operand:XF 1 "register_operand" "")))
3915    (clobber (match_operand:SF 2 "memory_operand" ""))]
3916   "TARGET_80387"
3917   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3918   "")
3919
3920 (define_split
3921   [(set (match_operand:SF 0 "register_operand" "")
3922         (float_truncate:SF
3923          (match_operand:XF 1 "register_operand" "")))
3924    (clobber (match_operand:SF 2 "memory_operand" ""))]
3925   "TARGET_80387 && reload_completed"
3926   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3927    (set (match_dup 0) (match_dup 2))]
3928   "")
3929
3930 (define_expand "truncxfdf2"
3931   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3932                    (float_truncate:DF
3933                     (match_operand:XF 1 "register_operand" "")))
3934               (clobber (match_dup 2))])]
3935   "TARGET_80387"
3936   "
3937   if (flag_unsafe_math_optimizations)
3938     {
3939       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3940       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3941       if (reg != operands[0])
3942         emit_move_insn (operands[0], reg);
3943       DONE;
3944     }
3945   else
3946     operands[2] = assign_386_stack_local (DFmode, 0);
3947   ")
3948
3949 (define_insn "truncxfdf2_noop"
3950   [(set (match_operand:DF 0 "register_operand" "=f")
3951         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3952   "TARGET_80387 && flag_unsafe_math_optimizations"
3953 {
3954   return output_387_reg_move (insn, operands);
3955 }
3956   [(set_attr "type" "fmov")
3957    (set_attr "mode" "DF")])
3958
3959 (define_insn "*truncxfdf2_1"
3960   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3961         (float_truncate:DF
3962          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3963    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3964   "TARGET_80387"
3965 {
3966   switch (which_alternative)
3967     {
3968     case 0:
3969       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3970         return "fstp%z0\t%y0";
3971       else
3972         return "fst%z0\t%y0";
3973     default:
3974       abort();
3975     }
3976   abort ();
3977 }
3978   [(set_attr "type" "fmov,multi,multi,multi")
3979    (set_attr "mode" "DF")])
3980
3981 (define_insn "*truncxfdf2_2"
3982   [(set (match_operand:DF 0 "memory_operand" "=m")
3983         (float_truncate:DF
3984           (match_operand:XF 1 "register_operand" "f")))]
3985   "TARGET_80387"
3986 {
3987   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3988     return "fstp%z0\t%y0";
3989   else
3990     return "fst%z0\t%y0";
3991 }
3992   [(set_attr "type" "fmov")
3993    (set_attr "mode" "DF")])
3994
3995 (define_split
3996   [(set (match_operand:DF 0 "memory_operand" "")
3997         (float_truncate:DF
3998          (match_operand:XF 1 "register_operand" "")))
3999    (clobber (match_operand:DF 2 "memory_operand" ""))]
4000   "TARGET_80387"
4001   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4002   "")
4003
4004 (define_split
4005   [(set (match_operand:DF 0 "register_operand" "")
4006         (float_truncate:DF
4007          (match_operand:XF 1 "register_operand" "")))
4008    (clobber (match_operand:DF 2 "memory_operand" ""))]
4009   "TARGET_80387 && reload_completed"
4010   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4011    (set (match_dup 0) (match_dup 2))]
4012   "")
4013
4014 \f
4015 ;; %%% Break up all these bad boys.
4016
4017 ;; Signed conversion to DImode.
4018
4019 (define_expand "fix_truncxfdi2"
4020   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4021                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4022               (clobber (reg:CC FLAGS_REG))])]
4023   "TARGET_80387"
4024   "")
4025
4026 (define_expand "fix_truncdfdi2"
4027   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4029               (clobber (reg:CC FLAGS_REG))])]
4030   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4031 {
4032   if (TARGET_64BIT && TARGET_SSE2)
4033    {
4034      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4035      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4036      if (out != operands[0])
4037         emit_move_insn (operands[0], out);
4038      DONE;
4039    }
4040 })
4041
4042 (define_expand "fix_truncsfdi2"
4043   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4044                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4045               (clobber (reg:CC FLAGS_REG))])] 
4046   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4047 {
4048   if (TARGET_SSE && TARGET_64BIT)
4049    {
4050      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4051      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4052      if (out != operands[0])
4053         emit_move_insn (operands[0], out);
4054      DONE;
4055    }
4056 })
4057
4058 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4059 ;; of the machinery.
4060 (define_insn_and_split "*fix_truncdi_1"
4061   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4062         (fix:DI (match_operand 1 "register_operand" "f,f")))
4063    (clobber (reg:CC FLAGS_REG))]
4064   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4065    && !reload_completed && !reload_in_progress
4066    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4067   "#"
4068   "&& 1"
4069   [(const_int 0)]
4070 {
4071   ix86_optimize_mode_switching = 1;
4072   operands[2] = assign_386_stack_local (HImode, 1);
4073   operands[3] = assign_386_stack_local (HImode, 2);
4074   if (memory_operand (operands[0], VOIDmode))
4075     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4076                                        operands[2], operands[3]));
4077   else
4078     {
4079       operands[4] = assign_386_stack_local (DImode, 0);
4080       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4081                                            operands[2], operands[3],
4082                                            operands[4]));
4083     }
4084   DONE;
4085 }
4086   [(set_attr "type" "fistp")
4087    (set_attr "mode" "DI")])
4088
4089 (define_insn "fix_truncdi_nomemory"
4090   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4091         (fix:DI (match_operand 1 "register_operand" "f,f")))
4092    (use (match_operand:HI 2 "memory_operand" "m,m"))
4093    (use (match_operand:HI 3 "memory_operand" "m,m"))
4094    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4095    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4096   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4097    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4098   "#"
4099   [(set_attr "type" "fistp")
4100    (set_attr "mode" "DI")])
4101
4102 (define_insn "fix_truncdi_memory"
4103   [(set (match_operand:DI 0 "memory_operand" "=m")
4104         (fix:DI (match_operand 1 "register_operand" "f")))
4105    (use (match_operand:HI 2 "memory_operand" "m"))
4106    (use (match_operand:HI 3 "memory_operand" "m"))
4107    (clobber (match_scratch:DF 4 "=&1f"))]
4108   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4109    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4110   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4111   [(set_attr "type" "fistp")
4112    (set_attr "mode" "DI")])
4113
4114 (define_split 
4115   [(set (match_operand:DI 0 "register_operand" "")
4116         (fix:DI (match_operand 1 "register_operand" "")))
4117    (use (match_operand:HI 2 "memory_operand" ""))
4118    (use (match_operand:HI 3 "memory_operand" ""))
4119    (clobber (match_operand:DI 4 "memory_operand" ""))
4120    (clobber (match_scratch 5 ""))]
4121   "reload_completed"
4122   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4123               (use (match_dup 2))
4124               (use (match_dup 3))
4125               (clobber (match_dup 5))])
4126    (set (match_dup 0) (match_dup 4))]
4127   "")
4128
4129 (define_split 
4130   [(set (match_operand:DI 0 "memory_operand" "")
4131         (fix:DI (match_operand 1 "register_operand" "")))
4132    (use (match_operand:HI 2 "memory_operand" ""))
4133    (use (match_operand:HI 3 "memory_operand" ""))
4134    (clobber (match_operand:DI 4 "memory_operand" ""))
4135    (clobber (match_scratch 5 ""))]
4136   "reload_completed"
4137   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4138               (use (match_dup 2))
4139               (use (match_dup 3))
4140               (clobber (match_dup 5))])]
4141   "")
4142
4143 ;; When SSE available, it is always faster to use it!
4144 (define_insn "fix_truncsfdi_sse"
4145   [(set (match_operand:DI 0 "register_operand" "=r,r")
4146         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4147   "TARGET_64BIT && TARGET_SSE"
4148   "cvttss2si{q}\t{%1, %0|%0, %1}"
4149   [(set_attr "type" "sseicvt")
4150    (set_attr "mode" "SF")
4151    (set_attr "athlon_decode" "double,vector")])
4152
4153 ;; Avoid vector decoded form of the instruction.
4154 (define_peephole2
4155   [(match_scratch:SF 2 "x")
4156    (set (match_operand:DI 0 "register_operand" "")
4157         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4158   "TARGET_K8 && !optimize_size"
4159   [(set (match_dup 2) (match_dup 1))
4160    (set (match_dup 0) (fix:DI (match_dup 2)))]
4161   "")
4162
4163 (define_insn "fix_truncdfdi_sse"
4164   [(set (match_operand:DI 0 "register_operand" "=r,r")
4165         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4166   "TARGET_64BIT && TARGET_SSE2"
4167   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4168   [(set_attr "type" "sseicvt,sseicvt")
4169    (set_attr "mode" "DF")
4170    (set_attr "athlon_decode" "double,vector")])
4171
4172 ;; Avoid vector decoded form of the instruction.
4173 (define_peephole2
4174   [(match_scratch:DF 2 "Y")
4175    (set (match_operand:DI 0 "register_operand" "")
4176         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4177   "TARGET_K8 && !optimize_size"
4178   [(set (match_dup 2) (match_dup 1))
4179    (set (match_dup 0) (fix:DI (match_dup 2)))]
4180   "")
4181
4182 ;; Signed conversion to SImode.
4183
4184 (define_expand "fix_truncxfsi2"
4185   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4186                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4187               (clobber (reg:CC FLAGS_REG))])]
4188   "TARGET_80387"
4189   "")
4190
4191 (define_expand "fix_truncdfsi2"
4192   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4193                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4194               (clobber (reg:CC FLAGS_REG))])]
4195   "TARGET_80387 || TARGET_SSE2"
4196 {
4197   if (TARGET_SSE2)
4198    {
4199      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4200      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4201      if (out != operands[0])
4202         emit_move_insn (operands[0], out);
4203      DONE;
4204    }
4205 })
4206
4207 (define_expand "fix_truncsfsi2"
4208   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4209                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4210               (clobber (reg:CC FLAGS_REG))])] 
4211   "TARGET_80387 || TARGET_SSE"
4212 {
4213   if (TARGET_SSE)
4214    {
4215      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4216      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4217      if (out != operands[0])
4218         emit_move_insn (operands[0], out);
4219      DONE;
4220    }
4221 })
4222
4223 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4224 ;; of the machinery.
4225 (define_insn_and_split "*fix_truncsi_1"
4226   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4227         (fix:SI (match_operand 1 "register_operand" "f,f")))
4228    (clobber (reg:CC FLAGS_REG))]
4229   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4230    && !reload_completed && !reload_in_progress
4231    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4232   "#"
4233   "&& 1"
4234   [(const_int 0)]
4235 {
4236   ix86_optimize_mode_switching = 1;
4237   operands[2] = assign_386_stack_local (HImode, 1);
4238   operands[3] = assign_386_stack_local (HImode, 2);
4239   if (memory_operand (operands[0], VOIDmode))
4240     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4241                                        operands[2], operands[3]));
4242   else
4243     {
4244       operands[4] = assign_386_stack_local (SImode, 0);
4245       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4246                                            operands[2], operands[3],
4247                                            operands[4]));
4248     }
4249   DONE;
4250 }
4251   [(set_attr "type" "fistp")
4252    (set_attr "mode" "SI")])
4253
4254 (define_insn "fix_truncsi_nomemory"
4255   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4256         (fix:SI (match_operand 1 "register_operand" "f,f")))
4257    (use (match_operand:HI 2 "memory_operand" "m,m"))
4258    (use (match_operand:HI 3 "memory_operand" "m,m"))
4259    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4260   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4261    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4262   "#"
4263   [(set_attr "type" "fistp")
4264    (set_attr "mode" "SI")])
4265
4266 (define_insn "fix_truncsi_memory"
4267   [(set (match_operand:SI 0 "memory_operand" "=m")
4268         (fix:SI (match_operand 1 "register_operand" "f")))
4269    (use (match_operand:HI 2 "memory_operand" "m"))
4270    (use (match_operand:HI 3 "memory_operand" "m"))]
4271   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4272    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4273   "* return output_fix_trunc (insn, operands);"
4274   [(set_attr "type" "fistp")
4275    (set_attr "mode" "SI")])
4276
4277 ;; When SSE available, it is always faster to use it!
4278 (define_insn "fix_truncsfsi_sse"
4279   [(set (match_operand:SI 0 "register_operand" "=r,r")
4280         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4281   "TARGET_SSE"
4282   "cvttss2si\t{%1, %0|%0, %1}"
4283   [(set_attr "type" "sseicvt")
4284    (set_attr "mode" "DF")
4285    (set_attr "athlon_decode" "double,vector")])
4286
4287 ;; Avoid vector decoded form of the instruction.
4288 (define_peephole2
4289   [(match_scratch:SF 2 "x")
4290    (set (match_operand:SI 0 "register_operand" "")
4291         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4292   "TARGET_K8 && !optimize_size"
4293   [(set (match_dup 2) (match_dup 1))
4294    (set (match_dup 0) (fix:SI (match_dup 2)))]
4295   "")
4296
4297 (define_insn "fix_truncdfsi_sse"
4298   [(set (match_operand:SI 0 "register_operand" "=r,r")
4299         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4300   "TARGET_SSE2"
4301   "cvttsd2si\t{%1, %0|%0, %1}"
4302   [(set_attr "type" "sseicvt")
4303    (set_attr "mode" "DF")
4304    (set_attr "athlon_decode" "double,vector")])
4305
4306 ;; Avoid vector decoded form of the instruction.
4307 (define_peephole2
4308   [(match_scratch:DF 2 "Y")
4309    (set (match_operand:SI 0 "register_operand" "")
4310         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4311   "TARGET_K8 && !optimize_size"
4312   [(set (match_dup 2) (match_dup 1))
4313    (set (match_dup 0) (fix:SI (match_dup 2)))]
4314   "")
4315
4316 (define_split 
4317   [(set (match_operand:SI 0 "register_operand" "")
4318         (fix:SI (match_operand 1 "register_operand" "")))
4319    (use (match_operand:HI 2 "memory_operand" ""))
4320    (use (match_operand:HI 3 "memory_operand" ""))
4321    (clobber (match_operand:SI 4 "memory_operand" ""))]
4322   "reload_completed"
4323   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4324               (use (match_dup 2))
4325               (use (match_dup 3))])
4326    (set (match_dup 0) (match_dup 4))]
4327   "")
4328
4329 (define_split 
4330   [(set (match_operand:SI 0 "memory_operand" "")
4331         (fix:SI (match_operand 1 "register_operand" "")))
4332    (use (match_operand:HI 2 "memory_operand" ""))
4333    (use (match_operand:HI 3 "memory_operand" ""))
4334    (clobber (match_operand:SI 4 "memory_operand" ""))]
4335   "reload_completed"
4336   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4337               (use (match_dup 2))
4338               (use (match_dup 3))])]
4339   "")
4340
4341 ;; Signed conversion to HImode.
4342
4343 (define_expand "fix_truncxfhi2"
4344   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4345                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4346               (clobber (reg:CC FLAGS_REG))])] 
4347   "TARGET_80387"
4348   "")
4349
4350 (define_expand "fix_truncdfhi2"
4351   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4352                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4353               (clobber (reg:CC FLAGS_REG))])]
4354   "TARGET_80387 && !TARGET_SSE2"
4355   "")
4356
4357 (define_expand "fix_truncsfhi2"
4358   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4359                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4360                (clobber (reg:CC FLAGS_REG))])]
4361   "TARGET_80387 && !TARGET_SSE"
4362   "")
4363
4364 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4365 ;; of the machinery.
4366 (define_insn_and_split "*fix_trunchi_1"
4367   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4368         (fix:HI (match_operand 1 "register_operand" "f,f")))
4369    (clobber (reg:CC FLAGS_REG))]
4370   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4371    && !reload_completed && !reload_in_progress
4372    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373   "#"
4374   ""
4375   [(const_int 0)]
4376 {
4377   ix86_optimize_mode_switching = 1;
4378   operands[2] = assign_386_stack_local (HImode, 1);
4379   operands[3] = assign_386_stack_local (HImode, 2);
4380   if (memory_operand (operands[0], VOIDmode))
4381     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4382                                        operands[2], operands[3]));
4383   else
4384     {
4385       operands[4] = assign_386_stack_local (HImode, 0);
4386       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4387                                            operands[2], operands[3],
4388                                            operands[4]));
4389     }
4390   DONE;
4391 }
4392   [(set_attr "type" "fistp")
4393    (set_attr "mode" "HI")])
4394
4395 (define_insn "fix_trunchi_nomemory"
4396   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4397         (fix:HI (match_operand 1 "register_operand" "f,f")))
4398    (use (match_operand:HI 2 "memory_operand" "m,m"))
4399    (use (match_operand:HI 3 "memory_operand" "m,m"))
4400    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4401   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4402    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4403   "#"
4404   [(set_attr "type" "fistp")
4405    (set_attr "mode" "HI")])
4406
4407 (define_insn "fix_trunchi_memory"
4408   [(set (match_operand:HI 0 "memory_operand" "=m")
4409         (fix:HI (match_operand 1 "register_operand" "f")))
4410    (use (match_operand:HI 2 "memory_operand" "m"))
4411    (use (match_operand:HI 3 "memory_operand" "m"))]
4412   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4413    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4414   "* return output_fix_trunc (insn, operands);"
4415   [(set_attr "type" "fistp")
4416    (set_attr "mode" "HI")])
4417
4418 (define_split 
4419   [(set (match_operand:HI 0 "memory_operand" "")
4420         (fix:HI (match_operand 1 "register_operand" "")))
4421    (use (match_operand:HI 2 "memory_operand" ""))
4422    (use (match_operand:HI 3 "memory_operand" ""))
4423    (clobber (match_operand:HI 4 "memory_operand" ""))]
4424   "reload_completed"
4425   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4426               (use (match_dup 2))
4427               (use (match_dup 3))])]
4428   "")
4429
4430 (define_split 
4431   [(set (match_operand:HI 0 "register_operand" "")
4432         (fix:HI (match_operand 1 "register_operand" "")))
4433    (use (match_operand:HI 2 "memory_operand" ""))
4434    (use (match_operand:HI 3 "memory_operand" ""))
4435    (clobber (match_operand:HI 4 "memory_operand" ""))]
4436   "reload_completed"
4437   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4438               (use (match_dup 2))
4439               (use (match_dup 3))
4440               (clobber (match_dup 4))])
4441    (set (match_dup 0) (match_dup 4))]
4442   "")
4443
4444 ;; %% Not used yet.
4445 (define_insn "x86_fnstcw_1"
4446   [(set (match_operand:HI 0 "memory_operand" "=m")
4447         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4448   "TARGET_80387"
4449   "fnstcw\t%0"
4450   [(set_attr "length" "2")
4451    (set_attr "mode" "HI")
4452    (set_attr "unit" "i387")])
4453
4454 (define_insn "x86_fldcw_1"
4455   [(set (reg:HI FPSR_REG)
4456         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4457   "TARGET_80387"
4458   "fldcw\t%0"
4459   [(set_attr "length" "2")
4460    (set_attr "mode" "HI")
4461    (set_attr "unit" "i387")
4462    (set_attr "athlon_decode" "vector")])
4463 \f
4464 ;; Conversion between fixed point and floating point.
4465
4466 ;; Even though we only accept memory inputs, the backend _really_
4467 ;; wants to be able to do this between registers.
4468
4469 (define_expand "floathisf2"
4470   [(set (match_operand:SF 0 "register_operand" "")
4471         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4472   "TARGET_SSE || TARGET_80387"
4473 {
4474   if (TARGET_SSE && TARGET_SSE_MATH)
4475     {
4476       emit_insn (gen_floatsisf2 (operands[0],
4477                                  convert_to_mode (SImode, operands[1], 0)));
4478       DONE;
4479     }
4480 })
4481
4482 (define_insn "*floathisf2_1"
4483   [(set (match_operand:SF 0 "register_operand" "=f,f")
4484         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4485   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4486   "@
4487    fild%z1\t%1
4488    #"
4489   [(set_attr "type" "fmov,multi")
4490    (set_attr "mode" "SF")
4491    (set_attr "fp_int_src" "true")])
4492
4493 (define_expand "floatsisf2"
4494   [(set (match_operand:SF 0 "register_operand" "")
4495         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4496   "TARGET_SSE || TARGET_80387"
4497   "")
4498
4499 (define_insn "*floatsisf2_i387"
4500   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4501         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4502   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4503   "@
4504    fild%z1\t%1
4505    #
4506    cvtsi2ss\t{%1, %0|%0, %1}
4507    cvtsi2ss\t{%1, %0|%0, %1}"
4508   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4509    (set_attr "mode" "SF")
4510    (set_attr "athlon_decode" "*,*,vector,double")
4511    (set_attr "fp_int_src" "true")])
4512
4513 (define_insn "*floatsisf2_sse"
4514   [(set (match_operand:SF 0 "register_operand" "=x,x")
4515         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4516   "TARGET_SSE"
4517   "cvtsi2ss\t{%1, %0|%0, %1}"
4518   [(set_attr "type" "sseicvt")
4519    (set_attr "mode" "SF")
4520    (set_attr "athlon_decode" "vector,double")
4521    (set_attr "fp_int_src" "true")])
4522
4523 ; Avoid possible reformatting penalty on the destination by first
4524 ; zeroing it out
4525 (define_split
4526   [(set (match_operand:SF 0 "register_operand" "")
4527         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4528   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4529    && SSE_REG_P (operands[0])"
4530   [(const_int 0)]
4531 {
4532   rtx dest;
4533   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4534   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4535   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4536   DONE;
4537 })
4538
4539 (define_expand "floatdisf2"
4540   [(set (match_operand:SF 0 "register_operand" "")
4541         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4542   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4543   "")
4544
4545 (define_insn "*floatdisf2_i387_only"
4546   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4547         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4548   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4549   "@
4550    fild%z1\t%1
4551    #"
4552   [(set_attr "type" "fmov,multi")
4553    (set_attr "mode" "SF")
4554    (set_attr "fp_int_src" "true")])
4555
4556 (define_insn "*floatdisf2_i387"
4557   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4558         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4559   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4560   "@
4561    fild%z1\t%1
4562    #
4563    cvtsi2ss{q}\t{%1, %0|%0, %1}
4564    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4565   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4566    (set_attr "mode" "SF")
4567    (set_attr "athlon_decode" "*,*,vector,double")
4568    (set_attr "fp_int_src" "true")])
4569
4570 (define_insn "*floatdisf2_sse"
4571   [(set (match_operand:SF 0 "register_operand" "=x,x")
4572         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4573   "TARGET_64BIT && TARGET_SSE"
4574   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4575   [(set_attr "type" "sseicvt")
4576    (set_attr "mode" "SF")
4577    (set_attr "athlon_decode" "vector,double")
4578    (set_attr "fp_int_src" "true")])
4579
4580 ; Avoid possible reformatting penalty on the destination by first
4581 ; zeroing it out
4582 (define_split
4583   [(set (match_operand:SF 0 "register_operand" "")
4584         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4585   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4586    && SSE_REG_P (operands[0])"
4587   [(const_int 0)]
4588 {
4589   rtx dest;
4590   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4591   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4592   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4593   DONE;
4594 })
4595
4596 (define_expand "floathidf2"
4597   [(set (match_operand:DF 0 "register_operand" "")
4598         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4599   "TARGET_SSE2 || TARGET_80387"
4600 {
4601   if (TARGET_SSE && TARGET_SSE_MATH)
4602     {
4603       emit_insn (gen_floatsidf2 (operands[0],
4604                                  convert_to_mode (SImode, operands[1], 0)));
4605       DONE;
4606     }
4607 })
4608
4609 (define_insn "*floathidf2_1"
4610   [(set (match_operand:DF 0 "register_operand" "=f,f")
4611         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4612   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4613   "@
4614    fild%z1\t%1
4615    #"
4616   [(set_attr "type" "fmov,multi")
4617    (set_attr "mode" "DF")
4618    (set_attr "fp_int_src" "true")])
4619
4620 (define_expand "floatsidf2"
4621   [(set (match_operand:DF 0 "register_operand" "")
4622         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4623   "TARGET_80387 || TARGET_SSE2"
4624   "")
4625
4626 (define_insn "*floatsidf2_i387"
4627   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4628         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4629   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4630   "@
4631    fild%z1\t%1
4632    #
4633    cvtsi2sd\t{%1, %0|%0, %1}
4634    cvtsi2sd\t{%1, %0|%0, %1}"
4635   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4636    (set_attr "mode" "DF")
4637    (set_attr "athlon_decode" "*,*,double,direct")
4638    (set_attr "fp_int_src" "true")])
4639
4640 (define_insn "*floatsidf2_sse"
4641   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4642         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4643   "TARGET_SSE2"
4644   "cvtsi2sd\t{%1, %0|%0, %1}"
4645   [(set_attr "type" "sseicvt")
4646    (set_attr "mode" "DF")
4647    (set_attr "athlon_decode" "double,direct")
4648    (set_attr "fp_int_src" "true")])
4649
4650 (define_expand "floatdidf2"
4651   [(set (match_operand:DF 0 "register_operand" "")
4652         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4653   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4654   "")
4655
4656 (define_insn "*floatdidf2_i387_only"
4657   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4658         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4659   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4660   "@
4661    fild%z1\t%1
4662    #"
4663   [(set_attr "type" "fmov,multi")
4664    (set_attr "mode" "DF")
4665    (set_attr "fp_int_src" "true")])
4666
4667 (define_insn "*floatdidf2_i387"
4668   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4669         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4670   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4671   "@
4672    fild%z1\t%1
4673    #
4674    cvtsi2sd{q}\t{%1, %0|%0, %1}
4675    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4676   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4677    (set_attr "mode" "DF")
4678    (set_attr "athlon_decode" "*,*,double,direct")
4679    (set_attr "fp_int_src" "true")])
4680
4681 (define_insn "*floatdidf2_sse"
4682   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4683         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4684   "TARGET_SSE2"
4685   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4686   [(set_attr "type" "sseicvt")
4687    (set_attr "mode" "DF")
4688    (set_attr "athlon_decode" "double,direct")
4689    (set_attr "fp_int_src" "true")])
4690
4691 (define_insn "floathixf2"
4692   [(set (match_operand:XF 0 "register_operand" "=f,f")
4693         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4694   "TARGET_80387"
4695   "@
4696    fild%z1\t%1
4697    #"
4698   [(set_attr "type" "fmov,multi")
4699    (set_attr "mode" "XF")
4700    (set_attr "fp_int_src" "true")])
4701
4702 (define_insn "floatsixf2"
4703   [(set (match_operand:XF 0 "register_operand" "=f,f")
4704         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4705   "TARGET_80387"
4706   "@
4707    fild%z1\t%1
4708    #"
4709   [(set_attr "type" "fmov,multi")
4710    (set_attr "mode" "XF")
4711    (set_attr "fp_int_src" "true")])
4712
4713 (define_insn "floatdixf2"
4714   [(set (match_operand:XF 0 "register_operand" "=f,f")
4715         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4716   "TARGET_80387"
4717   "@
4718    fild%z1\t%1
4719    #"
4720   [(set_attr "type" "fmov,multi")
4721    (set_attr "mode" "XF")
4722    (set_attr "fp_int_src" "true")])
4723
4724 ;; %%% Kill these when reload knows how to do it.
4725 (define_split
4726   [(set (match_operand 0 "fp_register_operand" "")
4727         (float (match_operand 1 "register_operand" "")))]
4728   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4729   [(const_int 0)]
4730 {
4731   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4732   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4733   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4734   ix86_free_from_memory (GET_MODE (operands[1]));
4735   DONE;
4736 })
4737
4738 (define_expand "floatunssisf2"
4739   [(use (match_operand:SF 0 "register_operand" ""))
4740    (use (match_operand:SI 1 "register_operand" ""))]
4741   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4742   "x86_emit_floatuns (operands); DONE;")
4743
4744 (define_expand "floatunsdisf2"
4745   [(use (match_operand:SF 0 "register_operand" ""))
4746    (use (match_operand:DI 1 "register_operand" ""))]
4747   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4748   "x86_emit_floatuns (operands); DONE;")
4749
4750 (define_expand "floatunsdidf2"
4751   [(use (match_operand:DF 0 "register_operand" ""))
4752    (use (match_operand:DI 1 "register_operand" ""))]
4753   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4754   "x86_emit_floatuns (operands); DONE;")
4755 \f
4756 ;; SSE extract/set expanders
4757
4758 (define_expand "vec_setv2df"
4759   [(match_operand:V2DF 0 "register_operand" "")
4760    (match_operand:DF 1 "register_operand" "")
4761    (match_operand 2 "const_int_operand" "")]
4762   "TARGET_SSE2"
4763 {
4764   switch (INTVAL (operands[2]))
4765     {
4766     case 0:
4767       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4768                                  simplify_gen_subreg (V2DFmode, operands[1],
4769                                                       DFmode, 0)));
4770       break;
4771     case 1:
4772       {
4773         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4774
4775         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4776       }
4777       break;
4778     default:
4779       abort ();
4780     }
4781   DONE;
4782 })
4783
4784 (define_expand "vec_extractv2df"
4785   [(match_operand:DF 0 "register_operand" "")
4786    (match_operand:V2DF 1 "register_operand" "")
4787    (match_operand 2 "const_int_operand" "")]
4788   "TARGET_SSE2"
4789 {
4790   switch (INTVAL (operands[2]))
4791     {
4792     case 0:
4793       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4794       break;
4795     case 1:
4796       {
4797         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4798
4799         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4800       }
4801       break;
4802     default:
4803       abort ();
4804     }
4805   DONE;
4806 })
4807
4808 (define_expand "vec_initv2df"
4809   [(match_operand:V2DF 0 "register_operand" "")
4810    (match_operand 1 "" "")]
4811   "TARGET_SSE2"
4812 {
4813   ix86_expand_vector_init (operands[0], operands[1]);
4814   DONE;
4815 })
4816
4817 (define_expand "vec_setv4sf"
4818   [(match_operand:V4SF 0 "register_operand" "")
4819    (match_operand:SF 1 "register_operand" "")
4820    (match_operand 2 "const_int_operand" "")]
4821   "TARGET_SSE"
4822 {
4823   switch (INTVAL (operands[2]))
4824     {
4825     case 0:
4826       emit_insn (gen_sse_movss (operands[0], operands[0],
4827                                 simplify_gen_subreg (V4SFmode, operands[1],
4828                                                      SFmode, 0)));
4829       break;
4830     case 1:
4831       {
4832         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4833         rtx tmp = gen_reg_rtx (V4SFmode);
4834  
4835         emit_move_insn (tmp, operands[0]);
4836         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4837         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4838         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4839                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4840       }
4841     case 2:
4842       {
4843         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4844         rtx tmp = gen_reg_rtx (V4SFmode);
4845
4846         emit_move_insn (tmp, operands[0]);
4847         emit_insn (gen_sse_movss (tmp, tmp, op1));
4848         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4849                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4850       }
4851       break;
4852     case 3:
4853       {
4854         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4855         rtx tmp = gen_reg_rtx (V4SFmode);
4856
4857         emit_move_insn (tmp, operands[0]);
4858         emit_insn (gen_sse_movss (tmp, tmp, op1));
4859         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4860                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4861       }
4862       break;
4863     default:
4864       abort ();
4865     }
4866   DONE;
4867 })
4868
4869 (define_expand "vec_extractv4sf"
4870   [(match_operand:SF 0 "register_operand" "")
4871    (match_operand:V4SF 1 "register_operand" "")
4872    (match_operand 2 "const_int_operand" "")]
4873   "TARGET_SSE"
4874 {
4875   switch (INTVAL (operands[2]))
4876     {
4877     case 0:
4878       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4879       break;
4880     case 1:
4881       {
4882         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4883         rtx tmp = gen_reg_rtx (V4SFmode);
4884  
4885         emit_move_insn (tmp, operands[1]);
4886         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4887                                    const1_rtx));
4888       }
4889     case 2:
4890       {
4891         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4892         rtx tmp = gen_reg_rtx (V4SFmode);
4893  
4894         emit_move_insn (tmp, operands[1]);
4895         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4896       }
4897     case 3:
4898       {
4899         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4900         rtx tmp = gen_reg_rtx (V4SFmode);
4901  
4902         emit_move_insn (tmp, operands[1]);
4903         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4904                                    GEN_INT (3)));
4905       }
4906     default:
4907       abort ();
4908     }
4909   DONE;
4910 })
4911
4912 (define_expand "vec_initv4sf"
4913   [(match_operand:V4SF 0 "register_operand" "")
4914    (match_operand 1 "" "")]
4915   "TARGET_SSE"
4916 {
4917   ix86_expand_vector_init (operands[0], operands[1]);
4918   DONE;
4919 })
4920 \f
4921 ;; Add instructions
4922
4923 ;; %%% splits for addsidi3
4924 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4925 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4926 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4927
4928 (define_expand "adddi3"
4929   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4930         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4931                  (match_operand:DI 2 "x86_64_general_operand" "")))
4932    (clobber (reg:CC FLAGS_REG))]
4933   ""
4934   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4935
4936 (define_insn "*adddi3_1"
4937   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4938         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4939                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4940    (clobber (reg:CC FLAGS_REG))]
4941   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4942   "#")
4943
4944 (define_split
4945   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4946         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4947                  (match_operand:DI 2 "general_operand" "")))
4948    (clobber (reg:CC FLAGS_REG))]
4949   "!TARGET_64BIT && reload_completed"
4950   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4951                                           UNSPEC_ADD_CARRY))
4952               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4953    (parallel [(set (match_dup 3)
4954                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4955                                      (match_dup 4))
4956                             (match_dup 5)))
4957               (clobber (reg:CC FLAGS_REG))])]
4958   "split_di (operands+0, 1, operands+0, operands+3);
4959    split_di (operands+1, 1, operands+1, operands+4);
4960    split_di (operands+2, 1, operands+2, operands+5);")
4961
4962 (define_insn "adddi3_carry_rex64"
4963   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4964           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4965                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4966                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4967    (clobber (reg:CC FLAGS_REG))]
4968   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4969   "adc{q}\t{%2, %0|%0, %2}"
4970   [(set_attr "type" "alu")
4971    (set_attr "pent_pair" "pu")
4972    (set_attr "mode" "DI")])
4973
4974 (define_insn "*adddi3_cc_rex64"
4975   [(set (reg:CC FLAGS_REG)
4976         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4977                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4978                    UNSPEC_ADD_CARRY))
4979    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4980         (plus:DI (match_dup 1) (match_dup 2)))]
4981   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4982   "add{q}\t{%2, %0|%0, %2}"
4983   [(set_attr "type" "alu")
4984    (set_attr "mode" "DI")])
4985
4986 (define_insn "addqi3_carry"
4987   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4988           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4989                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4990                    (match_operand:QI 2 "general_operand" "qi,qm")))
4991    (clobber (reg:CC FLAGS_REG))]
4992   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4993   "adc{b}\t{%2, %0|%0, %2}"
4994   [(set_attr "type" "alu")
4995    (set_attr "pent_pair" "pu")
4996    (set_attr "mode" "QI")])
4997
4998 (define_insn "addhi3_carry"
4999   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5000           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5001                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5002                    (match_operand:HI 2 "general_operand" "ri,rm")))
5003    (clobber (reg:CC FLAGS_REG))]
5004   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5005   "adc{w}\t{%2, %0|%0, %2}"
5006   [(set_attr "type" "alu")
5007    (set_attr "pent_pair" "pu")
5008    (set_attr "mode" "HI")])
5009
5010 (define_insn "addsi3_carry"
5011   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5012           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5013                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5014                    (match_operand:SI 2 "general_operand" "ri,rm")))
5015    (clobber (reg:CC FLAGS_REG))]
5016   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5017   "adc{l}\t{%2, %0|%0, %2}"
5018   [(set_attr "type" "alu")
5019    (set_attr "pent_pair" "pu")
5020    (set_attr "mode" "SI")])
5021
5022 (define_insn "*addsi3_carry_zext"
5023   [(set (match_operand:DI 0 "register_operand" "=r")
5024           (zero_extend:DI 
5025             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5026                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5027                      (match_operand:SI 2 "general_operand" "rim"))))
5028    (clobber (reg:CC FLAGS_REG))]
5029   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5030   "adc{l}\t{%2, %k0|%k0, %2}"
5031   [(set_attr "type" "alu")
5032    (set_attr "pent_pair" "pu")
5033    (set_attr "mode" "SI")])
5034
5035 (define_insn "*addsi3_cc"
5036   [(set (reg:CC FLAGS_REG)
5037         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5038                     (match_operand:SI 2 "general_operand" "ri,rm")]
5039                    UNSPEC_ADD_CARRY))
5040    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5041         (plus:SI (match_dup 1) (match_dup 2)))]
5042   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5043   "add{l}\t{%2, %0|%0, %2}"
5044   [(set_attr "type" "alu")
5045    (set_attr "mode" "SI")])
5046
5047 (define_insn "addqi3_cc"
5048   [(set (reg:CC FLAGS_REG)
5049         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5050                     (match_operand:QI 2 "general_operand" "qi,qm")]
5051                    UNSPEC_ADD_CARRY))
5052    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5053         (plus:QI (match_dup 1) (match_dup 2)))]
5054   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5055   "add{b}\t{%2, %0|%0, %2}"
5056   [(set_attr "type" "alu")
5057    (set_attr "mode" "QI")])
5058
5059 (define_expand "addsi3"
5060   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5061                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5062                             (match_operand:SI 2 "general_operand" "")))
5063               (clobber (reg:CC FLAGS_REG))])]
5064   ""
5065   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5066
5067 (define_insn "*lea_1"
5068   [(set (match_operand:SI 0 "register_operand" "=r")
5069         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5070   "!TARGET_64BIT"
5071   "lea{l}\t{%a1, %0|%0, %a1}"
5072   [(set_attr "type" "lea")
5073    (set_attr "mode" "SI")])
5074
5075 (define_insn "*lea_1_rex64"
5076   [(set (match_operand:SI 0 "register_operand" "=r")
5077         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5078   "TARGET_64BIT"
5079   "lea{l}\t{%a1, %0|%0, %a1}"
5080   [(set_attr "type" "lea")
5081    (set_attr "mode" "SI")])
5082
5083 (define_insn "*lea_1_zext"
5084   [(set (match_operand:DI 0 "register_operand" "=r")
5085         (zero_extend:DI
5086          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5087   "TARGET_64BIT"
5088   "lea{l}\t{%a1, %k0|%k0, %a1}"
5089   [(set_attr "type" "lea")
5090    (set_attr "mode" "SI")])
5091
5092 (define_insn "*lea_2_rex64"
5093   [(set (match_operand:DI 0 "register_operand" "=r")
5094         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5095   "TARGET_64BIT"
5096   "lea{q}\t{%a1, %0|%0, %a1}"
5097   [(set_attr "type" "lea")
5098    (set_attr "mode" "DI")])
5099
5100 ;; The lea patterns for non-Pmodes needs to be matched by several
5101 ;; insns converted to real lea by splitters.
5102
5103 (define_insn_and_split "*lea_general_1"
5104   [(set (match_operand 0 "register_operand" "=r")
5105         (plus (plus (match_operand 1 "index_register_operand" "r")
5106                     (match_operand 2 "register_operand" "r"))
5107               (match_operand 3 "immediate_operand" "i")))]
5108   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5109     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5110    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5111    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5112    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5113    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5114        || GET_MODE (operands[3]) == VOIDmode)"
5115   "#"
5116   "&& reload_completed"
5117   [(const_int 0)]
5118 {
5119   rtx pat;
5120   operands[0] = gen_lowpart (SImode, operands[0]);
5121   operands[1] = gen_lowpart (Pmode, operands[1]);
5122   operands[2] = gen_lowpart (Pmode, operands[2]);
5123   operands[3] = gen_lowpart (Pmode, operands[3]);
5124   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5125                       operands[3]);
5126   if (Pmode != SImode)
5127     pat = gen_rtx_SUBREG (SImode, pat, 0);
5128   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5129   DONE;
5130 }
5131   [(set_attr "type" "lea")
5132    (set_attr "mode" "SI")])
5133
5134 (define_insn_and_split "*lea_general_1_zext"
5135   [(set (match_operand:DI 0 "register_operand" "=r")
5136         (zero_extend:DI
5137           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5138                             (match_operand:SI 2 "register_operand" "r"))
5139                    (match_operand:SI 3 "immediate_operand" "i"))))]
5140   "TARGET_64BIT"
5141   "#"
5142   "&& reload_completed"
5143   [(set (match_dup 0)
5144         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5145                                                      (match_dup 2))
5146                                             (match_dup 3)) 0)))]
5147 {
5148   operands[1] = gen_lowpart (Pmode, operands[1]);
5149   operands[2] = gen_lowpart (Pmode, operands[2]);
5150   operands[3] = gen_lowpart (Pmode, operands[3]);
5151 }
5152   [(set_attr "type" "lea")
5153    (set_attr "mode" "SI")])
5154
5155 (define_insn_and_split "*lea_general_2"
5156   [(set (match_operand 0 "register_operand" "=r")
5157         (plus (mult (match_operand 1 "index_register_operand" "r")
5158                     (match_operand 2 "const248_operand" "i"))
5159               (match_operand 3 "nonmemory_operand" "ri")))]
5160   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5161     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5162    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5163    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5164    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5165        || GET_MODE (operands[3]) == VOIDmode)"
5166   "#"
5167   "&& reload_completed"
5168   [(const_int 0)]
5169 {
5170   rtx pat;
5171   operands[0] = gen_lowpart (SImode, operands[0]);
5172   operands[1] = gen_lowpart (Pmode, operands[1]);
5173   operands[3] = gen_lowpart (Pmode, operands[3]);
5174   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5175                       operands[3]);
5176   if (Pmode != SImode)
5177     pat = gen_rtx_SUBREG (SImode, pat, 0);
5178   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5179   DONE;
5180 }
5181   [(set_attr "type" "lea")
5182    (set_attr "mode" "SI")])
5183
5184 (define_insn_and_split "*lea_general_2_zext"
5185   [(set (match_operand:DI 0 "register_operand" "=r")
5186         (zero_extend:DI
5187           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5188                             (match_operand:SI 2 "const248_operand" "n"))
5189                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5190   "TARGET_64BIT"
5191   "#"
5192   "&& reload_completed"
5193   [(set (match_dup 0)
5194         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5195                                                      (match_dup 2))
5196                                             (match_dup 3)) 0)))]
5197 {
5198   operands[1] = gen_lowpart (Pmode, operands[1]);
5199   operands[3] = gen_lowpart (Pmode, operands[3]);
5200 }
5201   [(set_attr "type" "lea")
5202    (set_attr "mode" "SI")])
5203
5204 (define_insn_and_split "*lea_general_3"
5205   [(set (match_operand 0 "register_operand" "=r")
5206         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5207                           (match_operand 2 "const248_operand" "i"))
5208                     (match_operand 3 "register_operand" "r"))
5209               (match_operand 4 "immediate_operand" "i")))]
5210   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5211     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5212    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5213    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5214    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5215   "#"
5216   "&& reload_completed"
5217   [(const_int 0)]
5218 {
5219   rtx pat;
5220   operands[0] = gen_lowpart (SImode, operands[0]);
5221   operands[1] = gen_lowpart (Pmode, operands[1]);
5222   operands[3] = gen_lowpart (Pmode, operands[3]);
5223   operands[4] = gen_lowpart (Pmode, operands[4]);
5224   pat = gen_rtx_PLUS (Pmode,
5225                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5226                                                          operands[2]),
5227                                     operands[3]),
5228                       operands[4]);
5229   if (Pmode != SImode)
5230     pat = gen_rtx_SUBREG (SImode, pat, 0);
5231   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5232   DONE;
5233 }
5234   [(set_attr "type" "lea")
5235    (set_attr "mode" "SI")])
5236
5237 (define_insn_and_split "*lea_general_3_zext"
5238   [(set (match_operand:DI 0 "register_operand" "=r")
5239         (zero_extend:DI
5240           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5241                                      (match_operand:SI 2 "const248_operand" "n"))
5242                             (match_operand:SI 3 "register_operand" "r"))
5243                    (match_operand:SI 4 "immediate_operand" "i"))))]
5244   "TARGET_64BIT"
5245   "#"
5246   "&& reload_completed"
5247   [(set (match_dup 0)
5248         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5249                                                               (match_dup 2))
5250                                                      (match_dup 3))
5251                                             (match_dup 4)) 0)))]
5252 {
5253   operands[1] = gen_lowpart (Pmode, operands[1]);
5254   operands[3] = gen_lowpart (Pmode, operands[3]);
5255   operands[4] = gen_lowpart (Pmode, operands[4]);
5256 }
5257   [(set_attr "type" "lea")
5258    (set_attr "mode" "SI")])
5259
5260 (define_insn "*adddi_1_rex64"
5261   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5262         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5263                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5264    (clobber (reg:CC FLAGS_REG))]
5265   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5266 {
5267   switch (get_attr_type (insn))
5268     {
5269     case TYPE_LEA:
5270       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5271       return "lea{q}\t{%a2, %0|%0, %a2}";
5272
5273     case TYPE_INCDEC:
5274       if (! rtx_equal_p (operands[0], operands[1]))
5275         abort ();
5276       if (operands[2] == const1_rtx)
5277         return "inc{q}\t%0";
5278       else if (operands[2] == constm1_rtx)
5279         return "dec{q}\t%0";
5280       else
5281         abort ();
5282
5283     default:
5284       if (! rtx_equal_p (operands[0], operands[1]))
5285         abort ();
5286
5287       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5288          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5289       if (GET_CODE (operands[2]) == CONST_INT
5290           /* Avoid overflows.  */
5291           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5292           && (INTVAL (operands[2]) == 128
5293               || (INTVAL (operands[2]) < 0
5294                   && INTVAL (operands[2]) != -128)))
5295         {
5296           operands[2] = GEN_INT (-INTVAL (operands[2]));
5297           return "sub{q}\t{%2, %0|%0, %2}";
5298         }
5299       return "add{q}\t{%2, %0|%0, %2}";
5300     }
5301 }
5302   [(set (attr "type")
5303      (cond [(eq_attr "alternative" "2")
5304               (const_string "lea")
5305             ; Current assemblers are broken and do not allow @GOTOFF in
5306             ; ought but a memory context.
5307             (match_operand:DI 2 "pic_symbolic_operand" "")
5308               (const_string "lea")
5309             (match_operand:DI 2 "incdec_operand" "")
5310               (const_string "incdec")
5311            ]
5312            (const_string "alu")))
5313    (set_attr "mode" "DI")])
5314
5315 ;; Convert lea to the lea pattern to avoid flags dependency.
5316 (define_split
5317   [(set (match_operand:DI 0 "register_operand" "")
5318         (plus:DI (match_operand:DI 1 "register_operand" "")
5319                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5320    (clobber (reg:CC FLAGS_REG))]
5321   "TARGET_64BIT && reload_completed
5322    && true_regnum (operands[0]) != true_regnum (operands[1])"
5323   [(set (match_dup 0)
5324         (plus:DI (match_dup 1)
5325                  (match_dup 2)))]
5326   "")
5327
5328 (define_insn "*adddi_2_rex64"
5329   [(set (reg 17)
5330         (compare
5331           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5332                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5333           (const_int 0)))                       
5334    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5335         (plus:DI (match_dup 1) (match_dup 2)))]
5336   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5337    && ix86_binary_operator_ok (PLUS, DImode, operands)
5338    /* Current assemblers are broken and do not allow @GOTOFF in
5339       ought but a memory context.  */
5340    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5341 {
5342   switch (get_attr_type (insn))
5343     {
5344     case TYPE_INCDEC:
5345       if (! rtx_equal_p (operands[0], operands[1]))
5346         abort ();
5347       if (operands[2] == const1_rtx)
5348         return "inc{q}\t%0";
5349       else if (operands[2] == constm1_rtx)
5350         return "dec{q}\t%0";
5351       else
5352         abort ();
5353
5354     default:
5355       if (! rtx_equal_p (operands[0], operands[1]))
5356         abort ();
5357       /* ???? We ought to handle there the 32bit case too
5358          - do we need new constraint?  */
5359       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5360          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5361       if (GET_CODE (operands[2]) == CONST_INT
5362           /* Avoid overflows.  */
5363           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5364           && (INTVAL (operands[2]) == 128
5365               || (INTVAL (operands[2]) < 0
5366                   && INTVAL (operands[2]) != -128)))
5367         {
5368           operands[2] = GEN_INT (-INTVAL (operands[2]));
5369           return "sub{q}\t{%2, %0|%0, %2}";
5370         }
5371       return "add{q}\t{%2, %0|%0, %2}";
5372     }
5373 }
5374   [(set (attr "type")
5375      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5376         (const_string "incdec")
5377         (const_string "alu")))
5378    (set_attr "mode" "DI")])
5379
5380 (define_insn "*adddi_3_rex64"
5381   [(set (reg 17)
5382         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5383                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5384    (clobber (match_scratch:DI 0 "=r"))]
5385   "TARGET_64BIT
5386    && ix86_match_ccmode (insn, CCZmode)
5387    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5388    /* Current assemblers are broken and do not allow @GOTOFF in
5389       ought but a memory context.  */
5390    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5391 {
5392   switch (get_attr_type (insn))
5393     {
5394     case TYPE_INCDEC:
5395       if (! rtx_equal_p (operands[0], operands[1]))
5396         abort ();
5397       if (operands[2] == const1_rtx)
5398         return "inc{q}\t%0";
5399       else if (operands[2] == constm1_rtx)
5400         return "dec{q}\t%0";
5401       else
5402         abort ();
5403
5404     default:
5405       if (! rtx_equal_p (operands[0], operands[1]))
5406         abort ();
5407       /* ???? We ought to handle there the 32bit case too
5408          - do we need new constraint?  */
5409       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5410          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5411       if (GET_CODE (operands[2]) == CONST_INT
5412           /* Avoid overflows.  */
5413           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5414           && (INTVAL (operands[2]) == 128
5415               || (INTVAL (operands[2]) < 0
5416                   && INTVAL (operands[2]) != -128)))
5417         {
5418           operands[2] = GEN_INT (-INTVAL (operands[2]));
5419           return "sub{q}\t{%2, %0|%0, %2}";
5420         }
5421       return "add{q}\t{%2, %0|%0, %2}";
5422     }
5423 }
5424   [(set (attr "type")
5425      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5426         (const_string "incdec")
5427         (const_string "alu")))
5428    (set_attr "mode" "DI")])
5429
5430 ; For comparisons against 1, -1 and 128, we may generate better code
5431 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5432 ; is matched then.  We can't accept general immediate, because for
5433 ; case of overflows,  the result is messed up.
5434 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5435 ; when negated.
5436 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5437 ; only for comparisons not depending on it.
5438 (define_insn "*adddi_4_rex64"
5439   [(set (reg 17)
5440         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5441                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5442    (clobber (match_scratch:DI 0 "=rm"))]
5443   "TARGET_64BIT
5444    &&  ix86_match_ccmode (insn, CCGCmode)"
5445 {
5446   switch (get_attr_type (insn))
5447     {
5448     case TYPE_INCDEC:
5449       if (operands[2] == constm1_rtx)
5450         return "inc{q}\t%0";
5451       else if (operands[2] == const1_rtx)
5452         return "dec{q}\t%0";
5453       else
5454         abort();
5455
5456     default:
5457       if (! rtx_equal_p (operands[0], operands[1]))
5458         abort ();
5459       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5460          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5461       if ((INTVAL (operands[2]) == -128
5462            || (INTVAL (operands[2]) > 0
5463                && INTVAL (operands[2]) != 128))
5464           /* Avoid overflows.  */
5465           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5466         return "sub{q}\t{%2, %0|%0, %2}";
5467       operands[2] = GEN_INT (-INTVAL (operands[2]));
5468       return "add{q}\t{%2, %0|%0, %2}";
5469     }
5470 }
5471   [(set (attr "type")
5472      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5473         (const_string "incdec")
5474         (const_string "alu")))
5475    (set_attr "mode" "DI")])
5476
5477 (define_insn "*adddi_5_rex64"
5478   [(set (reg 17)
5479         (compare
5480           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5481                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5482           (const_int 0)))                       
5483    (clobber (match_scratch:DI 0 "=r"))]
5484   "TARGET_64BIT
5485    && ix86_match_ccmode (insn, CCGOCmode)
5486    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5487    /* Current assemblers are broken and do not allow @GOTOFF in
5488       ought but a memory context.  */
5489    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5490 {
5491   switch (get_attr_type (insn))
5492     {
5493     case TYPE_INCDEC:
5494       if (! rtx_equal_p (operands[0], operands[1]))
5495         abort ();
5496       if (operands[2] == const1_rtx)
5497         return "inc{q}\t%0";
5498       else if (operands[2] == constm1_rtx)
5499         return "dec{q}\t%0";
5500       else
5501         abort();
5502
5503     default:
5504       if (! rtx_equal_p (operands[0], operands[1]))
5505         abort ();
5506       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5507          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5508       if (GET_CODE (operands[2]) == CONST_INT
5509           /* Avoid overflows.  */
5510           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5511           && (INTVAL (operands[2]) == 128
5512               || (INTVAL (operands[2]) < 0
5513                   && INTVAL (operands[2]) != -128)))
5514         {
5515           operands[2] = GEN_INT (-INTVAL (operands[2]));
5516           return "sub{q}\t{%2, %0|%0, %2}";
5517         }
5518       return "add{q}\t{%2, %0|%0, %2}";
5519     }
5520 }
5521   [(set (attr "type")
5522      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5523         (const_string "incdec")
5524         (const_string "alu")))
5525    (set_attr "mode" "DI")])
5526
5527
5528 (define_insn "*addsi_1"
5529   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5530         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5531                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5532    (clobber (reg:CC FLAGS_REG))]
5533   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5534 {
5535   switch (get_attr_type (insn))
5536     {
5537     case TYPE_LEA:
5538       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5539       return "lea{l}\t{%a2, %0|%0, %a2}";
5540
5541     case TYPE_INCDEC:
5542       if (! rtx_equal_p (operands[0], operands[1]))
5543         abort ();
5544       if (operands[2] == const1_rtx)
5545         return "inc{l}\t%0";
5546       else if (operands[2] == constm1_rtx)
5547         return "dec{l}\t%0";
5548       else
5549         abort();
5550
5551     default:
5552       if (! rtx_equal_p (operands[0], operands[1]))
5553         abort ();
5554
5555       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5556          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5557       if (GET_CODE (operands[2]) == CONST_INT
5558           && (INTVAL (operands[2]) == 128
5559               || (INTVAL (operands[2]) < 0
5560                   && INTVAL (operands[2]) != -128)))
5561         {
5562           operands[2] = GEN_INT (-INTVAL (operands[2]));
5563           return "sub{l}\t{%2, %0|%0, %2}";
5564         }
5565       return "add{l}\t{%2, %0|%0, %2}";
5566     }
5567 }
5568   [(set (attr "type")
5569      (cond [(eq_attr "alternative" "2")
5570               (const_string "lea")
5571             ; Current assemblers are broken and do not allow @GOTOFF in
5572             ; ought but a memory context.
5573             (match_operand:SI 2 "pic_symbolic_operand" "")
5574               (const_string "lea")
5575             (match_operand:SI 2 "incdec_operand" "")
5576               (const_string "incdec")
5577            ]
5578            (const_string "alu")))
5579    (set_attr "mode" "SI")])
5580
5581 ;; Convert lea to the lea pattern to avoid flags dependency.
5582 (define_split
5583   [(set (match_operand 0 "register_operand" "")
5584         (plus (match_operand 1 "register_operand" "")
5585               (match_operand 2 "nonmemory_operand" "")))
5586    (clobber (reg:CC FLAGS_REG))]
5587   "reload_completed
5588    && true_regnum (operands[0]) != true_regnum (operands[1])"
5589   [(const_int 0)]
5590 {
5591   rtx pat;
5592   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5593      may confuse gen_lowpart.  */
5594   if (GET_MODE (operands[0]) != Pmode)
5595     {
5596       operands[1] = gen_lowpart (Pmode, operands[1]);
5597       operands[2] = gen_lowpart (Pmode, operands[2]);
5598     }
5599   operands[0] = gen_lowpart (SImode, operands[0]);
5600   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5601   if (Pmode != SImode)
5602     pat = gen_rtx_SUBREG (SImode, pat, 0);
5603   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5604   DONE;
5605 })
5606
5607 ;; It may seem that nonimmediate operand is proper one for operand 1.
5608 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5609 ;; we take care in ix86_binary_operator_ok to not allow two memory
5610 ;; operands so proper swapping will be done in reload.  This allow
5611 ;; patterns constructed from addsi_1 to match.
5612 (define_insn "addsi_1_zext"
5613   [(set (match_operand:DI 0 "register_operand" "=r,r")
5614         (zero_extend:DI
5615           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5616                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5617    (clobber (reg:CC FLAGS_REG))]
5618   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5619 {
5620   switch (get_attr_type (insn))
5621     {
5622     case TYPE_LEA:
5623       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5624       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5625
5626     case TYPE_INCDEC:
5627       if (operands[2] == const1_rtx)
5628         return "inc{l}\t%k0";
5629       else if (operands[2] == constm1_rtx)
5630         return "dec{l}\t%k0";
5631       else
5632         abort();
5633
5634     default:
5635       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5636          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5637       if (GET_CODE (operands[2]) == CONST_INT
5638           && (INTVAL (operands[2]) == 128
5639               || (INTVAL (operands[2]) < 0
5640                   && INTVAL (operands[2]) != -128)))
5641         {
5642           operands[2] = GEN_INT (-INTVAL (operands[2]));
5643           return "sub{l}\t{%2, %k0|%k0, %2}";
5644         }
5645       return "add{l}\t{%2, %k0|%k0, %2}";
5646     }
5647 }
5648   [(set (attr "type")
5649      (cond [(eq_attr "alternative" "1")
5650               (const_string "lea")
5651             ; Current assemblers are broken and do not allow @GOTOFF in
5652             ; ought but a memory context.
5653             (match_operand:SI 2 "pic_symbolic_operand" "")
5654               (const_string "lea")
5655             (match_operand:SI 2 "incdec_operand" "")
5656               (const_string "incdec")
5657            ]
5658            (const_string "alu")))
5659    (set_attr "mode" "SI")])
5660
5661 ;; Convert lea to the lea pattern to avoid flags dependency.
5662 (define_split
5663   [(set (match_operand:DI 0 "register_operand" "")
5664         (zero_extend:DI
5665           (plus:SI (match_operand:SI 1 "register_operand" "")
5666                    (match_operand:SI 2 "nonmemory_operand" ""))))
5667    (clobber (reg:CC FLAGS_REG))]
5668   "TARGET_64BIT && reload_completed
5669    && true_regnum (operands[0]) != true_regnum (operands[1])"
5670   [(set (match_dup 0)
5671         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5672 {
5673   operands[1] = gen_lowpart (Pmode, operands[1]);
5674   operands[2] = gen_lowpart (Pmode, operands[2]);
5675 })
5676
5677 (define_insn "*addsi_2"
5678   [(set (reg 17)
5679         (compare
5680           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5681                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5682           (const_int 0)))                       
5683    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5684         (plus:SI (match_dup 1) (match_dup 2)))]
5685   "ix86_match_ccmode (insn, CCGOCmode)
5686    && ix86_binary_operator_ok (PLUS, SImode, operands)
5687    /* Current assemblers are broken and do not allow @GOTOFF in
5688       ought but a memory context.  */
5689    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5690 {
5691   switch (get_attr_type (insn))
5692     {
5693     case TYPE_INCDEC:
5694       if (! rtx_equal_p (operands[0], operands[1]))
5695         abort ();
5696       if (operands[2] == const1_rtx)
5697         return "inc{l}\t%0";
5698       else if (operands[2] == constm1_rtx)
5699         return "dec{l}\t%0";
5700       else
5701         abort();
5702
5703     default:
5704       if (! rtx_equal_p (operands[0], operands[1]))
5705         abort ();
5706       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5707          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5708       if (GET_CODE (operands[2]) == CONST_INT
5709           && (INTVAL (operands[2]) == 128
5710               || (INTVAL (operands[2]) < 0
5711                   && INTVAL (operands[2]) != -128)))
5712         {
5713           operands[2] = GEN_INT (-INTVAL (operands[2]));
5714           return "sub{l}\t{%2, %0|%0, %2}";
5715         }
5716       return "add{l}\t{%2, %0|%0, %2}";
5717     }
5718 }
5719   [(set (attr "type")
5720      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5721         (const_string "incdec")
5722         (const_string "alu")))
5723    (set_attr "mode" "SI")])
5724
5725 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5726 (define_insn "*addsi_2_zext"
5727   [(set (reg 17)
5728         (compare
5729           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5730                    (match_operand:SI 2 "general_operand" "rmni"))
5731           (const_int 0)))                       
5732    (set (match_operand:DI 0 "register_operand" "=r")
5733         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5734   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5735    && ix86_binary_operator_ok (PLUS, SImode, operands)
5736    /* Current assemblers are broken and do not allow @GOTOFF in
5737       ought but a memory context.  */
5738    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5739 {
5740   switch (get_attr_type (insn))
5741     {
5742     case TYPE_INCDEC:
5743       if (operands[2] == const1_rtx)
5744         return "inc{l}\t%k0";
5745       else if (operands[2] == constm1_rtx)
5746         return "dec{l}\t%k0";
5747       else
5748         abort();
5749
5750     default:
5751       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5752          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5753       if (GET_CODE (operands[2]) == CONST_INT
5754           && (INTVAL (operands[2]) == 128
5755               || (INTVAL (operands[2]) < 0
5756                   && INTVAL (operands[2]) != -128)))
5757         {
5758           operands[2] = GEN_INT (-INTVAL (operands[2]));
5759           return "sub{l}\t{%2, %k0|%k0, %2}";
5760         }
5761       return "add{l}\t{%2, %k0|%k0, %2}";
5762     }
5763 }
5764   [(set (attr "type")
5765      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5766         (const_string "incdec")
5767         (const_string "alu")))
5768    (set_attr "mode" "SI")])
5769
5770 (define_insn "*addsi_3"
5771   [(set (reg 17)
5772         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5773                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5774    (clobber (match_scratch:SI 0 "=r"))]
5775   "ix86_match_ccmode (insn, CCZmode)
5776    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5777    /* Current assemblers are broken and do not allow @GOTOFF in
5778       ought but a memory context.  */
5779    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5780 {
5781   switch (get_attr_type (insn))
5782     {
5783     case TYPE_INCDEC:
5784       if (! rtx_equal_p (operands[0], operands[1]))
5785         abort ();
5786       if (operands[2] == const1_rtx)
5787         return "inc{l}\t%0";
5788       else if (operands[2] == constm1_rtx)
5789         return "dec{l}\t%0";
5790       else
5791         abort();
5792
5793     default:
5794       if (! rtx_equal_p (operands[0], operands[1]))
5795         abort ();
5796       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5797          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5798       if (GET_CODE (operands[2]) == CONST_INT
5799           && (INTVAL (operands[2]) == 128
5800               || (INTVAL (operands[2]) < 0
5801                   && INTVAL (operands[2]) != -128)))
5802         {
5803           operands[2] = GEN_INT (-INTVAL (operands[2]));
5804           return "sub{l}\t{%2, %0|%0, %2}";
5805         }
5806       return "add{l}\t{%2, %0|%0, %2}";
5807     }
5808 }
5809   [(set (attr "type")
5810      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5811         (const_string "incdec")
5812         (const_string "alu")))
5813    (set_attr "mode" "SI")])
5814
5815 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5816 (define_insn "*addsi_3_zext"
5817   [(set (reg 17)
5818         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5819                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5820    (set (match_operand:DI 0 "register_operand" "=r")
5821         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5822   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5823    && ix86_binary_operator_ok (PLUS, SImode, operands)
5824    /* Current assemblers are broken and do not allow @GOTOFF in
5825       ought but a memory context.  */
5826    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5827 {
5828   switch (get_attr_type (insn))
5829     {
5830     case TYPE_INCDEC:
5831       if (operands[2] == const1_rtx)
5832         return "inc{l}\t%k0";
5833       else if (operands[2] == constm1_rtx)
5834         return "dec{l}\t%k0";
5835       else
5836         abort();
5837
5838     default:
5839       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5840          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5841       if (GET_CODE (operands[2]) == CONST_INT
5842           && (INTVAL (operands[2]) == 128
5843               || (INTVAL (operands[2]) < 0
5844                   && INTVAL (operands[2]) != -128)))
5845         {
5846           operands[2] = GEN_INT (-INTVAL (operands[2]));
5847           return "sub{l}\t{%2, %k0|%k0, %2}";
5848         }
5849       return "add{l}\t{%2, %k0|%k0, %2}";
5850     }
5851 }
5852   [(set (attr "type")
5853      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5854         (const_string "incdec")
5855         (const_string "alu")))
5856    (set_attr "mode" "SI")])
5857
5858 ; For comparisons against 1, -1 and 128, we may generate better code
5859 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5860 ; is matched then.  We can't accept general immediate, because for
5861 ; case of overflows,  the result is messed up.
5862 ; This pattern also don't hold of 0x80000000, since the value overflows
5863 ; when negated.
5864 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5865 ; only for comparisons not depending on it.
5866 (define_insn "*addsi_4"
5867   [(set (reg 17)
5868         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5869                  (match_operand:SI 2 "const_int_operand" "n")))
5870    (clobber (match_scratch:SI 0 "=rm"))]
5871   "ix86_match_ccmode (insn, CCGCmode)
5872    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5873 {
5874   switch (get_attr_type (insn))
5875     {
5876     case TYPE_INCDEC:
5877       if (operands[2] == constm1_rtx)
5878         return "inc{l}\t%0";
5879       else if (operands[2] == const1_rtx)
5880         return "dec{l}\t%0";
5881       else
5882         abort();
5883
5884     default:
5885       if (! rtx_equal_p (operands[0], operands[1]))
5886         abort ();
5887       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5888          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5889       if ((INTVAL (operands[2]) == -128
5890            || (INTVAL (operands[2]) > 0
5891                && INTVAL (operands[2]) != 128)))
5892         return "sub{l}\t{%2, %0|%0, %2}";
5893       operands[2] = GEN_INT (-INTVAL (operands[2]));
5894       return "add{l}\t{%2, %0|%0, %2}";
5895     }
5896 }
5897   [(set (attr "type")
5898      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5899         (const_string "incdec")
5900         (const_string "alu")))
5901    (set_attr "mode" "SI")])
5902
5903 (define_insn "*addsi_5"
5904   [(set (reg 17)
5905         (compare
5906           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5907                    (match_operand:SI 2 "general_operand" "rmni"))
5908           (const_int 0)))                       
5909    (clobber (match_scratch:SI 0 "=r"))]
5910   "ix86_match_ccmode (insn, CCGOCmode)
5911    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5912    /* Current assemblers are broken and do not allow @GOTOFF in
5913       ought but a memory context.  */
5914    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5915 {
5916   switch (get_attr_type (insn))
5917     {
5918     case TYPE_INCDEC:
5919       if (! rtx_equal_p (operands[0], operands[1]))
5920         abort ();
5921       if (operands[2] == const1_rtx)
5922         return "inc{l}\t%0";
5923       else if (operands[2] == constm1_rtx)
5924         return "dec{l}\t%0";
5925       else
5926         abort();
5927
5928     default:
5929       if (! rtx_equal_p (operands[0], operands[1]))
5930         abort ();
5931       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5932          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5933       if (GET_CODE (operands[2]) == CONST_INT
5934           && (INTVAL (operands[2]) == 128
5935               || (INTVAL (operands[2]) < 0
5936                   && INTVAL (operands[2]) != -128)))
5937         {
5938           operands[2] = GEN_INT (-INTVAL (operands[2]));
5939           return "sub{l}\t{%2, %0|%0, %2}";
5940         }
5941       return "add{l}\t{%2, %0|%0, %2}";
5942     }
5943 }
5944   [(set (attr "type")
5945      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5946         (const_string "incdec")
5947         (const_string "alu")))
5948    (set_attr "mode" "SI")])
5949
5950 (define_expand "addhi3"
5951   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5952                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5953                             (match_operand:HI 2 "general_operand" "")))
5954               (clobber (reg:CC FLAGS_REG))])]
5955   "TARGET_HIMODE_MATH"
5956   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5957
5958 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5959 ;; type optimizations enabled by define-splits.  This is not important
5960 ;; for PII, and in fact harmful because of partial register stalls.
5961
5962 (define_insn "*addhi_1_lea"
5963   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5964         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5965                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5966    (clobber (reg:CC FLAGS_REG))]
5967   "!TARGET_PARTIAL_REG_STALL
5968    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5969 {
5970   switch (get_attr_type (insn))
5971     {
5972     case TYPE_LEA:
5973       return "#";
5974     case TYPE_INCDEC:
5975       if (operands[2] == const1_rtx)
5976         return "inc{w}\t%0";
5977       else if (operands[2] == constm1_rtx)
5978         return "dec{w}\t%0";
5979       abort();
5980
5981     default:
5982       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5983          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5984       if (GET_CODE (operands[2]) == CONST_INT
5985           && (INTVAL (operands[2]) == 128
5986               || (INTVAL (operands[2]) < 0
5987                   && INTVAL (operands[2]) != -128)))
5988         {
5989           operands[2] = GEN_INT (-INTVAL (operands[2]));
5990           return "sub{w}\t{%2, %0|%0, %2}";
5991         }
5992       return "add{w}\t{%2, %0|%0, %2}";
5993     }
5994 }
5995   [(set (attr "type")
5996      (if_then_else (eq_attr "alternative" "2")
5997         (const_string "lea")
5998         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5999            (const_string "incdec")
6000            (const_string "alu"))))
6001    (set_attr "mode" "HI,HI,SI")])
6002
6003 (define_insn "*addhi_1"
6004   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6005         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6006                  (match_operand:HI 2 "general_operand" "ri,rm")))
6007    (clobber (reg:CC FLAGS_REG))]
6008   "TARGET_PARTIAL_REG_STALL
6009    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6010 {
6011   switch (get_attr_type (insn))
6012     {
6013     case TYPE_INCDEC:
6014       if (operands[2] == const1_rtx)
6015         return "inc{w}\t%0";
6016       else if (operands[2] == constm1_rtx)
6017         return "dec{w}\t%0";
6018       abort();
6019
6020     default:
6021       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6022          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6023       if (GET_CODE (operands[2]) == CONST_INT
6024           && (INTVAL (operands[2]) == 128
6025               || (INTVAL (operands[2]) < 0
6026                   && INTVAL (operands[2]) != -128)))
6027         {
6028           operands[2] = GEN_INT (-INTVAL (operands[2]));
6029           return "sub{w}\t{%2, %0|%0, %2}";
6030         }
6031       return "add{w}\t{%2, %0|%0, %2}";
6032     }
6033 }
6034   [(set (attr "type")
6035      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6036         (const_string "incdec")
6037         (const_string "alu")))
6038    (set_attr "mode" "HI")])
6039
6040 (define_insn "*addhi_2"
6041   [(set (reg 17)
6042         (compare
6043           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6044                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6045           (const_int 0)))                       
6046    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6047         (plus:HI (match_dup 1) (match_dup 2)))]
6048   "ix86_match_ccmode (insn, CCGOCmode)
6049    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6050 {
6051   switch (get_attr_type (insn))
6052     {
6053     case TYPE_INCDEC:
6054       if (operands[2] == const1_rtx)
6055         return "inc{w}\t%0";
6056       else if (operands[2] == constm1_rtx)
6057         return "dec{w}\t%0";
6058       abort();
6059
6060     default:
6061       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6062          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6063       if (GET_CODE (operands[2]) == CONST_INT
6064           && (INTVAL (operands[2]) == 128
6065               || (INTVAL (operands[2]) < 0
6066                   && INTVAL (operands[2]) != -128)))
6067         {
6068           operands[2] = GEN_INT (-INTVAL (operands[2]));
6069           return "sub{w}\t{%2, %0|%0, %2}";
6070         }
6071       return "add{w}\t{%2, %0|%0, %2}";
6072     }
6073 }
6074   [(set (attr "type")
6075      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6076         (const_string "incdec")
6077         (const_string "alu")))
6078    (set_attr "mode" "HI")])
6079
6080 (define_insn "*addhi_3"
6081   [(set (reg 17)
6082         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6083                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6084    (clobber (match_scratch:HI 0 "=r"))]
6085   "ix86_match_ccmode (insn, CCZmode)
6086    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6087 {
6088   switch (get_attr_type (insn))
6089     {
6090     case TYPE_INCDEC:
6091       if (operands[2] == const1_rtx)
6092         return "inc{w}\t%0";
6093       else if (operands[2] == constm1_rtx)
6094         return "dec{w}\t%0";
6095       abort();
6096
6097     default:
6098       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6099          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6100       if (GET_CODE (operands[2]) == CONST_INT
6101           && (INTVAL (operands[2]) == 128
6102               || (INTVAL (operands[2]) < 0
6103                   && INTVAL (operands[2]) != -128)))
6104         {
6105           operands[2] = GEN_INT (-INTVAL (operands[2]));
6106           return "sub{w}\t{%2, %0|%0, %2}";
6107         }
6108       return "add{w}\t{%2, %0|%0, %2}";
6109     }
6110 }
6111   [(set (attr "type")
6112      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6113         (const_string "incdec")
6114         (const_string "alu")))
6115    (set_attr "mode" "HI")])
6116
6117 ; See comments above addsi_3_imm for details.
6118 (define_insn "*addhi_4"
6119   [(set (reg 17)
6120         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6121                  (match_operand:HI 2 "const_int_operand" "n")))
6122    (clobber (match_scratch:HI 0 "=rm"))]
6123   "ix86_match_ccmode (insn, CCGCmode)
6124    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6125 {
6126   switch (get_attr_type (insn))
6127     {
6128     case TYPE_INCDEC:
6129       if (operands[2] == constm1_rtx)
6130         return "inc{w}\t%0";
6131       else if (operands[2] == const1_rtx)
6132         return "dec{w}\t%0";
6133       else
6134         abort();
6135
6136     default:
6137       if (! rtx_equal_p (operands[0], operands[1]))
6138         abort ();
6139       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6140          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6141       if ((INTVAL (operands[2]) == -128
6142            || (INTVAL (operands[2]) > 0
6143                && INTVAL (operands[2]) != 128)))
6144         return "sub{w}\t{%2, %0|%0, %2}";
6145       operands[2] = GEN_INT (-INTVAL (operands[2]));
6146       return "add{w}\t{%2, %0|%0, %2}";
6147     }
6148 }
6149   [(set (attr "type")
6150      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6151         (const_string "incdec")
6152         (const_string "alu")))
6153    (set_attr "mode" "SI")])
6154
6155
6156 (define_insn "*addhi_5"
6157   [(set (reg 17)
6158         (compare
6159           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6160                    (match_operand:HI 2 "general_operand" "rmni"))
6161           (const_int 0)))                       
6162    (clobber (match_scratch:HI 0 "=r"))]
6163   "ix86_match_ccmode (insn, CCGOCmode)
6164    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6165 {
6166   switch (get_attr_type (insn))
6167     {
6168     case TYPE_INCDEC:
6169       if (operands[2] == const1_rtx)
6170         return "inc{w}\t%0";
6171       else if (operands[2] == constm1_rtx)
6172         return "dec{w}\t%0";
6173       abort();
6174
6175     default:
6176       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6177          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6178       if (GET_CODE (operands[2]) == CONST_INT
6179           && (INTVAL (operands[2]) == 128
6180               || (INTVAL (operands[2]) < 0
6181                   && INTVAL (operands[2]) != -128)))
6182         {
6183           operands[2] = GEN_INT (-INTVAL (operands[2]));
6184           return "sub{w}\t{%2, %0|%0, %2}";
6185         }
6186       return "add{w}\t{%2, %0|%0, %2}";
6187     }
6188 }
6189   [(set (attr "type")
6190      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6191         (const_string "incdec")
6192         (const_string "alu")))
6193    (set_attr "mode" "HI")])
6194
6195 (define_expand "addqi3"
6196   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6197                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6198                             (match_operand:QI 2 "general_operand" "")))
6199               (clobber (reg:CC FLAGS_REG))])]
6200   "TARGET_QIMODE_MATH"
6201   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6202
6203 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6204 (define_insn "*addqi_1_lea"
6205   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6206         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6207                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6208    (clobber (reg:CC FLAGS_REG))]
6209   "!TARGET_PARTIAL_REG_STALL
6210    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6211 {
6212   int widen = (which_alternative == 2);
6213   switch (get_attr_type (insn))
6214     {
6215     case TYPE_LEA:
6216       return "#";
6217     case TYPE_INCDEC:
6218       if (operands[2] == const1_rtx)
6219         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6220       else if (operands[2] == constm1_rtx)
6221         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6222       abort();
6223
6224     default:
6225       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6226          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6227       if (GET_CODE (operands[2]) == CONST_INT
6228           && (INTVAL (operands[2]) == 128
6229               || (INTVAL (operands[2]) < 0
6230                   && INTVAL (operands[2]) != -128)))
6231         {
6232           operands[2] = GEN_INT (-INTVAL (operands[2]));
6233           if (widen)
6234             return "sub{l}\t{%2, %k0|%k0, %2}";
6235           else
6236             return "sub{b}\t{%2, %0|%0, %2}";
6237         }
6238       if (widen)
6239         return "add{l}\t{%k2, %k0|%k0, %k2}";
6240       else
6241         return "add{b}\t{%2, %0|%0, %2}";
6242     }
6243 }
6244   [(set (attr "type")
6245      (if_then_else (eq_attr "alternative" "3")
6246         (const_string "lea")
6247         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6248            (const_string "incdec")
6249            (const_string "alu"))))
6250    (set_attr "mode" "QI,QI,SI,SI")])
6251
6252 (define_insn "*addqi_1"
6253   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6254         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6255                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6256    (clobber (reg:CC FLAGS_REG))]
6257   "TARGET_PARTIAL_REG_STALL
6258    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6259 {
6260   int widen = (which_alternative == 2);
6261   switch (get_attr_type (insn))
6262     {
6263     case TYPE_INCDEC:
6264       if (operands[2] == const1_rtx)
6265         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6266       else if (operands[2] == constm1_rtx)
6267         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6268       abort();
6269
6270     default:
6271       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6272          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6273       if (GET_CODE (operands[2]) == CONST_INT
6274           && (INTVAL (operands[2]) == 128
6275               || (INTVAL (operands[2]) < 0
6276                   && INTVAL (operands[2]) != -128)))
6277         {
6278           operands[2] = GEN_INT (-INTVAL (operands[2]));
6279           if (widen)
6280             return "sub{l}\t{%2, %k0|%k0, %2}";
6281           else
6282             return "sub{b}\t{%2, %0|%0, %2}";
6283         }
6284       if (widen)
6285         return "add{l}\t{%k2, %k0|%k0, %k2}";
6286       else
6287         return "add{b}\t{%2, %0|%0, %2}";
6288     }
6289 }
6290   [(set (attr "type")
6291      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292         (const_string "incdec")
6293         (const_string "alu")))
6294    (set_attr "mode" "QI,QI,SI")])
6295
6296 (define_insn "*addqi_1_slp"
6297   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6298         (plus:QI (match_dup 0)
6299                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6300    (clobber (reg:CC FLAGS_REG))]
6301   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6302    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6303 {
6304   switch (get_attr_type (insn))
6305     {
6306     case TYPE_INCDEC:
6307       if (operands[1] == const1_rtx)
6308         return "inc{b}\t%0";
6309       else if (operands[1] == constm1_rtx)
6310         return "dec{b}\t%0";
6311       abort();
6312
6313     default:
6314       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6315       if (GET_CODE (operands[1]) == CONST_INT
6316           && INTVAL (operands[1]) < 0)
6317         {
6318           operands[1] = GEN_INT (-INTVAL (operands[1]));
6319           return "sub{b}\t{%1, %0|%0, %1}";
6320         }
6321       return "add{b}\t{%1, %0|%0, %1}";
6322     }
6323 }
6324   [(set (attr "type")
6325      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6326         (const_string "incdec")
6327         (const_string "alu1")))
6328    (set_attr "mode" "QI")])
6329
6330 (define_insn "*addqi_2"
6331   [(set (reg 17)
6332         (compare
6333           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6334                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6335           (const_int 0)))
6336    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6337         (plus:QI (match_dup 1) (match_dup 2)))]
6338   "ix86_match_ccmode (insn, CCGOCmode)
6339    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6340 {
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       if (operands[2] == const1_rtx)
6345         return "inc{b}\t%0";
6346       else if (operands[2] == constm1_rtx
6347                || (GET_CODE (operands[2]) == CONST_INT
6348                    && INTVAL (operands[2]) == 255))
6349         return "dec{b}\t%0";
6350       abort();
6351
6352     default:
6353       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6354       if (GET_CODE (operands[2]) == CONST_INT
6355           && INTVAL (operands[2]) < 0)
6356         {
6357           operands[2] = GEN_INT (-INTVAL (operands[2]));
6358           return "sub{b}\t{%2, %0|%0, %2}";
6359         }
6360       return "add{b}\t{%2, %0|%0, %2}";
6361     }
6362 }
6363   [(set (attr "type")
6364      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6365         (const_string "incdec")
6366         (const_string "alu")))
6367    (set_attr "mode" "QI")])
6368
6369 (define_insn "*addqi_3"
6370   [(set (reg 17)
6371         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6372                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6373    (clobber (match_scratch:QI 0 "=q"))]
6374   "ix86_match_ccmode (insn, CCZmode)
6375    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6376 {
6377   switch (get_attr_type (insn))
6378     {
6379     case TYPE_INCDEC:
6380       if (operands[2] == const1_rtx)
6381         return "inc{b}\t%0";
6382       else if (operands[2] == constm1_rtx
6383                || (GET_CODE (operands[2]) == CONST_INT
6384                    && INTVAL (operands[2]) == 255))
6385         return "dec{b}\t%0";
6386       abort();
6387
6388     default:
6389       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6390       if (GET_CODE (operands[2]) == CONST_INT
6391           && INTVAL (operands[2]) < 0)
6392         {
6393           operands[2] = GEN_INT (-INTVAL (operands[2]));
6394           return "sub{b}\t{%2, %0|%0, %2}";
6395         }
6396       return "add{b}\t{%2, %0|%0, %2}";
6397     }
6398 }
6399   [(set (attr "type")
6400      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6401         (const_string "incdec")
6402         (const_string "alu")))
6403    (set_attr "mode" "QI")])
6404
6405 ; See comments above addsi_3_imm for details.
6406 (define_insn "*addqi_4"
6407   [(set (reg 17)
6408         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6409                  (match_operand:QI 2 "const_int_operand" "n")))
6410    (clobber (match_scratch:QI 0 "=qm"))]
6411   "ix86_match_ccmode (insn, CCGCmode)
6412    && (INTVAL (operands[2]) & 0xff) != 0x80"
6413 {
6414   switch (get_attr_type (insn))
6415     {
6416     case TYPE_INCDEC:
6417       if (operands[2] == constm1_rtx
6418           || (GET_CODE (operands[2]) == CONST_INT
6419               && INTVAL (operands[2]) == 255))
6420         return "inc{b}\t%0";
6421       else if (operands[2] == const1_rtx)
6422         return "dec{b}\t%0";
6423       else
6424         abort();
6425
6426     default:
6427       if (! rtx_equal_p (operands[0], operands[1]))
6428         abort ();
6429       if (INTVAL (operands[2]) < 0)
6430         {
6431           operands[2] = GEN_INT (-INTVAL (operands[2]));
6432           return "add{b}\t{%2, %0|%0, %2}";
6433         }
6434       return "sub{b}\t{%2, %0|%0, %2}";
6435     }
6436 }
6437   [(set (attr "type")
6438      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6439         (const_string "incdec")
6440         (const_string "alu")))
6441    (set_attr "mode" "QI")])
6442
6443
6444 (define_insn "*addqi_5"
6445   [(set (reg 17)
6446         (compare
6447           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6448                    (match_operand:QI 2 "general_operand" "qmni"))
6449           (const_int 0)))
6450    (clobber (match_scratch:QI 0 "=q"))]
6451   "ix86_match_ccmode (insn, CCGOCmode)
6452    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6453 {
6454   switch (get_attr_type (insn))
6455     {
6456     case TYPE_INCDEC:
6457       if (operands[2] == const1_rtx)
6458         return "inc{b}\t%0";
6459       else if (operands[2] == constm1_rtx
6460                || (GET_CODE (operands[2]) == CONST_INT
6461                    && INTVAL (operands[2]) == 255))
6462         return "dec{b}\t%0";
6463       abort();
6464
6465     default:
6466       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6467       if (GET_CODE (operands[2]) == CONST_INT
6468           && INTVAL (operands[2]) < 0)
6469         {
6470           operands[2] = GEN_INT (-INTVAL (operands[2]));
6471           return "sub{b}\t{%2, %0|%0, %2}";
6472         }
6473       return "add{b}\t{%2, %0|%0, %2}";
6474     }
6475 }
6476   [(set (attr "type")
6477      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6478         (const_string "incdec")
6479         (const_string "alu")))
6480    (set_attr "mode" "QI")])
6481
6482
6483 (define_insn "addqi_ext_1"
6484   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6485                          (const_int 8)
6486                          (const_int 8))
6487         (plus:SI
6488           (zero_extract:SI
6489             (match_operand 1 "ext_register_operand" "0")
6490             (const_int 8)
6491             (const_int 8))
6492           (match_operand:QI 2 "general_operand" "Qmn")))
6493    (clobber (reg:CC FLAGS_REG))]
6494   "!TARGET_64BIT"
6495 {
6496   switch (get_attr_type (insn))
6497     {
6498     case TYPE_INCDEC:
6499       if (operands[2] == const1_rtx)
6500         return "inc{b}\t%h0";
6501       else if (operands[2] == constm1_rtx
6502                || (GET_CODE (operands[2]) == CONST_INT
6503                    && INTVAL (operands[2]) == 255))
6504         return "dec{b}\t%h0";
6505       abort();
6506
6507     default:
6508       return "add{b}\t{%2, %h0|%h0, %2}";
6509     }
6510 }
6511   [(set (attr "type")
6512      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6513         (const_string "incdec")
6514         (const_string "alu")))
6515    (set_attr "mode" "QI")])
6516
6517 (define_insn "*addqi_ext_1_rex64"
6518   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6519                          (const_int 8)
6520                          (const_int 8))
6521         (plus:SI
6522           (zero_extract:SI
6523             (match_operand 1 "ext_register_operand" "0")
6524             (const_int 8)
6525             (const_int 8))
6526           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6527    (clobber (reg:CC FLAGS_REG))]
6528   "TARGET_64BIT"
6529 {
6530   switch (get_attr_type (insn))
6531     {
6532     case TYPE_INCDEC:
6533       if (operands[2] == const1_rtx)
6534         return "inc{b}\t%h0";
6535       else if (operands[2] == constm1_rtx
6536                || (GET_CODE (operands[2]) == CONST_INT
6537                    && INTVAL (operands[2]) == 255))
6538         return "dec{b}\t%h0";
6539       abort();
6540
6541     default:
6542       return "add{b}\t{%2, %h0|%h0, %2}";
6543     }
6544 }
6545   [(set (attr "type")
6546      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6547         (const_string "incdec")
6548         (const_string "alu")))
6549    (set_attr "mode" "QI")])
6550
6551 (define_insn "*addqi_ext_2"
6552   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6553                          (const_int 8)
6554                          (const_int 8))
6555         (plus:SI
6556           (zero_extract:SI
6557             (match_operand 1 "ext_register_operand" "%0")
6558             (const_int 8)
6559             (const_int 8))
6560           (zero_extract:SI
6561             (match_operand 2 "ext_register_operand" "Q")
6562             (const_int 8)
6563             (const_int 8))))
6564    (clobber (reg:CC FLAGS_REG))]
6565   ""
6566   "add{b}\t{%h2, %h0|%h0, %h2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "mode" "QI")])
6569
6570 ;; The patterns that match these are at the end of this file.
6571
6572 (define_expand "addxf3"
6573   [(set (match_operand:XF 0 "register_operand" "")
6574         (plus:XF (match_operand:XF 1 "register_operand" "")
6575                  (match_operand:XF 2 "register_operand" "")))]
6576   "TARGET_80387"
6577   "")
6578
6579 (define_expand "adddf3"
6580   [(set (match_operand:DF 0 "register_operand" "")
6581         (plus:DF (match_operand:DF 1 "register_operand" "")
6582                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6583   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6584   "")
6585
6586 (define_expand "addsf3"
6587   [(set (match_operand:SF 0 "register_operand" "")
6588         (plus:SF (match_operand:SF 1 "register_operand" "")
6589                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6590   "TARGET_80387 || TARGET_SSE_MATH"
6591   "")
6592 \f
6593 ;; Subtract instructions
6594
6595 ;; %%% splits for subsidi3
6596
6597 (define_expand "subdi3"
6598   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6599                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6600                              (match_operand:DI 2 "x86_64_general_operand" "")))
6601               (clobber (reg:CC FLAGS_REG))])]
6602   ""
6603   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6604
6605 (define_insn "*subdi3_1"
6606   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6607         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6608                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6609    (clobber (reg:CC FLAGS_REG))]
6610   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6611   "#")
6612
6613 (define_split
6614   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6615         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6616                   (match_operand:DI 2 "general_operand" "")))
6617    (clobber (reg:CC FLAGS_REG))]
6618   "!TARGET_64BIT && reload_completed"
6619   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6620               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6621    (parallel [(set (match_dup 3)
6622                    (minus:SI (match_dup 4)
6623                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6624                                       (match_dup 5))))
6625               (clobber (reg:CC FLAGS_REG))])]
6626   "split_di (operands+0, 1, operands+0, operands+3);
6627    split_di (operands+1, 1, operands+1, operands+4);
6628    split_di (operands+2, 1, operands+2, operands+5);")
6629
6630 (define_insn "subdi3_carry_rex64"
6631   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6632           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6633             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6634                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6635    (clobber (reg:CC FLAGS_REG))]
6636   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6637   "sbb{q}\t{%2, %0|%0, %2}"
6638   [(set_attr "type" "alu")
6639    (set_attr "pent_pair" "pu")
6640    (set_attr "mode" "DI")])
6641
6642 (define_insn "*subdi_1_rex64"
6643   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6644         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
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   "sub{q}\t{%2, %0|%0, %2}"
6649   [(set_attr "type" "alu")
6650    (set_attr "mode" "DI")])
6651
6652 (define_insn "*subdi_2_rex64"
6653   [(set (reg 17)
6654         (compare
6655           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6656                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6657           (const_int 0)))
6658    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6659         (minus:DI (match_dup 1) (match_dup 2)))]
6660   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6661    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6662   "sub{q}\t{%2, %0|%0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "mode" "DI")])
6665
6666 (define_insn "*subdi_3_rex63"
6667   [(set (reg 17)
6668         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6669                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6670    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6671         (minus:DI (match_dup 1) (match_dup 2)))]
6672   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6673    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6674   "sub{q}\t{%2, %0|%0, %2}"
6675   [(set_attr "type" "alu")
6676    (set_attr "mode" "DI")])
6677
6678 (define_insn "subqi3_carry"
6679   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6680           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6681             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6682                (match_operand:QI 2 "general_operand" "qi,qm"))))
6683    (clobber (reg:CC FLAGS_REG))]
6684   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6685   "sbb{b}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "pent_pair" "pu")
6688    (set_attr "mode" "QI")])
6689
6690 (define_insn "subhi3_carry"
6691   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6692           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6693             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6694                (match_operand:HI 2 "general_operand" "ri,rm"))))
6695    (clobber (reg:CC FLAGS_REG))]
6696   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6697   "sbb{w}\t{%2, %0|%0, %2}"
6698   [(set_attr "type" "alu")
6699    (set_attr "pent_pair" "pu")
6700    (set_attr "mode" "HI")])
6701
6702 (define_insn "subsi3_carry"
6703   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6705             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6706                (match_operand:SI 2 "general_operand" "ri,rm"))))
6707    (clobber (reg:CC FLAGS_REG))]
6708   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6709   "sbb{l}\t{%2, %0|%0, %2}"
6710   [(set_attr "type" "alu")
6711    (set_attr "pent_pair" "pu")
6712    (set_attr "mode" "SI")])
6713
6714 (define_insn "subsi3_carry_zext"
6715   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6716           (zero_extend:DI
6717             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6718               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6719                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6720    (clobber (reg:CC FLAGS_REG))]
6721   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6722   "sbb{l}\t{%2, %k0|%k0, %2}"
6723   [(set_attr "type" "alu")
6724    (set_attr "pent_pair" "pu")
6725    (set_attr "mode" "SI")])
6726
6727 (define_expand "subsi3"
6728   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6729                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6730                              (match_operand:SI 2 "general_operand" "")))
6731               (clobber (reg:CC FLAGS_REG))])]
6732   ""
6733   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6734
6735 (define_insn "*subsi_1"
6736   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6737         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6738                   (match_operand:SI 2 "general_operand" "ri,rm")))
6739    (clobber (reg:CC FLAGS_REG))]
6740   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6741   "sub{l}\t{%2, %0|%0, %2}"
6742   [(set_attr "type" "alu")
6743    (set_attr "mode" "SI")])
6744
6745 (define_insn "*subsi_1_zext"
6746   [(set (match_operand:DI 0 "register_operand" "=r")
6747         (zero_extend:DI
6748           (minus:SI (match_operand:SI 1 "register_operand" "0")
6749                     (match_operand:SI 2 "general_operand" "rim"))))
6750    (clobber (reg:CC FLAGS_REG))]
6751   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6752   "sub{l}\t{%2, %k0|%k0, %2}"
6753   [(set_attr "type" "alu")
6754    (set_attr "mode" "SI")])
6755
6756 (define_insn "*subsi_2"
6757   [(set (reg 17)
6758         (compare
6759           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6760                     (match_operand:SI 2 "general_operand" "ri,rm"))
6761           (const_int 0)))
6762    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6763         (minus:SI (match_dup 1) (match_dup 2)))]
6764   "ix86_match_ccmode (insn, CCGOCmode)
6765    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6766   "sub{l}\t{%2, %0|%0, %2}"
6767   [(set_attr "type" "alu")
6768    (set_attr "mode" "SI")])
6769
6770 (define_insn "*subsi_2_zext"
6771   [(set (reg 17)
6772         (compare
6773           (minus:SI (match_operand:SI 1 "register_operand" "0")
6774                     (match_operand:SI 2 "general_operand" "rim"))
6775           (const_int 0)))
6776    (set (match_operand:DI 0 "register_operand" "=r")
6777         (zero_extend:DI
6778           (minus:SI (match_dup 1)
6779                     (match_dup 2))))]
6780   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6781    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6782   "sub{l}\t{%2, %k0|%k0, %2}"
6783   [(set_attr "type" "alu")
6784    (set_attr "mode" "SI")])
6785
6786 (define_insn "*subsi_3"
6787   [(set (reg 17)
6788         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6789                  (match_operand:SI 2 "general_operand" "ri,rm")))
6790    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6791         (minus:SI (match_dup 1) (match_dup 2)))]
6792   "ix86_match_ccmode (insn, CCmode)
6793    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6794   "sub{l}\t{%2, %0|%0, %2}"
6795   [(set_attr "type" "alu")
6796    (set_attr "mode" "SI")])
6797
6798 (define_insn "*subsi_3_zext"
6799   [(set (reg 17)
6800         (compare (match_operand:SI 1 "register_operand" "0")
6801                  (match_operand:SI 2 "general_operand" "rim")))
6802    (set (match_operand:DI 0 "register_operand" "=r")
6803         (zero_extend:DI
6804           (minus:SI (match_dup 1)
6805                     (match_dup 2))))]
6806   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6807    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6808   "sub{q}\t{%2, %0|%0, %2}"
6809   [(set_attr "type" "alu")
6810    (set_attr "mode" "DI")])
6811
6812 (define_expand "subhi3"
6813   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6814                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6815                              (match_operand:HI 2 "general_operand" "")))
6816               (clobber (reg:CC FLAGS_REG))])]
6817   "TARGET_HIMODE_MATH"
6818   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6819
6820 (define_insn "*subhi_1"
6821   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6822         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6823                   (match_operand:HI 2 "general_operand" "ri,rm")))
6824    (clobber (reg:CC FLAGS_REG))]
6825   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6826   "sub{w}\t{%2, %0|%0, %2}"
6827   [(set_attr "type" "alu")
6828    (set_attr "mode" "HI")])
6829
6830 (define_insn "*subhi_2"
6831   [(set (reg 17)
6832         (compare
6833           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6834                     (match_operand:HI 2 "general_operand" "ri,rm"))
6835           (const_int 0)))
6836    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6837         (minus:HI (match_dup 1) (match_dup 2)))]
6838   "ix86_match_ccmode (insn, CCGOCmode)
6839    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6840   "sub{w}\t{%2, %0|%0, %2}"
6841   [(set_attr "type" "alu")
6842    (set_attr "mode" "HI")])
6843
6844 (define_insn "*subhi_3"
6845   [(set (reg 17)
6846         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6847                  (match_operand:HI 2 "general_operand" "ri,rm")))
6848    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6849         (minus:HI (match_dup 1) (match_dup 2)))]
6850   "ix86_match_ccmode (insn, CCmode)
6851    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6852   "sub{w}\t{%2, %0|%0, %2}"
6853   [(set_attr "type" "alu")
6854    (set_attr "mode" "HI")])
6855
6856 (define_expand "subqi3"
6857   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6858                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6859                              (match_operand:QI 2 "general_operand" "")))
6860               (clobber (reg:CC FLAGS_REG))])]
6861   "TARGET_QIMODE_MATH"
6862   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6863
6864 (define_insn "*subqi_1"
6865   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6866         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6867                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6868    (clobber (reg:CC FLAGS_REG))]
6869   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6870   "sub{b}\t{%2, %0|%0, %2}"
6871   [(set_attr "type" "alu")
6872    (set_attr "mode" "QI")])
6873
6874 (define_insn "*subqi_1_slp"
6875   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6876         (minus:QI (match_dup 0)
6877                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6878    (clobber (reg:CC FLAGS_REG))]
6879   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6880    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6881   "sub{b}\t{%1, %0|%0, %1}"
6882   [(set_attr "type" "alu1")
6883    (set_attr "mode" "QI")])
6884
6885 (define_insn "*subqi_2"
6886   [(set (reg 17)
6887         (compare
6888           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6889                     (match_operand:QI 2 "general_operand" "qi,qm"))
6890           (const_int 0)))
6891    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6892         (minus:HI (match_dup 1) (match_dup 2)))]
6893   "ix86_match_ccmode (insn, CCGOCmode)
6894    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6895   "sub{b}\t{%2, %0|%0, %2}"
6896   [(set_attr "type" "alu")
6897    (set_attr "mode" "QI")])
6898
6899 (define_insn "*subqi_3"
6900   [(set (reg 17)
6901         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6902                  (match_operand:QI 2 "general_operand" "qi,qm")))
6903    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6904         (minus:HI (match_dup 1) (match_dup 2)))]
6905   "ix86_match_ccmode (insn, CCmode)
6906    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6907   "sub{b}\t{%2, %0|%0, %2}"
6908   [(set_attr "type" "alu")
6909    (set_attr "mode" "QI")])
6910
6911 ;; The patterns that match these are at the end of this file.
6912
6913 (define_expand "subxf3"
6914   [(set (match_operand:XF 0 "register_operand" "")
6915         (minus:XF (match_operand:XF 1 "register_operand" "")
6916                   (match_operand:XF 2 "register_operand" "")))]
6917   "TARGET_80387"
6918   "")
6919
6920 (define_expand "subdf3"
6921   [(set (match_operand:DF 0 "register_operand" "")
6922         (minus:DF (match_operand:DF 1 "register_operand" "")
6923                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6924   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6925   "")
6926
6927 (define_expand "subsf3"
6928   [(set (match_operand:SF 0 "register_operand" "")
6929         (minus:SF (match_operand:SF 1 "register_operand" "")
6930                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6931   "TARGET_80387 || TARGET_SSE_MATH"
6932   "")
6933 \f
6934 ;; Multiply instructions
6935
6936 (define_expand "muldi3"
6937   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6938                    (mult:DI (match_operand:DI 1 "register_operand" "")
6939                             (match_operand:DI 2 "x86_64_general_operand" "")))
6940               (clobber (reg:CC FLAGS_REG))])]
6941   "TARGET_64BIT"
6942   "")
6943
6944 (define_insn "*muldi3_1_rex64"
6945   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6946         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6947                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6948    (clobber (reg:CC FLAGS_REG))]
6949   "TARGET_64BIT
6950    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6951   "@
6952    imul{q}\t{%2, %1, %0|%0, %1, %2}
6953    imul{q}\t{%2, %1, %0|%0, %1, %2}
6954    imul{q}\t{%2, %0|%0, %2}"
6955   [(set_attr "type" "imul")
6956    (set_attr "prefix_0f" "0,0,1")
6957    (set (attr "athlon_decode")
6958         (cond [(eq_attr "cpu" "athlon")
6959                   (const_string "vector")
6960                (eq_attr "alternative" "1")
6961                   (const_string "vector")
6962                (and (eq_attr "alternative" "2")
6963                     (match_operand 1 "memory_operand" ""))
6964                   (const_string "vector")]
6965               (const_string "direct")))
6966    (set_attr "mode" "DI")])
6967
6968 (define_expand "mulsi3"
6969   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6970                    (mult:SI (match_operand:SI 1 "register_operand" "")
6971                             (match_operand:SI 2 "general_operand" "")))
6972               (clobber (reg:CC FLAGS_REG))])]
6973   ""
6974   "")
6975
6976 (define_insn "*mulsi3_1"
6977   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6978         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6979                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6980    (clobber (reg:CC FLAGS_REG))]
6981   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6982   "@
6983    imul{l}\t{%2, %1, %0|%0, %1, %2}
6984    imul{l}\t{%2, %1, %0|%0, %1, %2}
6985    imul{l}\t{%2, %0|%0, %2}"
6986   [(set_attr "type" "imul")
6987    (set_attr "prefix_0f" "0,0,1")
6988    (set (attr "athlon_decode")
6989         (cond [(eq_attr "cpu" "athlon")
6990                   (const_string "vector")
6991                (eq_attr "alternative" "1")
6992                   (const_string "vector")
6993                (and (eq_attr "alternative" "2")
6994                     (match_operand 1 "memory_operand" ""))
6995                   (const_string "vector")]
6996               (const_string "direct")))
6997    (set_attr "mode" "SI")])
6998
6999 (define_insn "*mulsi3_1_zext"
7000   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7001         (zero_extend:DI
7002           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7003                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7004    (clobber (reg:CC FLAGS_REG))]
7005   "TARGET_64BIT
7006    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7007   "@
7008    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7009    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7010    imul{l}\t{%2, %k0|%k0, %2}"
7011   [(set_attr "type" "imul")
7012    (set_attr "prefix_0f" "0,0,1")
7013    (set (attr "athlon_decode")
7014         (cond [(eq_attr "cpu" "athlon")
7015                   (const_string "vector")
7016                (eq_attr "alternative" "1")
7017                   (const_string "vector")
7018                (and (eq_attr "alternative" "2")
7019                     (match_operand 1 "memory_operand" ""))
7020                   (const_string "vector")]
7021               (const_string "direct")))
7022    (set_attr "mode" "SI")])
7023
7024 (define_expand "mulhi3"
7025   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7026                    (mult:HI (match_operand:HI 1 "register_operand" "")
7027                             (match_operand:HI 2 "general_operand" "")))
7028               (clobber (reg:CC FLAGS_REG))])]
7029   "TARGET_HIMODE_MATH"
7030   "")
7031
7032 (define_insn "*mulhi3_1"
7033   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7034         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7035                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7036    (clobber (reg:CC FLAGS_REG))]
7037   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7038   "@
7039    imul{w}\t{%2, %1, %0|%0, %1, %2}
7040    imul{w}\t{%2, %1, %0|%0, %1, %2}
7041    imul{w}\t{%2, %0|%0, %2}"
7042   [(set_attr "type" "imul")
7043    (set_attr "prefix_0f" "0,0,1")
7044    (set (attr "athlon_decode")
7045         (cond [(eq_attr "cpu" "athlon")
7046                   (const_string "vector")
7047                (eq_attr "alternative" "1,2")
7048                   (const_string "vector")]
7049               (const_string "direct")))
7050    (set_attr "mode" "HI")])
7051
7052 (define_expand "mulqi3"
7053   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7054                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7055                             (match_operand:QI 2 "register_operand" "")))
7056               (clobber (reg:CC FLAGS_REG))])]
7057   "TARGET_QIMODE_MATH"
7058   "")
7059
7060 (define_insn "*mulqi3_1"
7061   [(set (match_operand:QI 0 "register_operand" "=a")
7062         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7063                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7064    (clobber (reg:CC FLAGS_REG))]
7065   "TARGET_QIMODE_MATH
7066    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7067   "mul{b}\t%2"
7068   [(set_attr "type" "imul")
7069    (set_attr "length_immediate" "0")
7070    (set (attr "athlon_decode")
7071      (if_then_else (eq_attr "cpu" "athlon")
7072         (const_string "vector")
7073         (const_string "direct")))
7074    (set_attr "mode" "QI")])
7075
7076 (define_expand "umulqihi3"
7077   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7078                    (mult:HI (zero_extend:HI
7079                               (match_operand:QI 1 "nonimmediate_operand" ""))
7080                             (zero_extend:HI
7081                               (match_operand:QI 2 "register_operand" ""))))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   "TARGET_QIMODE_MATH"
7084   "")
7085
7086 (define_insn "*umulqihi3_1"
7087   [(set (match_operand:HI 0 "register_operand" "=a")
7088         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "TARGET_QIMODE_MATH
7092    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093   "mul{b}\t%2"
7094   [(set_attr "type" "imul")
7095    (set_attr "length_immediate" "0")
7096    (set (attr "athlon_decode")
7097      (if_then_else (eq_attr "cpu" "athlon")
7098         (const_string "vector")
7099         (const_string "direct")))
7100    (set_attr "mode" "QI")])
7101
7102 (define_expand "mulqihi3"
7103   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7104                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7105                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7106               (clobber (reg:CC FLAGS_REG))])]
7107   "TARGET_QIMODE_MATH"
7108   "")
7109
7110 (define_insn "*mulqihi3_insn"
7111   [(set (match_operand:HI 0 "register_operand" "=a")
7112         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7113                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7114    (clobber (reg:CC FLAGS_REG))]
7115   "TARGET_QIMODE_MATH
7116    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7117   "imul{b}\t%2"
7118   [(set_attr "type" "imul")
7119    (set_attr "length_immediate" "0")
7120    (set (attr "athlon_decode")
7121      (if_then_else (eq_attr "cpu" "athlon")
7122         (const_string "vector")
7123         (const_string "direct")))
7124    (set_attr "mode" "QI")])
7125
7126 (define_expand "umulditi3"
7127   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7128                    (mult:TI (zero_extend:TI
7129                               (match_operand:DI 1 "nonimmediate_operand" ""))
7130                             (zero_extend:TI
7131                               (match_operand:DI 2 "register_operand" ""))))
7132               (clobber (reg:CC FLAGS_REG))])]
7133   "TARGET_64BIT"
7134   "")
7135
7136 (define_insn "*umulditi3_insn"
7137   [(set (match_operand:TI 0 "register_operand" "=A")
7138         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7139                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7140    (clobber (reg:CC FLAGS_REG))]
7141   "TARGET_64BIT
7142    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7143   "mul{q}\t%2"
7144   [(set_attr "type" "imul")
7145    (set_attr "length_immediate" "0")
7146    (set (attr "athlon_decode")
7147      (if_then_else (eq_attr "cpu" "athlon")
7148         (const_string "vector")
7149         (const_string "double")))
7150    (set_attr "mode" "DI")])
7151
7152 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7153 (define_expand "umulsidi3"
7154   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7155                    (mult:DI (zero_extend:DI
7156                               (match_operand:SI 1 "nonimmediate_operand" ""))
7157                             (zero_extend:DI
7158                               (match_operand:SI 2 "register_operand" ""))))
7159               (clobber (reg:CC FLAGS_REG))])]
7160   "!TARGET_64BIT"
7161   "")
7162
7163 (define_insn "*umulsidi3_insn"
7164   [(set (match_operand:DI 0 "register_operand" "=A")
7165         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7166                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7167    (clobber (reg:CC FLAGS_REG))]
7168   "!TARGET_64BIT
7169    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7170   "mul{l}\t%2"
7171   [(set_attr "type" "imul")
7172    (set_attr "length_immediate" "0")
7173    (set (attr "athlon_decode")
7174      (if_then_else (eq_attr "cpu" "athlon")
7175         (const_string "vector")
7176         (const_string "double")))
7177    (set_attr "mode" "SI")])
7178
7179 (define_expand "mulditi3"
7180   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7181                    (mult:TI (sign_extend:TI
7182                               (match_operand:DI 1 "nonimmediate_operand" ""))
7183                             (sign_extend:TI
7184                               (match_operand:DI 2 "register_operand" ""))))
7185               (clobber (reg:CC FLAGS_REG))])]
7186   "TARGET_64BIT"
7187   "")
7188
7189 (define_insn "*mulditi3_insn"
7190   [(set (match_operand:TI 0 "register_operand" "=A")
7191         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7192                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7193    (clobber (reg:CC FLAGS_REG))]
7194   "TARGET_64BIT
7195    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7196   "imul{q}\t%2"
7197   [(set_attr "type" "imul")
7198    (set_attr "length_immediate" "0")
7199    (set (attr "athlon_decode")
7200      (if_then_else (eq_attr "cpu" "athlon")
7201         (const_string "vector")
7202         (const_string "double")))
7203    (set_attr "mode" "DI")])
7204
7205 (define_expand "mulsidi3"
7206   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7207                    (mult:DI (sign_extend:DI
7208                               (match_operand:SI 1 "nonimmediate_operand" ""))
7209                             (sign_extend:DI
7210                               (match_operand:SI 2 "register_operand" ""))))
7211               (clobber (reg:CC FLAGS_REG))])]
7212   "!TARGET_64BIT"
7213   "")
7214
7215 (define_insn "*mulsidi3_insn"
7216   [(set (match_operand:DI 0 "register_operand" "=A")
7217         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7218                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7219    (clobber (reg:CC FLAGS_REG))]
7220   "!TARGET_64BIT
7221    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7222   "imul{l}\t%2"
7223   [(set_attr "type" "imul")
7224    (set_attr "length_immediate" "0")
7225    (set (attr "athlon_decode")
7226      (if_then_else (eq_attr "cpu" "athlon")
7227         (const_string "vector")
7228         (const_string "double")))
7229    (set_attr "mode" "SI")])
7230
7231 (define_expand "umuldi3_highpart"
7232   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7233                    (truncate:DI
7234                      (lshiftrt:TI
7235                        (mult:TI (zero_extend:TI
7236                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7237                                 (zero_extend:TI
7238                                   (match_operand:DI 2 "register_operand" "")))
7239                        (const_int 64))))
7240               (clobber (match_scratch:DI 3 ""))
7241               (clobber (reg:CC FLAGS_REG))])]
7242   "TARGET_64BIT"
7243   "")
7244
7245 (define_insn "*umuldi3_highpart_rex64"
7246   [(set (match_operand:DI 0 "register_operand" "=d")
7247         (truncate:DI
7248           (lshiftrt:TI
7249             (mult:TI (zero_extend:TI
7250                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7251                      (zero_extend:TI
7252                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7253             (const_int 64))))
7254    (clobber (match_scratch:DI 3 "=1"))
7255    (clobber (reg:CC FLAGS_REG))]
7256   "TARGET_64BIT
7257    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7258   "mul{q}\t%2"
7259   [(set_attr "type" "imul")
7260    (set_attr "length_immediate" "0")
7261    (set (attr "athlon_decode")
7262      (if_then_else (eq_attr "cpu" "athlon")
7263         (const_string "vector")
7264         (const_string "double")))
7265    (set_attr "mode" "DI")])
7266
7267 (define_expand "umulsi3_highpart"
7268   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7269                    (truncate:SI
7270                      (lshiftrt:DI
7271                        (mult:DI (zero_extend:DI
7272                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7273                                 (zero_extend:DI
7274                                   (match_operand:SI 2 "register_operand" "")))
7275                        (const_int 32))))
7276               (clobber (match_scratch:SI 3 ""))
7277               (clobber (reg:CC FLAGS_REG))])]
7278   ""
7279   "")
7280
7281 (define_insn "*umulsi3_highpart_insn"
7282   [(set (match_operand:SI 0 "register_operand" "=d")
7283         (truncate:SI
7284           (lshiftrt:DI
7285             (mult:DI (zero_extend:DI
7286                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7287                      (zero_extend:DI
7288                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7289             (const_int 32))))
7290    (clobber (match_scratch:SI 3 "=1"))
7291    (clobber (reg:CC FLAGS_REG))]
7292   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7293   "mul{l}\t%2"
7294   [(set_attr "type" "imul")
7295    (set_attr "length_immediate" "0")
7296    (set (attr "athlon_decode")
7297      (if_then_else (eq_attr "cpu" "athlon")
7298         (const_string "vector")
7299         (const_string "double")))
7300    (set_attr "mode" "SI")])
7301
7302 (define_insn "*umulsi3_highpart_zext"
7303   [(set (match_operand:DI 0 "register_operand" "=d")
7304         (zero_extend:DI (truncate:SI
7305           (lshiftrt:DI
7306             (mult:DI (zero_extend:DI
7307                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7308                      (zero_extend:DI
7309                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7310             (const_int 32)))))
7311    (clobber (match_scratch:SI 3 "=1"))
7312    (clobber (reg:CC FLAGS_REG))]
7313   "TARGET_64BIT
7314    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7315   "mul{l}\t%2"
7316   [(set_attr "type" "imul")
7317    (set_attr "length_immediate" "0")
7318    (set (attr "athlon_decode")
7319      (if_then_else (eq_attr "cpu" "athlon")
7320         (const_string "vector")
7321         (const_string "double")))
7322    (set_attr "mode" "SI")])
7323
7324 (define_expand "smuldi3_highpart"
7325   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7326                    (truncate:DI
7327                      (lshiftrt:TI
7328                        (mult:TI (sign_extend:TI
7329                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7330                                 (sign_extend:TI
7331                                   (match_operand:DI 2 "register_operand" "")))
7332                        (const_int 64))))
7333               (clobber (match_scratch:DI 3 ""))
7334               (clobber (reg:CC FLAGS_REG))])]
7335   "TARGET_64BIT"
7336   "")
7337
7338 (define_insn "*smuldi3_highpart_rex64"
7339   [(set (match_operand:DI 0 "register_operand" "=d")
7340         (truncate:DI
7341           (lshiftrt:TI
7342             (mult:TI (sign_extend:TI
7343                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7344                      (sign_extend:TI
7345                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7346             (const_int 64))))
7347    (clobber (match_scratch:DI 3 "=1"))
7348    (clobber (reg:CC FLAGS_REG))]
7349   "TARGET_64BIT
7350    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7351   "imul{q}\t%2"
7352   [(set_attr "type" "imul")
7353    (set (attr "athlon_decode")
7354      (if_then_else (eq_attr "cpu" "athlon")
7355         (const_string "vector")
7356         (const_string "double")))
7357    (set_attr "mode" "DI")])
7358
7359 (define_expand "smulsi3_highpart"
7360   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7361                    (truncate:SI
7362                      (lshiftrt:DI
7363                        (mult:DI (sign_extend:DI
7364                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7365                                 (sign_extend:DI
7366                                   (match_operand:SI 2 "register_operand" "")))
7367                        (const_int 32))))
7368               (clobber (match_scratch:SI 3 ""))
7369               (clobber (reg:CC FLAGS_REG))])]
7370   ""
7371   "")
7372
7373 (define_insn "*smulsi3_highpart_insn"
7374   [(set (match_operand:SI 0 "register_operand" "=d")
7375         (truncate:SI
7376           (lshiftrt:DI
7377             (mult:DI (sign_extend:DI
7378                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7379                      (sign_extend:DI
7380                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7381             (const_int 32))))
7382    (clobber (match_scratch:SI 3 "=1"))
7383    (clobber (reg:CC FLAGS_REG))]
7384   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7385   "imul{l}\t%2"
7386   [(set_attr "type" "imul")
7387    (set (attr "athlon_decode")
7388      (if_then_else (eq_attr "cpu" "athlon")
7389         (const_string "vector")
7390         (const_string "double")))
7391    (set_attr "mode" "SI")])
7392
7393 (define_insn "*smulsi3_highpart_zext"
7394   [(set (match_operand:DI 0 "register_operand" "=d")
7395         (zero_extend:DI (truncate:SI
7396           (lshiftrt:DI
7397             (mult:DI (sign_extend:DI
7398                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7399                      (sign_extend:DI
7400                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7401             (const_int 32)))))
7402    (clobber (match_scratch:SI 3 "=1"))
7403    (clobber (reg:CC FLAGS_REG))]
7404   "TARGET_64BIT
7405    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7406   "imul{l}\t%2"
7407   [(set_attr "type" "imul")
7408    (set (attr "athlon_decode")
7409      (if_then_else (eq_attr "cpu" "athlon")
7410         (const_string "vector")
7411         (const_string "double")))
7412    (set_attr "mode" "SI")])
7413
7414 ;; The patterns that match these are at the end of this file.
7415
7416 (define_expand "mulxf3"
7417   [(set (match_operand:XF 0 "register_operand" "")
7418         (mult:XF (match_operand:XF 1 "register_operand" "")
7419                  (match_operand:XF 2 "register_operand" "")))]
7420   "TARGET_80387"
7421   "")
7422
7423 (define_expand "muldf3"
7424   [(set (match_operand:DF 0 "register_operand" "")
7425         (mult:DF (match_operand:DF 1 "register_operand" "")
7426                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7427   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7428   "")
7429
7430 (define_expand "mulsf3"
7431   [(set (match_operand:SF 0 "register_operand" "")
7432         (mult:SF (match_operand:SF 1 "register_operand" "")
7433                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7434   "TARGET_80387 || TARGET_SSE_MATH"
7435   "")
7436 \f
7437 ;; Divide instructions
7438
7439 (define_insn "divqi3"
7440   [(set (match_operand:QI 0 "register_operand" "=a")
7441         (div:QI (match_operand:HI 1 "register_operand" "0")
7442                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "TARGET_QIMODE_MATH"
7445   "idiv{b}\t%2"
7446   [(set_attr "type" "idiv")
7447    (set_attr "mode" "QI")])
7448
7449 (define_insn "udivqi3"
7450   [(set (match_operand:QI 0 "register_operand" "=a")
7451         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7452                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7453    (clobber (reg:CC FLAGS_REG))]
7454   "TARGET_QIMODE_MATH"
7455   "div{b}\t%2"
7456   [(set_attr "type" "idiv")
7457    (set_attr "mode" "QI")])
7458
7459 ;; The patterns that match these are at the end of this file.
7460
7461 (define_expand "divxf3"
7462   [(set (match_operand:XF 0 "register_operand" "")
7463         (div:XF (match_operand:XF 1 "register_operand" "")
7464                 (match_operand:XF 2 "register_operand" "")))]
7465   "TARGET_80387"
7466   "")
7467
7468 (define_expand "divdf3"
7469   [(set (match_operand:DF 0 "register_operand" "")
7470         (div:DF (match_operand:DF 1 "register_operand" "")
7471                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7472    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7473    "")
7474  
7475 (define_expand "divsf3"
7476   [(set (match_operand:SF 0 "register_operand" "")
7477         (div:SF (match_operand:SF 1 "register_operand" "")
7478                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7479   "TARGET_80387 || TARGET_SSE_MATH"
7480   "")
7481 \f
7482 ;; Remainder instructions.
7483
7484 (define_expand "divmoddi4"
7485   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7486                    (div:DI (match_operand:DI 1 "register_operand" "")
7487                            (match_operand:DI 2 "nonimmediate_operand" "")))
7488               (set (match_operand:DI 3 "register_operand" "")
7489                    (mod:DI (match_dup 1) (match_dup 2)))
7490               (clobber (reg:CC FLAGS_REG))])]
7491   "TARGET_64BIT"
7492   "")
7493
7494 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7495 ;; Penalize eax case slightly because it results in worse scheduling
7496 ;; of code.
7497 (define_insn "*divmoddi4_nocltd_rex64"
7498   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7499         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7500                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7501    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7502         (mod:DI (match_dup 2) (match_dup 3)))
7503    (clobber (reg:CC FLAGS_REG))]
7504   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7505   "#"
7506   [(set_attr "type" "multi")])
7507
7508 (define_insn "*divmoddi4_cltd_rex64"
7509   [(set (match_operand:DI 0 "register_operand" "=a")
7510         (div:DI (match_operand:DI 2 "register_operand" "a")
7511                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7512    (set (match_operand:DI 1 "register_operand" "=&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 "*divmoddi_noext_rex64"
7520   [(set (match_operand:DI 0 "register_operand" "=a")
7521         (div:DI (match_operand:DI 1 "register_operand" "0")
7522                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7523    (set (match_operand:DI 3 "register_operand" "=d")
7524         (mod:DI (match_dup 1) (match_dup 2)))
7525    (use (match_operand:DI 4 "register_operand" "3"))
7526    (clobber (reg:CC FLAGS_REG))]
7527   "TARGET_64BIT"
7528   "idiv{q}\t%2"
7529   [(set_attr "type" "idiv")
7530    (set_attr "mode" "DI")])
7531
7532 (define_split
7533   [(set (match_operand:DI 0 "register_operand" "")
7534         (div:DI (match_operand:DI 1 "register_operand" "")
7535                 (match_operand:DI 2 "nonimmediate_operand" "")))
7536    (set (match_operand:DI 3 "register_operand" "")
7537         (mod:DI (match_dup 1) (match_dup 2)))
7538    (clobber (reg:CC FLAGS_REG))]
7539   "TARGET_64BIT && reload_completed"
7540   [(parallel [(set (match_dup 3)
7541                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7542               (clobber (reg:CC FLAGS_REG))])
7543    (parallel [(set (match_dup 0)
7544                    (div:DI (reg:DI 0) (match_dup 2)))
7545               (set (match_dup 3)
7546                    (mod:DI (reg:DI 0) (match_dup 2)))
7547               (use (match_dup 3))
7548               (clobber (reg:CC FLAGS_REG))])]
7549 {
7550   /* Avoid use of cltd in favor of a mov+shift.  */
7551   if (!TARGET_USE_CLTD && !optimize_size)
7552     {
7553       if (true_regnum (operands[1]))
7554         emit_move_insn (operands[0], operands[1]);
7555       else
7556         emit_move_insn (operands[3], operands[1]);
7557       operands[4] = operands[3];
7558     }
7559   else
7560     {
7561       if (true_regnum (operands[1]))
7562         abort();
7563       operands[4] = operands[1];
7564     }
7565 })
7566
7567
7568 (define_expand "divmodsi4"
7569   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7570                    (div:SI (match_operand:SI 1 "register_operand" "")
7571                            (match_operand:SI 2 "nonimmediate_operand" "")))
7572               (set (match_operand:SI 3 "register_operand" "")
7573                    (mod:SI (match_dup 1) (match_dup 2)))
7574               (clobber (reg:CC FLAGS_REG))])]
7575   ""
7576   "")
7577
7578 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7579 ;; Penalize eax case slightly because it results in worse scheduling
7580 ;; of code.
7581 (define_insn "*divmodsi4_nocltd"
7582   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7583         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7584                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7585    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7586         (mod:SI (match_dup 2) (match_dup 3)))
7587    (clobber (reg:CC FLAGS_REG))]
7588   "!optimize_size && !TARGET_USE_CLTD"
7589   "#"
7590   [(set_attr "type" "multi")])
7591
7592 (define_insn "*divmodsi4_cltd"
7593   [(set (match_operand:SI 0 "register_operand" "=a")
7594         (div:SI (match_operand:SI 2 "register_operand" "a")
7595                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7596    (set (match_operand:SI 1 "register_operand" "=&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 "*divmodsi_noext"
7604   [(set (match_operand:SI 0 "register_operand" "=a")
7605         (div:SI (match_operand:SI 1 "register_operand" "0")
7606                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7607    (set (match_operand:SI 3 "register_operand" "=d")
7608         (mod:SI (match_dup 1) (match_dup 2)))
7609    (use (match_operand:SI 4 "register_operand" "3"))
7610    (clobber (reg:CC FLAGS_REG))]
7611   ""
7612   "idiv{l}\t%2"
7613   [(set_attr "type" "idiv")
7614    (set_attr "mode" "SI")])
7615
7616 (define_split
7617   [(set (match_operand:SI 0 "register_operand" "")
7618         (div:SI (match_operand:SI 1 "register_operand" "")
7619                 (match_operand:SI 2 "nonimmediate_operand" "")))
7620    (set (match_operand:SI 3 "register_operand" "")
7621         (mod:SI (match_dup 1) (match_dup 2)))
7622    (clobber (reg:CC FLAGS_REG))]
7623   "reload_completed"
7624   [(parallel [(set (match_dup 3)
7625                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7626               (clobber (reg:CC FLAGS_REG))])
7627    (parallel [(set (match_dup 0)
7628                    (div:SI (reg:SI 0) (match_dup 2)))
7629               (set (match_dup 3)
7630                    (mod:SI (reg:SI 0) (match_dup 2)))
7631               (use (match_dup 3))
7632               (clobber (reg:CC FLAGS_REG))])]
7633 {
7634   /* Avoid use of cltd in favor of a mov+shift.  */
7635   if (!TARGET_USE_CLTD && !optimize_size)
7636     {
7637       if (true_regnum (operands[1]))
7638         emit_move_insn (operands[0], operands[1]);
7639       else
7640         emit_move_insn (operands[3], operands[1]);
7641       operands[4] = operands[3];
7642     }
7643   else
7644     {
7645       if (true_regnum (operands[1]))
7646         abort();
7647       operands[4] = operands[1];
7648     }
7649 })
7650 ;; %%% Split me.
7651 (define_insn "divmodhi4"
7652   [(set (match_operand:HI 0 "register_operand" "=a")
7653         (div:HI (match_operand:HI 1 "register_operand" "0")
7654                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7655    (set (match_operand:HI 3 "register_operand" "=&d")
7656         (mod:HI (match_dup 1) (match_dup 2)))
7657    (clobber (reg:CC FLAGS_REG))]
7658   "TARGET_HIMODE_MATH"
7659   "cwtd\;idiv{w}\t%2"
7660   [(set_attr "type" "multi")
7661    (set_attr "length_immediate" "0")
7662    (set_attr "mode" "SI")])
7663
7664 (define_insn "udivmoddi4"
7665   [(set (match_operand:DI 0 "register_operand" "=a")
7666         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7667                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7668    (set (match_operand:DI 3 "register_operand" "=&d")
7669         (umod:DI (match_dup 1) (match_dup 2)))
7670    (clobber (reg:CC FLAGS_REG))]
7671   "TARGET_64BIT"
7672   "xor{q}\t%3, %3\;div{q}\t%2"
7673   [(set_attr "type" "multi")
7674    (set_attr "length_immediate" "0")
7675    (set_attr "mode" "DI")])
7676
7677 (define_insn "*udivmoddi4_noext"
7678   [(set (match_operand:DI 0 "register_operand" "=a")
7679         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7680                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7681    (set (match_operand:DI 3 "register_operand" "=d")
7682         (umod:DI (match_dup 1) (match_dup 2)))
7683    (use (match_dup 3))
7684    (clobber (reg:CC FLAGS_REG))]
7685   "TARGET_64BIT"
7686   "div{q}\t%2"
7687   [(set_attr "type" "idiv")
7688    (set_attr "mode" "DI")])
7689
7690 (define_split
7691   [(set (match_operand:DI 0 "register_operand" "")
7692         (udiv:DI (match_operand:DI 1 "register_operand" "")
7693                  (match_operand:DI 2 "nonimmediate_operand" "")))
7694    (set (match_operand:DI 3 "register_operand" "")
7695         (umod:DI (match_dup 1) (match_dup 2)))
7696    (clobber (reg:CC FLAGS_REG))]
7697   "TARGET_64BIT && reload_completed"
7698   [(set (match_dup 3) (const_int 0))
7699    (parallel [(set (match_dup 0)
7700                    (udiv:DI (match_dup 1) (match_dup 2)))
7701               (set (match_dup 3)
7702                    (umod:DI (match_dup 1) (match_dup 2)))
7703               (use (match_dup 3))
7704               (clobber (reg:CC FLAGS_REG))])]
7705   "")
7706
7707 (define_insn "udivmodsi4"
7708   [(set (match_operand:SI 0 "register_operand" "=a")
7709         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7710                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7711    (set (match_operand:SI 3 "register_operand" "=&d")
7712         (umod:SI (match_dup 1) (match_dup 2)))
7713    (clobber (reg:CC FLAGS_REG))]
7714   ""
7715   "xor{l}\t%3, %3\;div{l}\t%2"
7716   [(set_attr "type" "multi")
7717    (set_attr "length_immediate" "0")
7718    (set_attr "mode" "SI")])
7719
7720 (define_insn "*udivmodsi4_noext"
7721   [(set (match_operand:SI 0 "register_operand" "=a")
7722         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7723                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7724    (set (match_operand:SI 3 "register_operand" "=d")
7725         (umod:SI (match_dup 1) (match_dup 2)))
7726    (use (match_dup 3))
7727    (clobber (reg:CC FLAGS_REG))]
7728   ""
7729   "div{l}\t%2"
7730   [(set_attr "type" "idiv")
7731    (set_attr "mode" "SI")])
7732
7733 (define_split
7734   [(set (match_operand:SI 0 "register_operand" "")
7735         (udiv:SI (match_operand:SI 1 "register_operand" "")
7736                  (match_operand:SI 2 "nonimmediate_operand" "")))
7737    (set (match_operand:SI 3 "register_operand" "")
7738         (umod:SI (match_dup 1) (match_dup 2)))
7739    (clobber (reg:CC FLAGS_REG))]
7740   "reload_completed"
7741   [(set (match_dup 3) (const_int 0))
7742    (parallel [(set (match_dup 0)
7743                    (udiv:SI (match_dup 1) (match_dup 2)))
7744               (set (match_dup 3)
7745                    (umod:SI (match_dup 1) (match_dup 2)))
7746               (use (match_dup 3))
7747               (clobber (reg:CC FLAGS_REG))])]
7748   "")
7749
7750 (define_expand "udivmodhi4"
7751   [(set (match_dup 4) (const_int 0))
7752    (parallel [(set (match_operand:HI 0 "register_operand" "")
7753                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7754                             (match_operand:HI 2 "nonimmediate_operand" "")))
7755               (set (match_operand:HI 3 "register_operand" "")
7756                    (umod:HI (match_dup 1) (match_dup 2)))
7757               (use (match_dup 4))
7758               (clobber (reg:CC FLAGS_REG))])]
7759   "TARGET_HIMODE_MATH"
7760   "operands[4] = gen_reg_rtx (HImode);")
7761
7762 (define_insn "*udivmodhi_noext"
7763   [(set (match_operand:HI 0 "register_operand" "=a")
7764         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7765                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7766    (set (match_operand:HI 3 "register_operand" "=d")
7767         (umod:HI (match_dup 1) (match_dup 2)))
7768    (use (match_operand:HI 4 "register_operand" "3"))
7769    (clobber (reg:CC FLAGS_REG))]
7770   ""
7771   "div{w}\t%2"
7772   [(set_attr "type" "idiv")
7773    (set_attr "mode" "HI")])
7774
7775 ;; We can not use div/idiv for double division, because it causes
7776 ;; "division by zero" on the overflow and that's not what we expect
7777 ;; from truncate.  Because true (non truncating) double division is
7778 ;; never generated, we can't create this insn anyway.
7779 ;
7780 ;(define_insn ""
7781 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7782 ;       (truncate:SI
7783 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7784 ;                  (zero_extend:DI
7785 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7786 ;   (set (match_operand:SI 3 "register_operand" "=d")
7787 ;       (truncate:SI
7788 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7789 ;   (clobber (reg:CC FLAGS_REG))]
7790 ;  ""
7791 ;  "div{l}\t{%2, %0|%0, %2}"
7792 ;  [(set_attr "type" "idiv")])
7793 \f
7794 ;;- Logical AND instructions
7795
7796 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7797 ;; Note that this excludes ah.
7798
7799 (define_insn "*testdi_1_rex64"
7800   [(set (reg 17)
7801         (compare
7802           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7803                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7804           (const_int 0)))]
7805   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7806    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7807   "@
7808    test{l}\t{%k1, %k0|%k0, %k1}
7809    test{l}\t{%k1, %k0|%k0, %k1}
7810    test{q}\t{%1, %0|%0, %1}
7811    test{q}\t{%1, %0|%0, %1}
7812    test{q}\t{%1, %0|%0, %1}"
7813   [(set_attr "type" "test")
7814    (set_attr "modrm" "0,1,0,1,1")
7815    (set_attr "mode" "SI,SI,DI,DI,DI")
7816    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7817
7818 (define_insn "testsi_1"
7819   [(set (reg 17)
7820         (compare
7821           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7822                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7823           (const_int 0)))]
7824   "ix86_match_ccmode (insn, CCNOmode)
7825    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7826   "test{l}\t{%1, %0|%0, %1}"
7827   [(set_attr "type" "test")
7828    (set_attr "modrm" "0,1,1")
7829    (set_attr "mode" "SI")
7830    (set_attr "pent_pair" "uv,np,uv")])
7831
7832 (define_expand "testsi_ccno_1"
7833   [(set (reg:CCNO FLAGS_REG)
7834         (compare:CCNO
7835           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7836                   (match_operand:SI 1 "nonmemory_operand" ""))
7837           (const_int 0)))]
7838   ""
7839   "")
7840
7841 (define_insn "*testhi_1"
7842   [(set (reg 17)
7843         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7844                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7845                  (const_int 0)))]
7846   "ix86_match_ccmode (insn, CCNOmode)
7847    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7848   "test{w}\t{%1, %0|%0, %1}"
7849   [(set_attr "type" "test")
7850    (set_attr "modrm" "0,1,1")
7851    (set_attr "mode" "HI")
7852    (set_attr "pent_pair" "uv,np,uv")])
7853
7854 (define_expand "testqi_ccz_1"
7855   [(set (reg:CCZ FLAGS_REG)
7856         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7857                              (match_operand:QI 1 "nonmemory_operand" ""))
7858                  (const_int 0)))]
7859   ""
7860   "")
7861
7862 (define_insn "*testqi_1"
7863   [(set (reg 17)
7864         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7865                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7866                  (const_int 0)))]
7867   "ix86_match_ccmode (insn, CCNOmode)
7868    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7869 {
7870   if (which_alternative == 3)
7871     {
7872       if (GET_CODE (operands[1]) == CONST_INT
7873           && (INTVAL (operands[1]) & 0xffffff00))
7874         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7875       return "test{l}\t{%1, %k0|%k0, %1}";
7876     }
7877   return "test{b}\t{%1, %0|%0, %1}";
7878 }
7879   [(set_attr "type" "test")
7880    (set_attr "modrm" "0,1,1,1")
7881    (set_attr "mode" "QI,QI,QI,SI")
7882    (set_attr "pent_pair" "uv,np,uv,np")])
7883
7884 (define_expand "testqi_ext_ccno_0"
7885   [(set (reg:CCNO FLAGS_REG)
7886         (compare:CCNO
7887           (and:SI
7888             (zero_extract:SI
7889               (match_operand 0 "ext_register_operand" "")
7890               (const_int 8)
7891               (const_int 8))
7892             (match_operand 1 "const_int_operand" ""))
7893           (const_int 0)))]
7894   ""
7895   "")
7896
7897 (define_insn "*testqi_ext_0"
7898   [(set (reg 17)
7899         (compare
7900           (and:SI
7901             (zero_extract:SI
7902               (match_operand 0 "ext_register_operand" "Q")
7903               (const_int 8)
7904               (const_int 8))
7905             (match_operand 1 "const_int_operand" "n"))
7906           (const_int 0)))]
7907   "ix86_match_ccmode (insn, CCNOmode)"
7908   "test{b}\t{%1, %h0|%h0, %1}"
7909   [(set_attr "type" "test")
7910    (set_attr "mode" "QI")
7911    (set_attr "length_immediate" "1")
7912    (set_attr "pent_pair" "np")])
7913
7914 (define_insn "*testqi_ext_1"
7915   [(set (reg 17)
7916         (compare
7917           (and:SI
7918             (zero_extract:SI
7919               (match_operand 0 "ext_register_operand" "Q")
7920               (const_int 8)
7921               (const_int 8))
7922             (zero_extend:SI
7923               (match_operand:QI 1 "general_operand" "Qm")))
7924           (const_int 0)))]
7925   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7926    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7927   "test{b}\t{%1, %h0|%h0, %1}"
7928   [(set_attr "type" "test")
7929    (set_attr "mode" "QI")])
7930
7931 (define_insn "*testqi_ext_1_rex64"
7932   [(set (reg 17)
7933         (compare
7934           (and:SI
7935             (zero_extract:SI
7936               (match_operand 0 "ext_register_operand" "Q")
7937               (const_int 8)
7938               (const_int 8))
7939             (zero_extend:SI
7940               (match_operand:QI 1 "register_operand" "Q")))
7941           (const_int 0)))]
7942   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7943   "test{b}\t{%1, %h0|%h0, %1}"
7944   [(set_attr "type" "test")
7945    (set_attr "mode" "QI")])
7946
7947 (define_insn "*testqi_ext_2"
7948   [(set (reg 17)
7949         (compare
7950           (and:SI
7951             (zero_extract:SI
7952               (match_operand 0 "ext_register_operand" "Q")
7953               (const_int 8)
7954               (const_int 8))
7955             (zero_extract:SI
7956               (match_operand 1 "ext_register_operand" "Q")
7957               (const_int 8)
7958               (const_int 8)))
7959           (const_int 0)))]
7960   "ix86_match_ccmode (insn, CCNOmode)"
7961   "test{b}\t{%h1, %h0|%h0, %h1}"
7962   [(set_attr "type" "test")
7963    (set_attr "mode" "QI")])
7964
7965 ;; Combine likes to form bit extractions for some tests.  Humor it.
7966 (define_insn "*testqi_ext_3"
7967   [(set (reg 17)
7968         (compare (zero_extract:SI
7969                    (match_operand 0 "nonimmediate_operand" "rm")
7970                    (match_operand:SI 1 "const_int_operand" "")
7971                    (match_operand:SI 2 "const_int_operand" ""))
7972                  (const_int 0)))]
7973   "ix86_match_ccmode (insn, CCNOmode)
7974    && (GET_MODE (operands[0]) == SImode
7975        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7976        || GET_MODE (operands[0]) == HImode
7977        || GET_MODE (operands[0]) == QImode)"
7978   "#")
7979
7980 (define_insn "*testqi_ext_3_rex64"
7981   [(set (reg 17)
7982         (compare (zero_extract:DI
7983                    (match_operand 0 "nonimmediate_operand" "rm")
7984                    (match_operand:DI 1 "const_int_operand" "")
7985                    (match_operand:DI 2 "const_int_operand" ""))
7986                  (const_int 0)))]
7987   "TARGET_64BIT
7988    && ix86_match_ccmode (insn, CCNOmode)
7989    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7990    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7991    /* Ensure that resulting mask is zero or sign extended operand.  */
7992    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7993        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7994            && INTVAL (operands[1]) > 32))
7995    && (GET_MODE (operands[0]) == SImode
7996        || GET_MODE (operands[0]) == DImode
7997        || GET_MODE (operands[0]) == HImode
7998        || GET_MODE (operands[0]) == QImode)"
7999   "#")
8000
8001 (define_split
8002   [(set (reg 17)
8003         (compare (zero_extract
8004                    (match_operand 0 "nonimmediate_operand" "")
8005                    (match_operand 1 "const_int_operand" "")
8006                    (match_operand 2 "const_int_operand" ""))
8007                  (const_int 0)))]
8008   "ix86_match_ccmode (insn, CCNOmode)"
8009   [(set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
8010 {
8011   HOST_WIDE_INT len = INTVAL (operands[1]);
8012   HOST_WIDE_INT pos = INTVAL (operands[2]);
8013   HOST_WIDE_INT mask;
8014   enum machine_mode mode, submode;
8015
8016   mode = GET_MODE (operands[0]);
8017   if (GET_CODE (operands[0]) == MEM)
8018     {
8019       /* ??? Combine likes to put non-volatile mem extractions in QImode
8020          no matter the size of the test.  So find a mode that works.  */
8021       if (! MEM_VOLATILE_P (operands[0]))
8022         {
8023           mode = smallest_mode_for_size (pos + len, MODE_INT);
8024           operands[0] = adjust_address (operands[0], mode, 0);
8025         }
8026     }
8027   else if (GET_CODE (operands[0]) == SUBREG
8028            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8029                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8030            && pos + len <= GET_MODE_BITSIZE (submode))
8031     {
8032       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8033       mode = submode;
8034       operands[0] = SUBREG_REG (operands[0]);
8035     }
8036   else if (mode == HImode && pos + len <= 8)
8037     {
8038       /* Small HImode tests can be converted to QImode.  */
8039       mode = QImode;
8040       operands[0] = gen_lowpart (QImode, operands[0]);
8041     }
8042
8043   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8044   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8045
8046   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8047 })
8048
8049 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8050 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8051 ;; this is relatively important trick.
8052 ;; Do the conversion only post-reload to avoid limiting of the register class
8053 ;; to QI regs.
8054 (define_split
8055   [(set (reg 17)
8056         (compare
8057           (and (match_operand 0 "register_operand" "")
8058                (match_operand 1 "const_int_operand" ""))
8059           (const_int 0)))]
8060    "reload_completed
8061     && QI_REG_P (operands[0])
8062     && ((ix86_match_ccmode (insn, CCZmode)
8063          && !(INTVAL (operands[1]) & ~(255 << 8)))
8064         || (ix86_match_ccmode (insn, CCNOmode)
8065             && !(INTVAL (operands[1]) & ~(127 << 8))))
8066     && GET_MODE (operands[0]) != QImode"
8067   [(set (reg:CCNO FLAGS_REG)
8068         (compare:CCNO
8069           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8070                   (match_dup 1))
8071           (const_int 0)))]
8072   "operands[0] = gen_lowpart (SImode, operands[0]);
8073    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8074
8075 (define_split
8076   [(set (reg 17)
8077         (compare
8078           (and (match_operand 0 "nonimmediate_operand" "")
8079                (match_operand 1 "const_int_operand" ""))
8080           (const_int 0)))]
8081    "reload_completed
8082     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8083     && ((ix86_match_ccmode (insn, CCZmode)
8084          && !(INTVAL (operands[1]) & ~255))
8085         || (ix86_match_ccmode (insn, CCNOmode)
8086             && !(INTVAL (operands[1]) & ~127)))
8087     && GET_MODE (operands[0]) != QImode"
8088   [(set (reg:CCNO FLAGS_REG)
8089         (compare:CCNO
8090           (and:QI (match_dup 0)
8091                   (match_dup 1))
8092           (const_int 0)))]
8093   "operands[0] = gen_lowpart (QImode, operands[0]);
8094    operands[1] = gen_lowpart (QImode, operands[1]);")
8095
8096
8097 ;; %%% This used to optimize known byte-wide and operations to memory,
8098 ;; and sometimes to QImode registers.  If this is considered useful,
8099 ;; it should be done with splitters.
8100
8101 (define_expand "anddi3"
8102   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8103         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8104                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8105    (clobber (reg:CC FLAGS_REG))]
8106   "TARGET_64BIT"
8107   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8108
8109 (define_insn "*anddi_1_rex64"
8110   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8111         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8112                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8113    (clobber (reg:CC FLAGS_REG))]
8114   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8115 {
8116   switch (get_attr_type (insn))
8117     {
8118     case TYPE_IMOVX:
8119       {
8120         enum machine_mode mode;
8121
8122         if (GET_CODE (operands[2]) != CONST_INT)
8123           abort ();
8124         if (INTVAL (operands[2]) == 0xff)
8125           mode = QImode;
8126         else if (INTVAL (operands[2]) == 0xffff)
8127           mode = HImode;
8128         else
8129           abort ();
8130         
8131         operands[1] = gen_lowpart (mode, operands[1]);
8132         if (mode == QImode)
8133           return "movz{bq|x}\t{%1,%0|%0, %1}";
8134         else
8135           return "movz{wq|x}\t{%1,%0|%0, %1}";
8136       }
8137
8138     default:
8139       if (! rtx_equal_p (operands[0], operands[1]))
8140         abort ();
8141       if (get_attr_mode (insn) == MODE_SI)
8142         return "and{l}\t{%k2, %k0|%k0, %k2}";
8143       else
8144         return "and{q}\t{%2, %0|%0, %2}";
8145     }
8146 }
8147   [(set_attr "type" "alu,alu,alu,imovx")
8148    (set_attr "length_immediate" "*,*,*,0")
8149    (set_attr "mode" "SI,DI,DI,DI")])
8150
8151 (define_insn "*anddi_2"
8152   [(set (reg 17)
8153         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8154                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8155                  (const_int 0)))
8156    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8157         (and:DI (match_dup 1) (match_dup 2)))]
8158   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8159    && ix86_binary_operator_ok (AND, DImode, operands)"
8160   "@
8161    and{l}\t{%k2, %k0|%k0, %k2}
8162    and{q}\t{%2, %0|%0, %2}
8163    and{q}\t{%2, %0|%0, %2}"
8164   [(set_attr "type" "alu")
8165    (set_attr "mode" "SI,DI,DI")])
8166
8167 (define_expand "andsi3"
8168   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8169         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8170                 (match_operand:SI 2 "general_operand" "")))
8171    (clobber (reg:CC FLAGS_REG))]
8172   ""
8173   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8174
8175 (define_insn "*andsi_1"
8176   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8177         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8178                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8179    (clobber (reg:CC FLAGS_REG))]
8180   "ix86_binary_operator_ok (AND, SImode, operands)"
8181 {
8182   switch (get_attr_type (insn))
8183     {
8184     case TYPE_IMOVX:
8185       {
8186         enum machine_mode mode;
8187
8188         if (GET_CODE (operands[2]) != CONST_INT)
8189           abort ();
8190         if (INTVAL (operands[2]) == 0xff)
8191           mode = QImode;
8192         else if (INTVAL (operands[2]) == 0xffff)
8193           mode = HImode;
8194         else
8195           abort ();
8196         
8197         operands[1] = gen_lowpart (mode, operands[1]);
8198         if (mode == QImode)
8199           return "movz{bl|x}\t{%1,%0|%0, %1}";
8200         else
8201           return "movz{wl|x}\t{%1,%0|%0, %1}";
8202       }
8203
8204     default:
8205       if (! rtx_equal_p (operands[0], operands[1]))
8206         abort ();
8207       return "and{l}\t{%2, %0|%0, %2}";
8208     }
8209 }
8210   [(set_attr "type" "alu,alu,imovx")
8211    (set_attr "length_immediate" "*,*,0")
8212    (set_attr "mode" "SI")])
8213
8214 (define_split
8215   [(set (match_operand 0 "register_operand" "")
8216         (and (match_dup 0)
8217              (const_int -65536)))
8218    (clobber (reg:CC FLAGS_REG))]
8219   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8220   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8221   "operands[1] = gen_lowpart (HImode, operands[0]);")
8222
8223 (define_split
8224   [(set (match_operand 0 "ext_register_operand" "")
8225         (and (match_dup 0)
8226              (const_int -256)))
8227    (clobber (reg:CC FLAGS_REG))]
8228   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8229   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8230   "operands[1] = gen_lowpart (QImode, operands[0]);")
8231
8232 (define_split
8233   [(set (match_operand 0 "ext_register_operand" "")
8234         (and (match_dup 0)
8235              (const_int -65281)))
8236    (clobber (reg:CC FLAGS_REG))]
8237   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8238   [(parallel [(set (zero_extract:SI (match_dup 0)
8239                                     (const_int 8)
8240                                     (const_int 8))
8241                    (xor:SI 
8242                      (zero_extract:SI (match_dup 0)
8243                                       (const_int 8)
8244                                       (const_int 8))
8245                      (zero_extract:SI (match_dup 0)
8246                                       (const_int 8)
8247                                       (const_int 8))))
8248               (clobber (reg:CC FLAGS_REG))])]
8249   "operands[0] = gen_lowpart (SImode, operands[0]);")
8250
8251 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8252 (define_insn "*andsi_1_zext"
8253   [(set (match_operand:DI 0 "register_operand" "=r")
8254         (zero_extend:DI
8255           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8256                   (match_operand:SI 2 "general_operand" "rim"))))
8257    (clobber (reg:CC FLAGS_REG))]
8258   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8259   "and{l}\t{%2, %k0|%k0, %2}"
8260   [(set_attr "type" "alu")
8261    (set_attr "mode" "SI")])
8262
8263 (define_insn "*andsi_2"
8264   [(set (reg 17)
8265         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8266                          (match_operand:SI 2 "general_operand" "rim,ri"))
8267                  (const_int 0)))
8268    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8269         (and:SI (match_dup 1) (match_dup 2)))]
8270   "ix86_match_ccmode (insn, CCNOmode)
8271    && ix86_binary_operator_ok (AND, SImode, operands)"
8272   "and{l}\t{%2, %0|%0, %2}"
8273   [(set_attr "type" "alu")
8274    (set_attr "mode" "SI")])
8275
8276 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8277 (define_insn "*andsi_2_zext"
8278   [(set (reg 17)
8279         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8280                          (match_operand:SI 2 "general_operand" "rim"))
8281                  (const_int 0)))
8282    (set (match_operand:DI 0 "register_operand" "=r")
8283         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8284   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8285    && ix86_binary_operator_ok (AND, SImode, operands)"
8286   "and{l}\t{%2, %k0|%k0, %2}"
8287   [(set_attr "type" "alu")
8288    (set_attr "mode" "SI")])
8289
8290 (define_expand "andhi3"
8291   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8292         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8293                 (match_operand:HI 2 "general_operand" "")))
8294    (clobber (reg:CC FLAGS_REG))]
8295   "TARGET_HIMODE_MATH"
8296   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8297
8298 (define_insn "*andhi_1"
8299   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8300         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8301                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8302    (clobber (reg:CC FLAGS_REG))]
8303   "ix86_binary_operator_ok (AND, HImode, operands)"
8304 {
8305   switch (get_attr_type (insn))
8306     {
8307     case TYPE_IMOVX:
8308       if (GET_CODE (operands[2]) != CONST_INT)
8309         abort ();
8310       if (INTVAL (operands[2]) == 0xff)
8311         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8312       abort ();
8313
8314     default:
8315       if (! rtx_equal_p (operands[0], operands[1]))
8316         abort ();
8317
8318       return "and{w}\t{%2, %0|%0, %2}";
8319     }
8320 }
8321   [(set_attr "type" "alu,alu,imovx")
8322    (set_attr "length_immediate" "*,*,0")
8323    (set_attr "mode" "HI,HI,SI")])
8324
8325 (define_insn "*andhi_2"
8326   [(set (reg 17)
8327         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8328                          (match_operand:HI 2 "general_operand" "rim,ri"))
8329                  (const_int 0)))
8330    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8331         (and:HI (match_dup 1) (match_dup 2)))]
8332   "ix86_match_ccmode (insn, CCNOmode)
8333    && ix86_binary_operator_ok (AND, HImode, operands)"
8334   "and{w}\t{%2, %0|%0, %2}"
8335   [(set_attr "type" "alu")
8336    (set_attr "mode" "HI")])
8337
8338 (define_expand "andqi3"
8339   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8340         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8341                 (match_operand:QI 2 "general_operand" "")))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "TARGET_QIMODE_MATH"
8344   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8345
8346 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8347 (define_insn "*andqi_1"
8348   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8349         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8350                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8351    (clobber (reg:CC FLAGS_REG))]
8352   "ix86_binary_operator_ok (AND, QImode, operands)"
8353   "@
8354    and{b}\t{%2, %0|%0, %2}
8355    and{b}\t{%2, %0|%0, %2}
8356    and{l}\t{%k2, %k0|%k0, %k2}"
8357   [(set_attr "type" "alu")
8358    (set_attr "mode" "QI,QI,SI")])
8359
8360 (define_insn "*andqi_1_slp"
8361   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8362         (and:QI (match_dup 0)
8363                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8364    (clobber (reg:CC FLAGS_REG))]
8365   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8366    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8367   "and{b}\t{%1, %0|%0, %1}"
8368   [(set_attr "type" "alu1")
8369    (set_attr "mode" "QI")])
8370
8371 (define_insn "*andqi_2"
8372   [(set (reg 17)
8373         (compare (and:QI
8374                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8375                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8376                  (const_int 0)))
8377    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8378         (and:QI (match_dup 1) (match_dup 2)))]
8379   "ix86_match_ccmode (insn, CCNOmode)
8380    && ix86_binary_operator_ok (AND, QImode, operands)"
8381 {
8382   if (which_alternative == 2)
8383     {
8384       if (GET_CODE (operands[2]) == CONST_INT
8385           && (INTVAL (operands[2]) & 0xffffff00))
8386         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8387       return "and{l}\t{%2, %k0|%k0, %2}";
8388     }
8389   return "and{b}\t{%2, %0|%0, %2}";
8390 }
8391   [(set_attr "type" "alu")
8392    (set_attr "mode" "QI,QI,SI")])
8393
8394 (define_insn "*andqi_2_slp"
8395   [(set (reg 17)
8396         (compare (and:QI
8397                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8398                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8399                  (const_int 0)))
8400    (set (strict_low_part (match_dup 0))
8401         (and:QI (match_dup 0) (match_dup 1)))]
8402   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8403    && ix86_match_ccmode (insn, CCNOmode)
8404    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8405   "and{b}\t{%1, %0|%0, %1}"
8406   [(set_attr "type" "alu1")
8407    (set_attr "mode" "QI")])
8408
8409 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8410 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8411 ;; for a QImode operand, which of course failed.
8412
8413 (define_insn "andqi_ext_0"
8414   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8415                          (const_int 8)
8416                          (const_int 8))
8417         (and:SI 
8418           (zero_extract:SI
8419             (match_operand 1 "ext_register_operand" "0")
8420             (const_int 8)
8421             (const_int 8))
8422           (match_operand 2 "const_int_operand" "n")))
8423    (clobber (reg:CC FLAGS_REG))]
8424   ""
8425   "and{b}\t{%2, %h0|%h0, %2}"
8426   [(set_attr "type" "alu")
8427    (set_attr "length_immediate" "1")
8428    (set_attr "mode" "QI")])
8429
8430 ;; Generated by peephole translating test to and.  This shows up
8431 ;; often in fp comparisons.
8432
8433 (define_insn "*andqi_ext_0_cc"
8434   [(set (reg 17)
8435         (compare
8436           (and:SI
8437             (zero_extract:SI
8438               (match_operand 1 "ext_register_operand" "0")
8439               (const_int 8)
8440               (const_int 8))
8441             (match_operand 2 "const_int_operand" "n"))
8442           (const_int 0)))
8443    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444                          (const_int 8)
8445                          (const_int 8))
8446         (and:SI 
8447           (zero_extract:SI
8448             (match_dup 1)
8449             (const_int 8)
8450             (const_int 8))
8451           (match_dup 2)))]
8452   "ix86_match_ccmode (insn, CCNOmode)"
8453   "and{b}\t{%2, %h0|%h0, %2}"
8454   [(set_attr "type" "alu")
8455    (set_attr "length_immediate" "1")
8456    (set_attr "mode" "QI")])
8457
8458 (define_insn "*andqi_ext_1"
8459   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8460                          (const_int 8)
8461                          (const_int 8))
8462         (and:SI 
8463           (zero_extract:SI
8464             (match_operand 1 "ext_register_operand" "0")
8465             (const_int 8)
8466             (const_int 8))
8467           (zero_extend:SI
8468             (match_operand:QI 2 "general_operand" "Qm"))))
8469    (clobber (reg:CC FLAGS_REG))]
8470   "!TARGET_64BIT"
8471   "and{b}\t{%2, %h0|%h0, %2}"
8472   [(set_attr "type" "alu")
8473    (set_attr "length_immediate" "0")
8474    (set_attr "mode" "QI")])
8475
8476 (define_insn "*andqi_ext_1_rex64"
8477   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8478                          (const_int 8)
8479                          (const_int 8))
8480         (and:SI 
8481           (zero_extract:SI
8482             (match_operand 1 "ext_register_operand" "0")
8483             (const_int 8)
8484             (const_int 8))
8485           (zero_extend:SI
8486             (match_operand 2 "ext_register_operand" "Q"))))
8487    (clobber (reg:CC FLAGS_REG))]
8488   "TARGET_64BIT"
8489   "and{b}\t{%2, %h0|%h0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "length_immediate" "0")
8492    (set_attr "mode" "QI")])
8493
8494 (define_insn "*andqi_ext_2"
8495   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8496                          (const_int 8)
8497                          (const_int 8))
8498         (and:SI
8499           (zero_extract:SI
8500             (match_operand 1 "ext_register_operand" "%0")
8501             (const_int 8)
8502             (const_int 8))
8503           (zero_extract:SI
8504             (match_operand 2 "ext_register_operand" "Q")
8505             (const_int 8)
8506             (const_int 8))))
8507    (clobber (reg:CC FLAGS_REG))]
8508   ""
8509   "and{b}\t{%h2, %h0|%h0, %h2}"
8510   [(set_attr "type" "alu")
8511    (set_attr "length_immediate" "0")
8512    (set_attr "mode" "QI")])
8513
8514 ;; Convert wide AND instructions with immediate operand to shorter QImode
8515 ;; equivalents when possible.
8516 ;; Don't do the splitting with memory operands, since it introduces risk
8517 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8518 ;; for size, but that can (should?) be handled by generic code instead.
8519 (define_split
8520   [(set (match_operand 0 "register_operand" "")
8521         (and (match_operand 1 "register_operand" "")
8522              (match_operand 2 "const_int_operand" "")))
8523    (clobber (reg:CC FLAGS_REG))]
8524    "reload_completed
8525     && QI_REG_P (operands[0])
8526     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8527     && !(~INTVAL (operands[2]) & ~(255 << 8))
8528     && GET_MODE (operands[0]) != QImode"
8529   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8530                    (and:SI (zero_extract:SI (match_dup 1)
8531                                             (const_int 8) (const_int 8))
8532                            (match_dup 2)))
8533               (clobber (reg:CC FLAGS_REG))])]
8534   "operands[0] = gen_lowpart (SImode, operands[0]);
8535    operands[1] = gen_lowpart (SImode, operands[1]);
8536    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8537
8538 ;; Since AND can be encoded with sign extended immediate, this is only
8539 ;; profitable when 7th bit is not set.
8540 (define_split
8541   [(set (match_operand 0 "register_operand" "")
8542         (and (match_operand 1 "general_operand" "")
8543              (match_operand 2 "const_int_operand" "")))
8544    (clobber (reg:CC FLAGS_REG))]
8545    "reload_completed
8546     && ANY_QI_REG_P (operands[0])
8547     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8548     && !(~INTVAL (operands[2]) & ~255)
8549     && !(INTVAL (operands[2]) & 128)
8550     && GET_MODE (operands[0]) != QImode"
8551   [(parallel [(set (strict_low_part (match_dup 0))
8552                    (and:QI (match_dup 1)
8553                            (match_dup 2)))
8554               (clobber (reg:CC FLAGS_REG))])]
8555   "operands[0] = gen_lowpart (QImode, operands[0]);
8556    operands[1] = gen_lowpart (QImode, operands[1]);
8557    operands[2] = gen_lowpart (QImode, operands[2]);")
8558 \f
8559 ;; Logical inclusive OR instructions
8560
8561 ;; %%% This used to optimize known byte-wide and operations to memory.
8562 ;; If this is considered useful, it should be done with splitters.
8563
8564 (define_expand "iordi3"
8565   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8566         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8567                 (match_operand:DI 2 "x86_64_general_operand" "")))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "TARGET_64BIT"
8570   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8571
8572 (define_insn "*iordi_1_rex64"
8573   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8574         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8575                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8576    (clobber (reg:CC FLAGS_REG))]
8577   "TARGET_64BIT
8578    && ix86_binary_operator_ok (IOR, DImode, operands)"
8579   "or{q}\t{%2, %0|%0, %2}"
8580   [(set_attr "type" "alu")
8581    (set_attr "mode" "DI")])
8582
8583 (define_insn "*iordi_2_rex64"
8584   [(set (reg 17)
8585         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8587                  (const_int 0)))
8588    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8589         (ior:DI (match_dup 1) (match_dup 2)))]
8590   "TARGET_64BIT
8591    && ix86_match_ccmode (insn, CCNOmode)
8592    && ix86_binary_operator_ok (IOR, DImode, operands)"
8593   "or{q}\t{%2, %0|%0, %2}"
8594   [(set_attr "type" "alu")
8595    (set_attr "mode" "DI")])
8596
8597 (define_insn "*iordi_3_rex64"
8598   [(set (reg 17)
8599         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8600                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8601                  (const_int 0)))
8602    (clobber (match_scratch:DI 0 "=r"))]
8603   "TARGET_64BIT
8604    && ix86_match_ccmode (insn, CCNOmode)
8605    && ix86_binary_operator_ok (IOR, DImode, operands)"
8606   "or{q}\t{%2, %0|%0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "DI")])
8609
8610
8611 (define_expand "iorsi3"
8612   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8613         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8614                 (match_operand:SI 2 "general_operand" "")))
8615    (clobber (reg:CC FLAGS_REG))]
8616   ""
8617   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8618
8619 (define_insn "*iorsi_1"
8620   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8621         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8622                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8623    (clobber (reg:CC FLAGS_REG))]
8624   "ix86_binary_operator_ok (IOR, SImode, operands)"
8625   "or{l}\t{%2, %0|%0, %2}"
8626   [(set_attr "type" "alu")
8627    (set_attr "mode" "SI")])
8628
8629 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8630 (define_insn "*iorsi_1_zext"
8631   [(set (match_operand:DI 0 "register_operand" "=rm")
8632         (zero_extend:DI
8633           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8634                   (match_operand:SI 2 "general_operand" "rim"))))
8635    (clobber (reg:CC FLAGS_REG))]
8636   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8637   "or{l}\t{%2, %k0|%k0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "SI")])
8640
8641 (define_insn "*iorsi_1_zext_imm"
8642   [(set (match_operand:DI 0 "register_operand" "=rm")
8643         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8644                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8645    (clobber (reg:CC FLAGS_REG))]
8646   "TARGET_64BIT"
8647   "or{l}\t{%2, %k0|%k0, %2}"
8648   [(set_attr "type" "alu")
8649    (set_attr "mode" "SI")])
8650
8651 (define_insn "*iorsi_2"
8652   [(set (reg 17)
8653         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8654                          (match_operand:SI 2 "general_operand" "rim,ri"))
8655                  (const_int 0)))
8656    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8657         (ior:SI (match_dup 1) (match_dup 2)))]
8658   "ix86_match_ccmode (insn, CCNOmode)
8659    && ix86_binary_operator_ok (IOR, SImode, operands)"
8660   "or{l}\t{%2, %0|%0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8663
8664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665 ;; ??? Special case for immediate operand is missing - it is tricky.
8666 (define_insn "*iorsi_2_zext"
8667   [(set (reg 17)
8668         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669                          (match_operand:SI 2 "general_operand" "rim"))
8670                  (const_int 0)))
8671    (set (match_operand:DI 0 "register_operand" "=r")
8672         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8673   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8674    && ix86_binary_operator_ok (IOR, SImode, operands)"
8675   "or{l}\t{%2, %k0|%k0, %2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "SI")])
8678
8679 (define_insn "*iorsi_2_zext_imm"
8680   [(set (reg 17)
8681         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8682                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8683                  (const_int 0)))
8684    (set (match_operand:DI 0 "register_operand" "=r")
8685         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8686   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8687    && ix86_binary_operator_ok (IOR, SImode, operands)"
8688   "or{l}\t{%2, %k0|%k0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "mode" "SI")])
8691
8692 (define_insn "*iorsi_3"
8693   [(set (reg 17)
8694         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8695                          (match_operand:SI 2 "general_operand" "rim"))
8696                  (const_int 0)))
8697    (clobber (match_scratch:SI 0 "=r"))]
8698   "ix86_match_ccmode (insn, CCNOmode)
8699    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8700   "or{l}\t{%2, %0|%0, %2}"
8701   [(set_attr "type" "alu")
8702    (set_attr "mode" "SI")])
8703
8704 (define_expand "iorhi3"
8705   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8706         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8707                 (match_operand:HI 2 "general_operand" "")))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "TARGET_HIMODE_MATH"
8710   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8711
8712 (define_insn "*iorhi_1"
8713   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8714         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8715                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8716    (clobber (reg:CC FLAGS_REG))]
8717   "ix86_binary_operator_ok (IOR, HImode, operands)"
8718   "or{w}\t{%2, %0|%0, %2}"
8719   [(set_attr "type" "alu")
8720    (set_attr "mode" "HI")])
8721
8722 (define_insn "*iorhi_2"
8723   [(set (reg 17)
8724         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8725                          (match_operand:HI 2 "general_operand" "rim,ri"))
8726                  (const_int 0)))
8727    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8728         (ior:HI (match_dup 1) (match_dup 2)))]
8729   "ix86_match_ccmode (insn, CCNOmode)
8730    && ix86_binary_operator_ok (IOR, HImode, operands)"
8731   "or{w}\t{%2, %0|%0, %2}"
8732   [(set_attr "type" "alu")
8733    (set_attr "mode" "HI")])
8734
8735 (define_insn "*iorhi_3"
8736   [(set (reg 17)
8737         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8738                          (match_operand:HI 2 "general_operand" "rim"))
8739                  (const_int 0)))
8740    (clobber (match_scratch:HI 0 "=r"))]
8741   "ix86_match_ccmode (insn, CCNOmode)
8742    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8743   "or{w}\t{%2, %0|%0, %2}"
8744   [(set_attr "type" "alu")
8745    (set_attr "mode" "HI")])
8746
8747 (define_expand "iorqi3"
8748   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8749         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8750                 (match_operand:QI 2 "general_operand" "")))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "TARGET_QIMODE_MATH"
8753   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8754
8755 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8756 (define_insn "*iorqi_1"
8757   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8758         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8759                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "ix86_binary_operator_ok (IOR, QImode, operands)"
8762   "@
8763    or{b}\t{%2, %0|%0, %2}
8764    or{b}\t{%2, %0|%0, %2}
8765    or{l}\t{%k2, %k0|%k0, %k2}"
8766   [(set_attr "type" "alu")
8767    (set_attr "mode" "QI,QI,SI")])
8768
8769 (define_insn "*iorqi_1_slp"
8770   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8771         (ior:QI (match_dup 0)
8772                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8775    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8776   "or{b}\t{%1, %0|%0, %1}"
8777   [(set_attr "type" "alu1")
8778    (set_attr "mode" "QI")])
8779
8780 (define_insn "*iorqi_2"
8781   [(set (reg 17)
8782         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8783                          (match_operand:QI 2 "general_operand" "qim,qi"))
8784                  (const_int 0)))
8785    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8786         (ior:QI (match_dup 1) (match_dup 2)))]
8787   "ix86_match_ccmode (insn, CCNOmode)
8788    && ix86_binary_operator_ok (IOR, QImode, operands)"
8789   "or{b}\t{%2, %0|%0, %2}"
8790   [(set_attr "type" "alu")
8791    (set_attr "mode" "QI")])
8792
8793 (define_insn "*iorqi_2_slp"
8794   [(set (reg 17)
8795         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8796                          (match_operand:QI 1 "general_operand" "qim,qi"))
8797                  (const_int 0)))
8798    (set (strict_low_part (match_dup 0))
8799         (ior:QI (match_dup 0) (match_dup 1)))]
8800   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8801    && ix86_match_ccmode (insn, CCNOmode)
8802    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8803   "or{b}\t{%1, %0|%0, %1}"
8804   [(set_attr "type" "alu1")
8805    (set_attr "mode" "QI")])
8806
8807 (define_insn "*iorqi_3"
8808   [(set (reg 17)
8809         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8810                          (match_operand:QI 2 "general_operand" "qim"))
8811                  (const_int 0)))
8812    (clobber (match_scratch:QI 0 "=q"))]
8813   "ix86_match_ccmode (insn, CCNOmode)
8814    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8815   "or{b}\t{%2, %0|%0, %2}"
8816   [(set_attr "type" "alu")
8817    (set_attr "mode" "QI")])
8818
8819 (define_insn "iorqi_ext_0"
8820   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821                          (const_int 8)
8822                          (const_int 8))
8823         (ior:SI 
8824           (zero_extract:SI
8825             (match_operand 1 "ext_register_operand" "0")
8826             (const_int 8)
8827             (const_int 8))
8828           (match_operand 2 "const_int_operand" "n")))
8829    (clobber (reg:CC FLAGS_REG))]
8830   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8831   "or{b}\t{%2, %h0|%h0, %2}"
8832   [(set_attr "type" "alu")
8833    (set_attr "length_immediate" "1")
8834    (set_attr "mode" "QI")])
8835
8836 (define_insn "*iorqi_ext_1"
8837   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8838                          (const_int 8)
8839                          (const_int 8))
8840         (ior:SI 
8841           (zero_extract:SI
8842             (match_operand 1 "ext_register_operand" "0")
8843             (const_int 8)
8844             (const_int 8))
8845           (zero_extend:SI
8846             (match_operand:QI 2 "general_operand" "Qm"))))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "!TARGET_64BIT
8849    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8850   "or{b}\t{%2, %h0|%h0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "length_immediate" "0")
8853    (set_attr "mode" "QI")])
8854
8855 (define_insn "*iorqi_ext_1_rex64"
8856   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8857                          (const_int 8)
8858                          (const_int 8))
8859         (ior:SI 
8860           (zero_extract:SI
8861             (match_operand 1 "ext_register_operand" "0")
8862             (const_int 8)
8863             (const_int 8))
8864           (zero_extend:SI
8865             (match_operand 2 "ext_register_operand" "Q"))))
8866    (clobber (reg:CC FLAGS_REG))]
8867   "TARGET_64BIT
8868    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8869   "or{b}\t{%2, %h0|%h0, %2}"
8870   [(set_attr "type" "alu")
8871    (set_attr "length_immediate" "0")
8872    (set_attr "mode" "QI")])
8873
8874 (define_insn "*iorqi_ext_2"
8875   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8876                          (const_int 8)
8877                          (const_int 8))
8878         (ior:SI 
8879           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8880                            (const_int 8)
8881                            (const_int 8))
8882           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8883                            (const_int 8)
8884                            (const_int 8))))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8887   "ior{b}\t{%h2, %h0|%h0, %h2}"
8888   [(set_attr "type" "alu")
8889    (set_attr "length_immediate" "0")
8890    (set_attr "mode" "QI")])
8891
8892 (define_split
8893   [(set (match_operand 0 "register_operand" "")
8894         (ior (match_operand 1 "register_operand" "")
8895              (match_operand 2 "const_int_operand" "")))
8896    (clobber (reg:CC FLAGS_REG))]
8897    "reload_completed
8898     && QI_REG_P (operands[0])
8899     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8900     && !(INTVAL (operands[2]) & ~(255 << 8))
8901     && GET_MODE (operands[0]) != QImode"
8902   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8903                    (ior:SI (zero_extract:SI (match_dup 1)
8904                                             (const_int 8) (const_int 8))
8905                            (match_dup 2)))
8906               (clobber (reg:CC FLAGS_REG))])]
8907   "operands[0] = gen_lowpart (SImode, operands[0]);
8908    operands[1] = gen_lowpart (SImode, operands[1]);
8909    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8910
8911 ;; Since OR can be encoded with sign extended immediate, this is only
8912 ;; profitable when 7th bit is set.
8913 (define_split
8914   [(set (match_operand 0 "register_operand" "")
8915         (ior (match_operand 1 "general_operand" "")
8916              (match_operand 2 "const_int_operand" "")))
8917    (clobber (reg:CC FLAGS_REG))]
8918    "reload_completed
8919     && ANY_QI_REG_P (operands[0])
8920     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8921     && !(INTVAL (operands[2]) & ~255)
8922     && (INTVAL (operands[2]) & 128)
8923     && GET_MODE (operands[0]) != QImode"
8924   [(parallel [(set (strict_low_part (match_dup 0))
8925                    (ior:QI (match_dup 1)
8926                            (match_dup 2)))
8927               (clobber (reg:CC FLAGS_REG))])]
8928   "operands[0] = gen_lowpart (QImode, operands[0]);
8929    operands[1] = gen_lowpart (QImode, operands[1]);
8930    operands[2] = gen_lowpart (QImode, operands[2]);")
8931 \f
8932 ;; Logical XOR instructions
8933
8934 ;; %%% This used to optimize known byte-wide and operations to memory.
8935 ;; If this is considered useful, it should be done with splitters.
8936
8937 (define_expand "xordi3"
8938   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8939         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8940                 (match_operand:DI 2 "x86_64_general_operand" "")))
8941    (clobber (reg:CC FLAGS_REG))]
8942   "TARGET_64BIT"
8943   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8944
8945 (define_insn "*xordi_1_rex64"
8946   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8947         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8948                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "TARGET_64BIT
8951    && ix86_binary_operator_ok (XOR, DImode, operands)"
8952   "@
8953    xor{q}\t{%2, %0|%0, %2}
8954    xor{q}\t{%2, %0|%0, %2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "DI,DI")])
8957
8958 (define_insn "*xordi_2_rex64"
8959   [(set (reg 17)
8960         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8961                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8962                  (const_int 0)))
8963    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8964         (xor:DI (match_dup 1) (match_dup 2)))]
8965   "TARGET_64BIT
8966    && ix86_match_ccmode (insn, CCNOmode)
8967    && ix86_binary_operator_ok (XOR, DImode, operands)"
8968   "@
8969    xor{q}\t{%2, %0|%0, %2}
8970    xor{q}\t{%2, %0|%0, %2}"
8971   [(set_attr "type" "alu")
8972    (set_attr "mode" "DI,DI")])
8973
8974 (define_insn "*xordi_3_rex64"
8975   [(set (reg 17)
8976         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8977                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8978                  (const_int 0)))
8979    (clobber (match_scratch:DI 0 "=r"))]
8980   "TARGET_64BIT
8981    && ix86_match_ccmode (insn, CCNOmode)
8982    && ix86_binary_operator_ok (XOR, DImode, operands)"
8983   "xor{q}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "DI")])
8986
8987 (define_expand "xorsi3"
8988   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8989         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8990                 (match_operand:SI 2 "general_operand" "")))
8991    (clobber (reg:CC FLAGS_REG))]
8992   ""
8993   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8994
8995 (define_insn "*xorsi_1"
8996   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8997         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8998                 (match_operand:SI 2 "general_operand" "ri,rm")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "ix86_binary_operator_ok (XOR, SImode, operands)"
9001   "xor{l}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "SI")])
9004
9005 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9006 ;; Add speccase for immediates
9007 (define_insn "*xorsi_1_zext"
9008   [(set (match_operand:DI 0 "register_operand" "=r")
9009         (zero_extend:DI
9010           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011                   (match_operand:SI 2 "general_operand" "rim"))))
9012    (clobber (reg:CC FLAGS_REG))]
9013   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9014   "xor{l}\t{%2, %k0|%k0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "SI")])
9017
9018 (define_insn "*xorsi_1_zext_imm"
9019   [(set (match_operand:DI 0 "register_operand" "=r")
9020         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9021                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9022    (clobber (reg:CC FLAGS_REG))]
9023   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9024   "xor{l}\t{%2, %k0|%k0, %2}"
9025   [(set_attr "type" "alu")
9026    (set_attr "mode" "SI")])
9027
9028 (define_insn "*xorsi_2"
9029   [(set (reg 17)
9030         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9031                          (match_operand:SI 2 "general_operand" "rim,ri"))
9032                  (const_int 0)))
9033    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9034         (xor:SI (match_dup 1) (match_dup 2)))]
9035   "ix86_match_ccmode (insn, CCNOmode)
9036    && ix86_binary_operator_ok (XOR, SImode, operands)"
9037   "xor{l}\t{%2, %0|%0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9040
9041 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9042 ;; ??? Special case for immediate operand is missing - it is tricky.
9043 (define_insn "*xorsi_2_zext"
9044   [(set (reg 17)
9045         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046                          (match_operand:SI 2 "general_operand" "rim"))
9047                  (const_int 0)))
9048    (set (match_operand:DI 0 "register_operand" "=r")
9049         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9050   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (XOR, SImode, operands)"
9052   "xor{l}\t{%2, %k0|%k0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "SI")])
9055
9056 (define_insn "*xorsi_2_zext_imm"
9057   [(set (reg 17)
9058         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9060                  (const_int 0)))
9061    (set (match_operand:DI 0 "register_operand" "=r")
9062         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9063   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064    && ix86_binary_operator_ok (XOR, SImode, operands)"
9065   "xor{l}\t{%2, %k0|%k0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "SI")])
9068
9069 (define_insn "*xorsi_3"
9070   [(set (reg 17)
9071         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9072                          (match_operand:SI 2 "general_operand" "rim"))
9073                  (const_int 0)))
9074    (clobber (match_scratch:SI 0 "=r"))]
9075   "ix86_match_ccmode (insn, CCNOmode)
9076    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9077   "xor{l}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "SI")])
9080
9081 (define_expand "xorhi3"
9082   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9083         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9084                 (match_operand:HI 2 "general_operand" "")))
9085    (clobber (reg:CC FLAGS_REG))]
9086   "TARGET_HIMODE_MATH"
9087   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9088
9089 (define_insn "*xorhi_1"
9090   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9091         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9092                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "ix86_binary_operator_ok (XOR, HImode, operands)"
9095   "xor{w}\t{%2, %0|%0, %2}"
9096   [(set_attr "type" "alu")
9097    (set_attr "mode" "HI")])
9098
9099 (define_insn "*xorhi_2"
9100   [(set (reg 17)
9101         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9102                          (match_operand:HI 2 "general_operand" "rim,ri"))
9103                  (const_int 0)))
9104    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9105         (xor:HI (match_dup 1) (match_dup 2)))]
9106   "ix86_match_ccmode (insn, CCNOmode)
9107    && ix86_binary_operator_ok (XOR, HImode, operands)"
9108   "xor{w}\t{%2, %0|%0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "mode" "HI")])
9111
9112 (define_insn "*xorhi_3"
9113   [(set (reg 17)
9114         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9115                          (match_operand:HI 2 "general_operand" "rim"))
9116                  (const_int 0)))
9117    (clobber (match_scratch:HI 0 "=r"))]
9118   "ix86_match_ccmode (insn, CCNOmode)
9119    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9120   "xor{w}\t{%2, %0|%0, %2}"
9121   [(set_attr "type" "alu")
9122    (set_attr "mode" "HI")])
9123
9124 (define_expand "xorqi3"
9125   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9126         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9127                 (match_operand:QI 2 "general_operand" "")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "TARGET_QIMODE_MATH"
9130   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9131
9132 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9133 (define_insn "*xorqi_1"
9134   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9135         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9136                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "ix86_binary_operator_ok (XOR, QImode, operands)"
9139   "@
9140    xor{b}\t{%2, %0|%0, %2}
9141    xor{b}\t{%2, %0|%0, %2}
9142    xor{l}\t{%k2, %k0|%k0, %k2}"
9143   [(set_attr "type" "alu")
9144    (set_attr "mode" "QI,QI,SI")])
9145
9146 (define_insn "*xorqi_1_slp"
9147   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9148         (xor:QI (match_dup 0)
9149                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9150    (clobber (reg:CC FLAGS_REG))]
9151   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9152    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9153   "xor{b}\t{%1, %0|%0, %1}"
9154   [(set_attr "type" "alu1")
9155    (set_attr "mode" "QI")])
9156
9157 (define_insn "xorqi_ext_0"
9158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159                          (const_int 8)
9160                          (const_int 8))
9161         (xor:SI 
9162           (zero_extract:SI
9163             (match_operand 1 "ext_register_operand" "0")
9164             (const_int 8)
9165             (const_int 8))
9166           (match_operand 2 "const_int_operand" "n")))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9169   "xor{b}\t{%2, %h0|%h0, %2}"
9170   [(set_attr "type" "alu")
9171    (set_attr "length_immediate" "1")
9172    (set_attr "mode" "QI")])
9173
9174 (define_insn "*xorqi_ext_1"
9175   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9176                          (const_int 8)
9177                          (const_int 8))
9178         (xor:SI 
9179           (zero_extract:SI
9180             (match_operand 1 "ext_register_operand" "0")
9181             (const_int 8)
9182             (const_int 8))
9183           (zero_extend:SI
9184             (match_operand:QI 2 "general_operand" "Qm"))))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "!TARGET_64BIT
9187    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9188   "xor{b}\t{%2, %h0|%h0, %2}"
9189   [(set_attr "type" "alu")
9190    (set_attr "length_immediate" "0")
9191    (set_attr "mode" "QI")])
9192
9193 (define_insn "*xorqi_ext_1_rex64"
9194   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9195                          (const_int 8)
9196                          (const_int 8))
9197         (xor:SI 
9198           (zero_extract:SI
9199             (match_operand 1 "ext_register_operand" "0")
9200             (const_int 8)
9201             (const_int 8))
9202           (zero_extend:SI
9203             (match_operand 2 "ext_register_operand" "Q"))))
9204    (clobber (reg:CC FLAGS_REG))]
9205   "TARGET_64BIT
9206    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207   "xor{b}\t{%2, %h0|%h0, %2}"
9208   [(set_attr "type" "alu")
9209    (set_attr "length_immediate" "0")
9210    (set_attr "mode" "QI")])
9211
9212 (define_insn "*xorqi_ext_2"
9213   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9214                          (const_int 8)
9215                          (const_int 8))
9216         (xor:SI 
9217           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9218                            (const_int 8)
9219                            (const_int 8))
9220           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9221                            (const_int 8)
9222                            (const_int 8))))
9223    (clobber (reg:CC FLAGS_REG))]
9224   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9225   "xor{b}\t{%h2, %h0|%h0, %h2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "length_immediate" "0")
9228    (set_attr "mode" "QI")])
9229
9230 (define_insn "*xorqi_cc_1"
9231   [(set (reg 17)
9232         (compare
9233           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9234                   (match_operand:QI 2 "general_operand" "qim,qi"))
9235           (const_int 0)))
9236    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9237         (xor:QI (match_dup 1) (match_dup 2)))]
9238   "ix86_match_ccmode (insn, CCNOmode)
9239    && ix86_binary_operator_ok (XOR, QImode, operands)"
9240   "xor{b}\t{%2, %0|%0, %2}"
9241   [(set_attr "type" "alu")
9242    (set_attr "mode" "QI")])
9243
9244 (define_insn "*xorqi_2_slp"
9245   [(set (reg 17)
9246         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9247                          (match_operand:QI 1 "general_operand" "qim,qi"))
9248                  (const_int 0)))
9249    (set (strict_low_part (match_dup 0))
9250         (xor:QI (match_dup 0) (match_dup 1)))]
9251   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9252    && ix86_match_ccmode (insn, CCNOmode)
9253    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9254   "xor{b}\t{%1, %0|%0, %1}"
9255   [(set_attr "type" "alu1")
9256    (set_attr "mode" "QI")])
9257
9258 (define_insn "*xorqi_cc_2"
9259   [(set (reg 17)
9260         (compare
9261           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9262                   (match_operand:QI 2 "general_operand" "qim"))
9263           (const_int 0)))
9264    (clobber (match_scratch:QI 0 "=q"))]
9265   "ix86_match_ccmode (insn, CCNOmode)
9266    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9267   "xor{b}\t{%2, %0|%0, %2}"
9268   [(set_attr "type" "alu")
9269    (set_attr "mode" "QI")])
9270
9271 (define_insn "*xorqi_cc_ext_1"
9272   [(set (reg 17)
9273         (compare
9274           (xor:SI
9275             (zero_extract:SI
9276               (match_operand 1 "ext_register_operand" "0")
9277               (const_int 8)
9278               (const_int 8))
9279             (match_operand:QI 2 "general_operand" "qmn"))
9280           (const_int 0)))
9281    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9282                          (const_int 8)
9283                          (const_int 8))
9284         (xor:SI 
9285           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9286           (match_dup 2)))]
9287   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9288   "xor{b}\t{%2, %h0|%h0, %2}"
9289   [(set_attr "type" "alu")
9290    (set_attr "mode" "QI")])
9291
9292 (define_insn "*xorqi_cc_ext_1_rex64"
9293   [(set (reg 17)
9294         (compare
9295           (xor:SI
9296             (zero_extract:SI
9297               (match_operand 1 "ext_register_operand" "0")
9298               (const_int 8)
9299               (const_int 8))
9300             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9301           (const_int 0)))
9302    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9303                          (const_int 8)
9304                          (const_int 8))
9305         (xor:SI 
9306           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9307           (match_dup 2)))]
9308   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9309   "xor{b}\t{%2, %h0|%h0, %2}"
9310   [(set_attr "type" "alu")
9311    (set_attr "mode" "QI")])
9312
9313 (define_expand "xorqi_cc_ext_1"
9314   [(parallel [
9315      (set (reg:CCNO FLAGS_REG)
9316           (compare:CCNO
9317             (xor:SI
9318               (zero_extract:SI
9319                 (match_operand 1 "ext_register_operand" "")
9320                 (const_int 8)
9321                 (const_int 8))
9322               (match_operand:QI 2 "general_operand" ""))
9323             (const_int 0)))
9324      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9325                            (const_int 8)
9326                            (const_int 8))
9327           (xor:SI 
9328             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9329             (match_dup 2)))])]
9330   ""
9331   "")
9332
9333 (define_split
9334   [(set (match_operand 0 "register_operand" "")
9335         (xor (match_operand 1 "register_operand" "")
9336              (match_operand 2 "const_int_operand" "")))
9337    (clobber (reg:CC FLAGS_REG))]
9338    "reload_completed
9339     && QI_REG_P (operands[0])
9340     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9341     && !(INTVAL (operands[2]) & ~(255 << 8))
9342     && GET_MODE (operands[0]) != QImode"
9343   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9344                    (xor:SI (zero_extract:SI (match_dup 1)
9345                                             (const_int 8) (const_int 8))
9346                            (match_dup 2)))
9347               (clobber (reg:CC FLAGS_REG))])]
9348   "operands[0] = gen_lowpart (SImode, operands[0]);
9349    operands[1] = gen_lowpart (SImode, operands[1]);
9350    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9351
9352 ;; Since XOR can be encoded with sign extended immediate, this is only
9353 ;; profitable when 7th bit is set.
9354 (define_split
9355   [(set (match_operand 0 "register_operand" "")
9356         (xor (match_operand 1 "general_operand" "")
9357              (match_operand 2 "const_int_operand" "")))
9358    (clobber (reg:CC FLAGS_REG))]
9359    "reload_completed
9360     && ANY_QI_REG_P (operands[0])
9361     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9362     && !(INTVAL (operands[2]) & ~255)
9363     && (INTVAL (operands[2]) & 128)
9364     && GET_MODE (operands[0]) != QImode"
9365   [(parallel [(set (strict_low_part (match_dup 0))
9366                    (xor:QI (match_dup 1)
9367                            (match_dup 2)))
9368               (clobber (reg:CC FLAGS_REG))])]
9369   "operands[0] = gen_lowpart (QImode, operands[0]);
9370    operands[1] = gen_lowpart (QImode, operands[1]);
9371    operands[2] = gen_lowpart (QImode, operands[2]);")
9372 \f
9373 ;; Negation instructions
9374
9375 (define_expand "negdi2"
9376   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9377                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9378               (clobber (reg:CC FLAGS_REG))])]
9379   ""
9380   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9381
9382 (define_insn "*negdi2_1"
9383   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9384         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9385    (clobber (reg:CC FLAGS_REG))]
9386   "!TARGET_64BIT
9387    && ix86_unary_operator_ok (NEG, DImode, operands)"
9388   "#")
9389
9390 (define_split
9391   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9392         (neg:DI (match_operand:DI 1 "general_operand" "")))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "!TARGET_64BIT && reload_completed"
9395   [(parallel
9396     [(set (reg:CCZ FLAGS_REG)
9397           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9398      (set (match_dup 0) (neg:SI (match_dup 2)))])
9399    (parallel
9400     [(set (match_dup 1)
9401           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9402                             (match_dup 3))
9403                    (const_int 0)))
9404      (clobber (reg:CC FLAGS_REG))])
9405    (parallel
9406     [(set (match_dup 1)
9407           (neg:SI (match_dup 1)))
9408      (clobber (reg:CC FLAGS_REG))])]
9409   "split_di (operands+1, 1, operands+2, operands+3);
9410    split_di (operands+0, 1, operands+0, operands+1);")
9411
9412 (define_insn "*negdi2_1_rex64"
9413   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9414         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9415    (clobber (reg:CC FLAGS_REG))]
9416   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9417   "neg{q}\t%0"
9418   [(set_attr "type" "negnot")
9419    (set_attr "mode" "DI")])
9420
9421 ;; The problem with neg is that it does not perform (compare x 0),
9422 ;; it really performs (compare 0 x), which leaves us with the zero
9423 ;; flag being the only useful item.
9424
9425 (define_insn "*negdi2_cmpz_rex64"
9426   [(set (reg:CCZ FLAGS_REG)
9427         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9428                      (const_int 0)))
9429    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9430         (neg:DI (match_dup 1)))]
9431   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9432   "neg{q}\t%0"
9433   [(set_attr "type" "negnot")
9434    (set_attr "mode" "DI")])
9435
9436
9437 (define_expand "negsi2"
9438   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9439                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9440               (clobber (reg:CC FLAGS_REG))])]
9441   ""
9442   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9443
9444 (define_insn "*negsi2_1"
9445   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9446         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9447    (clobber (reg:CC FLAGS_REG))]
9448   "ix86_unary_operator_ok (NEG, SImode, operands)"
9449   "neg{l}\t%0"
9450   [(set_attr "type" "negnot")
9451    (set_attr "mode" "SI")])
9452
9453 ;; Combine is quite creative about this pattern.
9454 (define_insn "*negsi2_1_zext"
9455   [(set (match_operand:DI 0 "register_operand" "=r")
9456         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9457                                         (const_int 32)))
9458                      (const_int 32)))
9459    (clobber (reg:CC FLAGS_REG))]
9460   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9461   "neg{l}\t%k0"
9462   [(set_attr "type" "negnot")
9463    (set_attr "mode" "SI")])
9464
9465 ;; The problem with neg is that it does not perform (compare x 0),
9466 ;; it really performs (compare 0 x), which leaves us with the zero
9467 ;; flag being the only useful item.
9468
9469 (define_insn "*negsi2_cmpz"
9470   [(set (reg:CCZ FLAGS_REG)
9471         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9472                      (const_int 0)))
9473    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9474         (neg:SI (match_dup 1)))]
9475   "ix86_unary_operator_ok (NEG, SImode, operands)"
9476   "neg{l}\t%0"
9477   [(set_attr "type" "negnot")
9478    (set_attr "mode" "SI")])
9479
9480 (define_insn "*negsi2_cmpz_zext"
9481   [(set (reg:CCZ FLAGS_REG)
9482         (compare:CCZ (lshiftrt:DI
9483                        (neg:DI (ashift:DI
9484                                  (match_operand:DI 1 "register_operand" "0")
9485                                  (const_int 32)))
9486                        (const_int 32))
9487                      (const_int 0)))
9488    (set (match_operand:DI 0 "register_operand" "=r")
9489         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9490                                         (const_int 32)))
9491                      (const_int 32)))]
9492   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9493   "neg{l}\t%k0"
9494   [(set_attr "type" "negnot")
9495    (set_attr "mode" "SI")])
9496
9497 (define_expand "neghi2"
9498   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9499                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9500               (clobber (reg:CC FLAGS_REG))])]
9501   "TARGET_HIMODE_MATH"
9502   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9503
9504 (define_insn "*neghi2_1"
9505   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9506         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9507    (clobber (reg:CC FLAGS_REG))]
9508   "ix86_unary_operator_ok (NEG, HImode, operands)"
9509   "neg{w}\t%0"
9510   [(set_attr "type" "negnot")
9511    (set_attr "mode" "HI")])
9512
9513 (define_insn "*neghi2_cmpz"
9514   [(set (reg:CCZ FLAGS_REG)
9515         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9516                      (const_int 0)))
9517    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9518         (neg:HI (match_dup 1)))]
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_expand "negqi2"
9525   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9526                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9527               (clobber (reg:CC FLAGS_REG))])]
9528   "TARGET_QIMODE_MATH"
9529   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9530
9531 (define_insn "*negqi2_1"
9532   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9533         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9534    (clobber (reg:CC FLAGS_REG))]
9535   "ix86_unary_operator_ok (NEG, QImode, operands)"
9536   "neg{b}\t%0"
9537   [(set_attr "type" "negnot")
9538    (set_attr "mode" "QI")])
9539
9540 (define_insn "*negqi2_cmpz"
9541   [(set (reg:CCZ FLAGS_REG)
9542         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9543                      (const_int 0)))
9544    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9545         (neg:QI (match_dup 1)))]
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 ;; Changing of sign for FP values is doable using integer unit too.
9552
9553 (define_expand "negsf2"
9554   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9555                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9556               (clobber (reg:CC FLAGS_REG))])]
9557   "TARGET_80387"
9558   "if (TARGET_SSE)
9559      {
9560        /* In case operand is in memory,  we will not use SSE.  */
9561        if (memory_operand (operands[0], VOIDmode)
9562            && rtx_equal_p (operands[0], operands[1]))
9563          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9564        else
9565         {
9566           /* Using SSE is tricky, since we need bitwise negation of -0
9567              in register.  */
9568           rtx reg = gen_reg_rtx (SFmode);
9569           rtx dest = operands[0];
9570           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9571
9572           operands[1] = force_reg (SFmode, operands[1]);
9573           operands[0] = force_reg (SFmode, operands[0]);
9574           reg = force_reg (V4SFmode,
9575                            gen_rtx_CONST_VECTOR (V4SFmode,
9576                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9577                                         CONST0_RTX (SFmode),
9578                                         CONST0_RTX (SFmode))));
9579           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9580           if (dest != operands[0])
9581             emit_move_insn (dest, operands[0]);
9582         }
9583        DONE;
9584      }
9585    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9586
9587 (define_insn "negsf2_memory"
9588   [(set (match_operand:SF 0 "memory_operand" "=m")
9589         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9590    (clobber (reg:CC FLAGS_REG))]
9591   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9592   "#")
9593
9594 (define_insn "negsf2_ifs"
9595   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9596         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9597    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9598    (clobber (reg:CC FLAGS_REG))]
9599   "TARGET_SSE
9600    && (reload_in_progress || reload_completed
9601        || (register_operand (operands[0], VOIDmode)
9602            && register_operand (operands[1], VOIDmode)))"
9603   "#")
9604
9605 (define_split
9606   [(set (match_operand:SF 0 "memory_operand" "")
9607         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9608    (use (match_operand:SF 2 "" ""))
9609    (clobber (reg:CC FLAGS_REG))]
9610   ""
9611   [(parallel [(set (match_dup 0)
9612                    (neg:SF (match_dup 1)))
9613               (clobber (reg:CC FLAGS_REG))])])
9614
9615 (define_split
9616   [(set (match_operand:SF 0 "register_operand" "")
9617         (neg:SF (match_operand:SF 1 "register_operand" "")))
9618    (use (match_operand:V4SF 2 "" ""))
9619    (clobber (reg:CC FLAGS_REG))]
9620   "reload_completed && !SSE_REG_P (operands[0])"
9621   [(parallel [(set (match_dup 0)
9622                    (neg:SF (match_dup 1)))
9623               (clobber (reg:CC FLAGS_REG))])])
9624
9625 (define_split
9626   [(set (match_operand:SF 0 "register_operand" "")
9627         (neg:SF (match_operand:SF 1 "register_operand" "")))
9628    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9629    (clobber (reg:CC FLAGS_REG))]
9630   "reload_completed && SSE_REG_P (operands[0])"
9631   [(set (match_dup 0)
9632         (xor:V4SF (match_dup 1)
9633                   (match_dup 2)))]
9634 {
9635   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9636   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9637   if (operands_match_p (operands[0], operands[2]))
9638     {
9639       rtx tmp;
9640       tmp = operands[1];
9641       operands[1] = operands[2];
9642       operands[2] = tmp;
9643     }
9644 })
9645
9646
9647 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9648 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9649 ;; to itself.
9650 (define_insn "*negsf2_if"
9651   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9652         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9653    (clobber (reg:CC FLAGS_REG))]
9654   "TARGET_80387 && !TARGET_SSE
9655    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9656   "#")
9657
9658 (define_split
9659   [(set (match_operand:SF 0 "fp_register_operand" "")
9660         (neg:SF (match_operand:SF 1 "register_operand" "")))
9661    (clobber (reg:CC FLAGS_REG))]
9662   "TARGET_80387 && reload_completed"
9663   [(set (match_dup 0)
9664         (neg:SF (match_dup 1)))]
9665   "")
9666
9667 (define_split
9668   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9669         (neg:SF (match_operand:SF 1 "register_operand" "")))
9670    (clobber (reg:CC FLAGS_REG))]
9671   "TARGET_80387 && reload_completed"
9672   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9673               (clobber (reg:CC FLAGS_REG))])]
9674   "operands[1] = gen_int_mode (0x80000000, SImode);
9675    operands[0] = gen_lowpart (SImode, operands[0]);")
9676
9677 (define_split
9678   [(set (match_operand 0 "memory_operand" "")
9679         (neg (match_operand 1 "memory_operand" "")))
9680    (clobber (reg:CC FLAGS_REG))]
9681   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9682   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9683               (clobber (reg:CC FLAGS_REG))])]
9684 {
9685   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9686
9687   if (GET_MODE (operands[1]) == XFmode)
9688     size = 10;
9689   operands[0] = adjust_address (operands[0], QImode, size - 1);
9690   operands[1] = gen_int_mode (0x80, QImode);
9691 })
9692
9693 (define_expand "negdf2"
9694   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9695                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9696               (clobber (reg:CC FLAGS_REG))])]
9697   "TARGET_80387"
9698   "if (TARGET_SSE2)
9699      {
9700        /* In case operand is in memory,  we will not use SSE.  */
9701        if (memory_operand (operands[0], VOIDmode)
9702            && rtx_equal_p (operands[0], operands[1]))
9703          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9704        else
9705         {
9706           /* Using SSE is tricky, since we need bitwise negation of -0
9707              in register.  */
9708           rtx reg;
9709 #if HOST_BITS_PER_WIDE_INT >= 64
9710           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9711 #else
9712           rtx imm = immed_double_const (0, 0x80000000, DImode);
9713 #endif
9714           rtx dest = operands[0];
9715
9716           operands[1] = force_reg (DFmode, operands[1]);
9717           operands[0] = force_reg (DFmode, operands[0]);
9718           imm = gen_lowpart (DFmode, imm);
9719           reg = force_reg (V2DFmode,
9720                            gen_rtx_CONST_VECTOR (V2DFmode,
9721                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9722           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9723           if (dest != operands[0])
9724             emit_move_insn (dest, operands[0]);
9725         }
9726        DONE;
9727      }
9728    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9729
9730 (define_insn "negdf2_memory"
9731   [(set (match_operand:DF 0 "memory_operand" "=m")
9732         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9733    (clobber (reg:CC FLAGS_REG))]
9734   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9735   "#")
9736
9737 (define_insn "negdf2_ifs"
9738   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9739         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9740    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9741    (clobber (reg:CC FLAGS_REG))]
9742   "!TARGET_64BIT && TARGET_SSE2
9743    && (reload_in_progress || reload_completed
9744        || (register_operand (operands[0], VOIDmode)
9745            && register_operand (operands[1], VOIDmode)))"
9746   "#")
9747
9748 (define_insn "*negdf2_ifs_rex64"
9749   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9750         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9751    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,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_split
9760   [(set (match_operand:DF 0 "memory_operand" "")
9761         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9762    (use (match_operand:V2DF 2 "" ""))
9763    (clobber (reg:CC FLAGS_REG))]
9764   ""
9765   [(parallel [(set (match_dup 0)
9766                    (neg:DF (match_dup 1)))
9767               (clobber (reg:CC FLAGS_REG))])])
9768
9769 (define_split
9770   [(set (match_operand:DF 0 "register_operand" "")
9771         (neg:DF (match_operand:DF 1 "register_operand" "")))
9772    (use (match_operand:V2DF 2 "" ""))
9773    (clobber (reg:CC FLAGS_REG))]
9774   "reload_completed && !SSE_REG_P (operands[0])
9775    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
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   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9786   [(parallel [(set (match_dup 0)
9787                    (xor:DI (match_dup 1) (match_dup 2)))
9788               (clobber (reg:CC FLAGS_REG))])]
9789    "operands[0] = gen_lowpart (DImode, operands[0]);
9790     operands[1] = gen_lowpart (DImode, operands[1]);
9791     operands[2] = gen_lowpart (DImode, operands[2]);")
9792
9793 (define_split
9794   [(set (match_operand:DF 0 "register_operand" "")
9795         (neg:DF (match_operand:DF 1 "register_operand" "")))
9796    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "reload_completed && SSE_REG_P (operands[0])"
9799   [(set (match_dup 0)
9800         (xor:V2DF (match_dup 1)
9801                   (match_dup 2)))]
9802 {
9803   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9804   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9805   /* Avoid possible reformatting on the operands.  */
9806   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9807     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9808   if (operands_match_p (operands[0], operands[2]))
9809     {
9810       rtx tmp;
9811       tmp = operands[1];
9812       operands[1] = operands[2];
9813       operands[2] = tmp;
9814     }
9815 })
9816
9817 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9818 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9819 ;; to itself.
9820 (define_insn "*negdf2_if"
9821   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9822         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9823    (clobber (reg:CC FLAGS_REG))]
9824   "!TARGET_64BIT && TARGET_80387
9825    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9826   "#")
9827
9828 ;; FIXME: We should to allow integer registers here.  Problem is that
9829 ;; we need another scratch register to get constant from.
9830 ;; Forcing constant to mem if no register available in peep2 should be
9831 ;; safe even for PIC mode, because of RIP relative addressing.
9832 (define_insn "*negdf2_if_rex64"
9833   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9834         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9835    (clobber (reg:CC FLAGS_REG))]
9836   "TARGET_64BIT && TARGET_80387
9837    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9838   "#")
9839
9840 (define_split
9841   [(set (match_operand:DF 0 "fp_register_operand" "")
9842         (neg:DF (match_operand:DF 1 "register_operand" "")))
9843    (clobber (reg:CC FLAGS_REG))]
9844   "TARGET_80387 && reload_completed"
9845   [(set (match_dup 0)
9846         (neg:DF (match_dup 1)))]
9847   "")
9848
9849 (define_split
9850   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9851         (neg:DF (match_operand:DF 1 "register_operand" "")))
9852    (clobber (reg:CC FLAGS_REG))]
9853   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9854   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9855               (clobber (reg:CC FLAGS_REG))])]
9856   "operands[4] = gen_int_mode (0x80000000, SImode);
9857    split_di (operands+0, 1, operands+2, operands+3);")
9858
9859 (define_expand "negxf2"
9860   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9861                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9862               (clobber (reg:CC FLAGS_REG))])]
9863   "TARGET_80387"
9864   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9865
9866 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9867 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9868 ;; to itself.
9869 (define_insn "*negxf2_if"
9870   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9871         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9872    (clobber (reg:CC FLAGS_REG))]
9873   "TARGET_80387
9874    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9875   "#")
9876
9877 (define_split
9878   [(set (match_operand:XF 0 "fp_register_operand" "")
9879         (neg:XF (match_operand:XF 1 "register_operand" "")))
9880    (clobber (reg:CC FLAGS_REG))]
9881   "TARGET_80387 && reload_completed"
9882   [(set (match_dup 0)
9883         (neg:XF (match_dup 1)))]
9884   "")
9885
9886 (define_split
9887   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9888         (neg:XF (match_operand:XF 1 "register_operand" "")))
9889    (clobber (reg:CC FLAGS_REG))]
9890   "TARGET_80387 && reload_completed"
9891   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9892               (clobber (reg:CC FLAGS_REG))])]
9893   "operands[1] = GEN_INT (0x8000);
9894    operands[0] = gen_rtx_REG (SImode,
9895                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9896
9897 ;; Conditionalize these after reload. If they matches before reload, we 
9898 ;; lose the clobber and ability to use integer instructions.
9899
9900 (define_insn "*negsf2_1"
9901   [(set (match_operand:SF 0 "register_operand" "=f")
9902         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9903   "TARGET_80387 && reload_completed"
9904   "fchs"
9905   [(set_attr "type" "fsgn")
9906    (set_attr "mode" "SF")])
9907
9908 (define_insn "*negdf2_1"
9909   [(set (match_operand:DF 0 "register_operand" "=f")
9910         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9911   "TARGET_80387 && reload_completed"
9912   "fchs"
9913   [(set_attr "type" "fsgn")
9914    (set_attr "mode" "DF")])
9915
9916 (define_insn "*negextendsfdf2"
9917   [(set (match_operand:DF 0 "register_operand" "=f")
9918         (neg:DF (float_extend:DF
9919                   (match_operand:SF 1 "register_operand" "0"))))]
9920   "TARGET_80387"
9921   "fchs"
9922   [(set_attr "type" "fsgn")
9923    (set_attr "mode" "DF")])
9924
9925 (define_insn "*negxf2_1"
9926   [(set (match_operand:XF 0 "register_operand" "=f")
9927         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9928   "TARGET_80387 && reload_completed"
9929   "fchs"
9930   [(set_attr "type" "fsgn")
9931    (set_attr "mode" "XF")])
9932
9933 (define_insn "*negextenddfxf2"
9934   [(set (match_operand:XF 0 "register_operand" "=f")
9935         (neg:XF (float_extend:XF
9936                   (match_operand:DF 1 "register_operand" "0"))))]
9937   "TARGET_80387"
9938   "fchs"
9939   [(set_attr "type" "fsgn")
9940    (set_attr "mode" "XF")])
9941
9942 (define_insn "*negextendsfxf2"
9943   [(set (match_operand:XF 0 "register_operand" "=f")
9944         (neg:XF (float_extend:XF
9945                   (match_operand:SF 1 "register_operand" "0"))))]
9946   "TARGET_80387"
9947   "fchs"
9948   [(set_attr "type" "fsgn")
9949    (set_attr "mode" "XF")])
9950 \f
9951 ;; Absolute value instructions
9952
9953 (define_expand "abssf2"
9954   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9955                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9956               (clobber (reg:CC FLAGS_REG))])]
9957   "TARGET_80387"
9958   "if (TARGET_SSE)
9959      {
9960        /* In case operand is in memory,  we will not use SSE.  */
9961        if (memory_operand (operands[0], VOIDmode)
9962            && rtx_equal_p (operands[0], operands[1]))
9963          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9964        else
9965         {
9966           /* Using SSE is tricky, since we need bitwise negation of -0
9967              in register.  */
9968           rtx reg = gen_reg_rtx (V4SFmode);
9969           rtx dest = operands[0];
9970           rtx imm;
9971
9972           operands[1] = force_reg (SFmode, operands[1]);
9973           operands[0] = force_reg (SFmode, operands[0]);
9974           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9975           reg = force_reg (V4SFmode,
9976                            gen_rtx_CONST_VECTOR (V4SFmode,
9977                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
9978                                       CONST0_RTX (SFmode),
9979                                       CONST0_RTX (SFmode))));
9980           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9981           if (dest != operands[0])
9982             emit_move_insn (dest, operands[0]);
9983         }
9984        DONE;
9985      }
9986    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9987
9988 (define_insn "abssf2_memory"
9989   [(set (match_operand:SF 0 "memory_operand" "=m")
9990         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9991    (clobber (reg:CC FLAGS_REG))]
9992   "ix86_unary_operator_ok (ABS, SFmode, operands)"
9993   "#")
9994
9995 (define_insn "abssf2_ifs"
9996   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9997         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9998    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9999    (clobber (reg:CC FLAGS_REG))]
10000   "TARGET_SSE
10001    && (reload_in_progress || reload_completed
10002        || (register_operand (operands[0], VOIDmode)
10003             && register_operand (operands[1], VOIDmode)))"
10004   "#")
10005
10006 (define_split
10007   [(set (match_operand:SF 0 "memory_operand" "")
10008         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10009    (use (match_operand:V4SF 2 "" ""))
10010    (clobber (reg:CC FLAGS_REG))]
10011   ""
10012   [(parallel [(set (match_dup 0)
10013                    (abs:SF (match_dup 1)))
10014               (clobber (reg:CC FLAGS_REG))])])
10015
10016 (define_split
10017   [(set (match_operand:SF 0 "register_operand" "")
10018         (abs:SF (match_operand:SF 1 "register_operand" "")))
10019    (use (match_operand:V4SF 2 "" ""))
10020    (clobber (reg:CC FLAGS_REG))]
10021   "reload_completed && !SSE_REG_P (operands[0])"
10022   [(parallel [(set (match_dup 0)
10023                    (abs:SF (match_dup 1)))
10024               (clobber (reg:CC FLAGS_REG))])])
10025
10026 (define_split
10027   [(set (match_operand:SF 0 "register_operand" "")
10028         (abs:SF (match_operand:SF 1 "register_operand" "")))
10029    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10030    (clobber (reg:CC FLAGS_REG))]
10031   "reload_completed && SSE_REG_P (operands[0])"
10032   [(set (match_dup 0)
10033         (and:V4SF (match_dup 1)
10034                   (match_dup 2)))]
10035 {
10036   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10037   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10038   if (operands_match_p (operands[0], operands[2]))
10039     {
10040       rtx tmp;
10041       tmp = operands[1];
10042       operands[1] = operands[2];
10043       operands[2] = tmp;
10044     }
10045 })
10046
10047 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10048 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10049 ;; to itself.
10050 (define_insn "*abssf2_if"
10051   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10052         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10053    (clobber (reg:CC FLAGS_REG))]
10054   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10055   "#")
10056
10057 (define_split
10058   [(set (match_operand:SF 0 "fp_register_operand" "")
10059         (abs:SF (match_operand:SF 1 "register_operand" "")))
10060    (clobber (reg:CC FLAGS_REG))]
10061   "TARGET_80387 && reload_completed"
10062   [(set (match_dup 0)
10063         (abs:SF (match_dup 1)))]
10064   "")
10065
10066 (define_split
10067   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10068         (abs:SF (match_operand:SF 1 "register_operand" "")))
10069    (clobber (reg:CC FLAGS_REG))]
10070   "TARGET_80387 && reload_completed"
10071   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10072               (clobber (reg:CC FLAGS_REG))])]
10073   "operands[1] = gen_int_mode (~0x80000000, SImode);
10074    operands[0] = gen_lowpart (SImode, operands[0]);")
10075
10076 (define_split
10077   [(set (match_operand 0 "memory_operand" "")
10078         (abs (match_operand 1 "memory_operand" "")))
10079    (clobber (reg:CC FLAGS_REG))]
10080   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10081   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10082               (clobber (reg:CC FLAGS_REG))])]
10083 {
10084   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10085
10086   if (GET_MODE (operands[1]) == XFmode)
10087     size = 10;
10088   operands[0] = adjust_address (operands[0], QImode, size - 1);
10089   operands[1] = gen_int_mode (~0x80, QImode);
10090 })
10091
10092 (define_expand "absdf2"
10093   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10094                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10095               (clobber (reg:CC FLAGS_REG))])]
10096   "TARGET_80387"
10097   "if (TARGET_SSE2)
10098      {
10099        /* In case operand is in memory,  we will not use SSE.  */
10100        if (memory_operand (operands[0], VOIDmode)
10101            && rtx_equal_p (operands[0], operands[1]))
10102          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10103        else
10104         {
10105           /* Using SSE is tricky, since we need bitwise negation of -0
10106              in register.  */
10107           rtx reg = gen_reg_rtx (V2DFmode);
10108 #if HOST_BITS_PER_WIDE_INT >= 64
10109           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10110 #else
10111           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10112 #endif
10113           rtx dest = operands[0];
10114
10115           operands[1] = force_reg (DFmode, operands[1]);
10116           operands[0] = force_reg (DFmode, operands[0]);
10117
10118           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10119           imm = gen_lowpart (DFmode, imm);
10120           reg = force_reg (V2DFmode,
10121                            gen_rtx_CONST_VECTOR (V2DFmode,
10122                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10123           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10124           if (dest != operands[0])
10125             emit_move_insn (dest, operands[0]);
10126         }
10127        DONE;
10128      }
10129    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10130
10131 (define_insn "absdf2_memory"
10132   [(set (match_operand:DF 0 "memory_operand" "=m")
10133         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10134    (clobber (reg:CC FLAGS_REG))]
10135   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10136   "#")
10137
10138 (define_insn "absdf2_ifs"
10139   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10140         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10141    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10142    (clobber (reg:CC FLAGS_REG))]
10143   "!TARGET_64BIT && TARGET_SSE2
10144    && (reload_in_progress || reload_completed
10145        || (register_operand (operands[0], VOIDmode)
10146            && register_operand (operands[1], VOIDmode)))"
10147   "#")
10148
10149 (define_insn "*absdf2_ifs_rex64"
10150   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10151         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10152    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,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_split
10161   [(set (match_operand:DF 0 "memory_operand" "")
10162         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10163    (use (match_operand:V2DF 2 "" ""))
10164    (clobber (reg:CC FLAGS_REG))]
10165   ""
10166   [(parallel [(set (match_dup 0)
10167                    (abs:DF (match_dup 1)))
10168               (clobber (reg:CC FLAGS_REG))])])
10169
10170 (define_split
10171   [(set (match_operand:DF 0 "register_operand" "")
10172         (abs:DF (match_operand:DF 1 "register_operand" "")))
10173    (use (match_operand:V2DF 2 "" ""))
10174    (clobber (reg:CC FLAGS_REG))]
10175   "reload_completed && !SSE_REG_P (operands[0])"
10176   [(parallel [(set (match_dup 0)
10177                    (abs:DF (match_dup 1)))
10178               (clobber (reg:CC FLAGS_REG))])])
10179
10180 (define_split
10181   [(set (match_operand:DF 0 "register_operand" "")
10182         (abs:DF (match_operand:DF 1 "register_operand" "")))
10183    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10184    (clobber (reg:CC FLAGS_REG))]
10185   "reload_completed && SSE_REG_P (operands[0])"
10186   [(set (match_dup 0)
10187         (and:V2DF (match_dup 1)
10188                   (match_dup 2)))]
10189 {
10190   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10191   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10192   /* Avoid possible reformatting on the operands.  */
10193   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10194     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10195   if (operands_match_p (operands[0], operands[2]))
10196     {
10197       rtx tmp;
10198       tmp = operands[1];
10199       operands[1] = operands[2];
10200       operands[2] = tmp;
10201     }
10202 })
10203
10204
10205 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10206 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10207 ;; to itself.
10208 (define_insn "*absdf2_if"
10209   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10210         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10211    (clobber (reg:CC FLAGS_REG))]
10212   "!TARGET_64BIT && TARGET_80387
10213    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10214   "#")
10215
10216 ;; FIXME: We should to allow integer registers here.  Problem is that
10217 ;; we need another scratch register to get constant from.
10218 ;; Forcing constant to mem if no register available in peep2 should be
10219 ;; safe even for PIC mode, because of RIP relative addressing.
10220 (define_insn "*absdf2_if_rex64"
10221   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10222         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "TARGET_64BIT && TARGET_80387
10225    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10226   "#")
10227
10228 (define_split
10229   [(set (match_operand:DF 0 "fp_register_operand" "")
10230         (abs:DF (match_operand:DF 1 "register_operand" "")))
10231    (clobber (reg:CC FLAGS_REG))]
10232   "TARGET_80387 && reload_completed"
10233   [(set (match_dup 0)
10234         (abs:DF (match_dup 1)))]
10235   "")
10236
10237 (define_split
10238   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10239         (abs:DF (match_operand:DF 1 "register_operand" "")))
10240    (clobber (reg:CC FLAGS_REG))]
10241   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10242   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10243               (clobber (reg:CC FLAGS_REG))])]
10244   "operands[4] = gen_int_mode (~0x80000000, SImode);
10245    split_di (operands+0, 1, operands+2, operands+3);")
10246
10247 (define_expand "absxf2"
10248   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10249                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10250               (clobber (reg:CC FLAGS_REG))])]
10251   "TARGET_80387"
10252   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10253
10254 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10255 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10256 ;; to itself.
10257 (define_insn "*absxf2_if"
10258   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10259         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10260    (clobber (reg:CC FLAGS_REG))]
10261   "TARGET_80387
10262    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10263   "#")
10264
10265 (define_split
10266   [(set (match_operand:XF 0 "fp_register_operand" "")
10267         (abs:XF (match_operand:XF 1 "register_operand" "")))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "TARGET_80387 && reload_completed"
10270   [(set (match_dup 0)
10271         (abs:XF (match_dup 1)))]
10272   "")
10273
10274 (define_split
10275   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10276         (abs:XF (match_operand:XF 1 "register_operand" "")))
10277    (clobber (reg:CC FLAGS_REG))]
10278   "TARGET_80387 && reload_completed"
10279   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10280               (clobber (reg:CC FLAGS_REG))])]
10281   "operands[1] = GEN_INT (~0x8000);
10282    operands[0] = gen_rtx_REG (SImode,
10283                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10284
10285 (define_insn "*abssf2_1"
10286   [(set (match_operand:SF 0 "register_operand" "=f")
10287         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10288   "TARGET_80387 && reload_completed"
10289   "fabs"
10290   [(set_attr "type" "fsgn")
10291    (set_attr "mode" "SF")])
10292
10293 (define_insn "*absdf2_1"
10294   [(set (match_operand:DF 0 "register_operand" "=f")
10295         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10296   "TARGET_80387 && reload_completed"
10297   "fabs"
10298   [(set_attr "type" "fsgn")
10299    (set_attr "mode" "DF")])
10300
10301 (define_insn "*absextendsfdf2"
10302   [(set (match_operand:DF 0 "register_operand" "=f")
10303         (abs:DF (float_extend:DF
10304                   (match_operand:SF 1 "register_operand" "0"))))]
10305   "TARGET_80387"
10306   "fabs"
10307   [(set_attr "type" "fsgn")
10308    (set_attr "mode" "DF")])
10309
10310 (define_insn "*absxf2_1"
10311   [(set (match_operand:XF 0 "register_operand" "=f")
10312         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10313   "TARGET_80387 && reload_completed"
10314   "fabs"
10315   [(set_attr "type" "fsgn")
10316    (set_attr "mode" "DF")])
10317
10318 (define_insn "*absextenddfxf2"
10319   [(set (match_operand:XF 0 "register_operand" "=f")
10320         (abs:XF (float_extend:XF
10321           (match_operand:DF 1 "register_operand" "0"))))]
10322   "TARGET_80387"
10323   "fabs"
10324   [(set_attr "type" "fsgn")
10325    (set_attr "mode" "XF")])
10326
10327 (define_insn "*absextendsfxf2"
10328   [(set (match_operand:XF 0 "register_operand" "=f")
10329         (abs:XF (float_extend:XF
10330           (match_operand:SF 1 "register_operand" "0"))))]
10331   "TARGET_80387"
10332   "fabs"
10333   [(set_attr "type" "fsgn")
10334    (set_attr "mode" "XF")])
10335 \f
10336 ;; One complement instructions
10337
10338 (define_expand "one_cmpldi2"
10339   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10340         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10341   "TARGET_64BIT"
10342   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10343
10344 (define_insn "*one_cmpldi2_1_rex64"
10345   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10346         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10347   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10348   "not{q}\t%0"
10349   [(set_attr "type" "negnot")
10350    (set_attr "mode" "DI")])
10351
10352 (define_insn "*one_cmpldi2_2_rex64"
10353   [(set (reg 17)
10354         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10355                  (const_int 0)))
10356    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10357         (not:DI (match_dup 1)))]
10358   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10359    && ix86_unary_operator_ok (NOT, DImode, operands)"
10360   "#"
10361   [(set_attr "type" "alu1")
10362    (set_attr "mode" "DI")])
10363
10364 (define_split
10365   [(set (reg 17)
10366         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10367                  (const_int 0)))
10368    (set (match_operand:DI 0 "nonimmediate_operand" "")
10369         (not:DI (match_dup 1)))]
10370   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10371   [(parallel [(set (reg:CCNO FLAGS_REG)
10372                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10373                                  (const_int 0)))
10374               (set (match_dup 0)
10375                    (xor:DI (match_dup 1) (const_int -1)))])]
10376   "")
10377
10378 (define_expand "one_cmplsi2"
10379   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10380         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10381   ""
10382   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10383
10384 (define_insn "*one_cmplsi2_1"
10385   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10386         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10387   "ix86_unary_operator_ok (NOT, SImode, operands)"
10388   "not{l}\t%0"
10389   [(set_attr "type" "negnot")
10390    (set_attr "mode" "SI")])
10391
10392 ;; ??? Currently never generated - xor is used instead.
10393 (define_insn "*one_cmplsi2_1_zext"
10394   [(set (match_operand:DI 0 "register_operand" "=r")
10395         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10396   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10397   "not{l}\t%k0"
10398   [(set_attr "type" "negnot")
10399    (set_attr "mode" "SI")])
10400
10401 (define_insn "*one_cmplsi2_2"
10402   [(set (reg 17)
10403         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10404                  (const_int 0)))
10405    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10406         (not:SI (match_dup 1)))]
10407   "ix86_match_ccmode (insn, CCNOmode)
10408    && ix86_unary_operator_ok (NOT, SImode, operands)"
10409   "#"
10410   [(set_attr "type" "alu1")
10411    (set_attr "mode" "SI")])
10412
10413 (define_split
10414   [(set (reg 17)
10415         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10416                  (const_int 0)))
10417    (set (match_operand:SI 0 "nonimmediate_operand" "")
10418         (not:SI (match_dup 1)))]
10419   "ix86_match_ccmode (insn, CCNOmode)"
10420   [(parallel [(set (reg:CCNO FLAGS_REG)
10421                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10422                                  (const_int 0)))
10423               (set (match_dup 0)
10424                    (xor:SI (match_dup 1) (const_int -1)))])]
10425   "")
10426
10427 ;; ??? Currently never generated - xor is used instead.
10428 (define_insn "*one_cmplsi2_2_zext"
10429   [(set (reg 17)
10430         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10431                  (const_int 0)))
10432    (set (match_operand:DI 0 "register_operand" "=r")
10433         (zero_extend:DI (not:SI (match_dup 1))))]
10434   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10435    && ix86_unary_operator_ok (NOT, SImode, operands)"
10436   "#"
10437   [(set_attr "type" "alu1")
10438    (set_attr "mode" "SI")])
10439
10440 (define_split
10441   [(set (reg 17)
10442         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10443                  (const_int 0)))
10444    (set (match_operand:DI 0 "register_operand" "")
10445         (zero_extend:DI (not:SI (match_dup 1))))]
10446   "ix86_match_ccmode (insn, CCNOmode)"
10447   [(parallel [(set (reg:CCNO FLAGS_REG)
10448                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10449                                  (const_int 0)))
10450               (set (match_dup 0)
10451                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10452   "")
10453
10454 (define_expand "one_cmplhi2"
10455   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10456         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10457   "TARGET_HIMODE_MATH"
10458   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10459
10460 (define_insn "*one_cmplhi2_1"
10461   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10462         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10463   "ix86_unary_operator_ok (NOT, HImode, operands)"
10464   "not{w}\t%0"
10465   [(set_attr "type" "negnot")
10466    (set_attr "mode" "HI")])
10467
10468 (define_insn "*one_cmplhi2_2"
10469   [(set (reg 17)
10470         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10471                  (const_int 0)))
10472    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10473         (not:HI (match_dup 1)))]
10474   "ix86_match_ccmode (insn, CCNOmode)
10475    && ix86_unary_operator_ok (NEG, HImode, operands)"
10476   "#"
10477   [(set_attr "type" "alu1")
10478    (set_attr "mode" "HI")])
10479
10480 (define_split
10481   [(set (reg 17)
10482         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10483                  (const_int 0)))
10484    (set (match_operand:HI 0 "nonimmediate_operand" "")
10485         (not:HI (match_dup 1)))]
10486   "ix86_match_ccmode (insn, CCNOmode)"
10487   [(parallel [(set (reg:CCNO FLAGS_REG)
10488                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10489                                  (const_int 0)))
10490               (set (match_dup 0)
10491                    (xor:HI (match_dup 1) (const_int -1)))])]
10492   "")
10493
10494 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10495 (define_expand "one_cmplqi2"
10496   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10497         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10498   "TARGET_QIMODE_MATH"
10499   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10500
10501 (define_insn "*one_cmplqi2_1"
10502   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10503         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10504   "ix86_unary_operator_ok (NOT, QImode, operands)"
10505   "@
10506    not{b}\t%0
10507    not{l}\t%k0"
10508   [(set_attr "type" "negnot")
10509    (set_attr "mode" "QI,SI")])
10510
10511 (define_insn "*one_cmplqi2_2"
10512   [(set (reg 17)
10513         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10514                  (const_int 0)))
10515    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10516         (not:QI (match_dup 1)))]
10517   "ix86_match_ccmode (insn, CCNOmode)
10518    && ix86_unary_operator_ok (NOT, QImode, operands)"
10519   "#"
10520   [(set_attr "type" "alu1")
10521    (set_attr "mode" "QI")])
10522
10523 (define_split
10524   [(set (reg 17)
10525         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10526                  (const_int 0)))
10527    (set (match_operand:QI 0 "nonimmediate_operand" "")
10528         (not:QI (match_dup 1)))]
10529   "ix86_match_ccmode (insn, CCNOmode)"
10530   [(parallel [(set (reg:CCNO FLAGS_REG)
10531                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10532                                  (const_int 0)))
10533               (set (match_dup 0)
10534                    (xor:QI (match_dup 1) (const_int -1)))])]
10535   "")
10536 \f
10537 ;; Arithmetic shift instructions
10538
10539 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10540 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10541 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10542 ;; from the assembler input.
10543 ;;
10544 ;; This instruction shifts the target reg/mem as usual, but instead of
10545 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10546 ;; is a left shift double, bits are taken from the high order bits of
10547 ;; reg, else if the insn is a shift right double, bits are taken from the
10548 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10549 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10550 ;;
10551 ;; Since sh[lr]d does not change the `reg' operand, that is done
10552 ;; separately, making all shifts emit pairs of shift double and normal
10553 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10554 ;; support a 63 bit shift, each shift where the count is in a reg expands
10555 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10556 ;;
10557 ;; If the shift count is a constant, we need never emit more than one
10558 ;; shift pair, instead using moves and sign extension for counts greater
10559 ;; than 31.
10560
10561 (define_expand "ashldi3"
10562   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10563                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10564                               (match_operand:QI 2 "nonmemory_operand" "")))
10565               (clobber (reg:CC FLAGS_REG))])]
10566   ""
10567 {
10568   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10569     {
10570       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10571       DONE;
10572     }
10573   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10574   DONE;
10575 })
10576
10577 (define_insn "*ashldi3_1_rex64"
10578   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10579         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10580                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10581    (clobber (reg:CC FLAGS_REG))]
10582   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10583 {
10584   switch (get_attr_type (insn))
10585     {
10586     case TYPE_ALU:
10587       if (operands[2] != const1_rtx)
10588         abort ();
10589       if (!rtx_equal_p (operands[0], operands[1]))
10590         abort ();
10591       return "add{q}\t{%0, %0|%0, %0}";
10592
10593     case TYPE_LEA:
10594       if (GET_CODE (operands[2]) != CONST_INT
10595           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10596         abort ();
10597       operands[1] = gen_rtx_MULT (DImode, operands[1],
10598                                   GEN_INT (1 << INTVAL (operands[2])));
10599       return "lea{q}\t{%a1, %0|%0, %a1}";
10600
10601     default:
10602       if (REG_P (operands[2]))
10603         return "sal{q}\t{%b2, %0|%0, %b2}";
10604       else if (operands[2] == const1_rtx
10605                && (TARGET_SHIFT1 || optimize_size))
10606         return "sal{q}\t%0";
10607       else
10608         return "sal{q}\t{%2, %0|%0, %2}";
10609     }
10610 }
10611   [(set (attr "type")
10612      (cond [(eq_attr "alternative" "1")
10613               (const_string "lea")
10614             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10615                           (const_int 0))
10616                       (match_operand 0 "register_operand" ""))
10617                  (match_operand 2 "const1_operand" ""))
10618               (const_string "alu")
10619            ]
10620            (const_string "ishift")))
10621    (set_attr "mode" "DI")])
10622
10623 ;; Convert lea to the lea pattern to avoid flags dependency.
10624 (define_split
10625   [(set (match_operand:DI 0 "register_operand" "")
10626         (ashift:DI (match_operand:DI 1 "register_operand" "")
10627                    (match_operand:QI 2 "immediate_operand" "")))
10628    (clobber (reg:CC FLAGS_REG))]
10629   "TARGET_64BIT && reload_completed
10630    && true_regnum (operands[0]) != true_regnum (operands[1])"
10631   [(set (match_dup 0)
10632         (mult:DI (match_dup 1)
10633                  (match_dup 2)))]
10634   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10635
10636 ;; This pattern can't accept a variable shift count, since shifts by
10637 ;; zero don't affect the flags.  We assume that shifts by constant
10638 ;; zero are optimized away.
10639 (define_insn "*ashldi3_cmp_rex64"
10640   [(set (reg 17)
10641         (compare
10642           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10643                      (match_operand:QI 2 "immediate_operand" "e"))
10644           (const_int 0)))
10645    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10646         (ashift:DI (match_dup 1) (match_dup 2)))]
10647   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10648    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10649 {
10650   switch (get_attr_type (insn))
10651     {
10652     case TYPE_ALU:
10653       if (operands[2] != const1_rtx)
10654         abort ();
10655       return "add{q}\t{%0, %0|%0, %0}";
10656
10657     default:
10658       if (REG_P (operands[2]))
10659         return "sal{q}\t{%b2, %0|%0, %b2}";
10660       else if (operands[2] == const1_rtx
10661                && (TARGET_SHIFT1 || optimize_size))
10662         return "sal{q}\t%0";
10663       else
10664         return "sal{q}\t{%2, %0|%0, %2}";
10665     }
10666 }
10667   [(set (attr "type")
10668      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10669                           (const_int 0))
10670                       (match_operand 0 "register_operand" ""))
10671                  (match_operand 2 "const1_operand" ""))
10672               (const_string "alu")
10673            ]
10674            (const_string "ishift")))
10675    (set_attr "mode" "DI")])
10676
10677 (define_insn "ashldi3_1"
10678   [(set (match_operand:DI 0 "register_operand" "=r")
10679         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10680                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10681    (clobber (match_scratch:SI 3 "=&r"))
10682    (clobber (reg:CC FLAGS_REG))]
10683   "!TARGET_64BIT && TARGET_CMOVE"
10684   "#"
10685   [(set_attr "type" "multi")])
10686
10687 (define_insn "*ashldi3_2"
10688   [(set (match_operand:DI 0 "register_operand" "=r")
10689         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10690                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10691    (clobber (reg:CC FLAGS_REG))]
10692   "!TARGET_64BIT"
10693   "#"
10694   [(set_attr "type" "multi")])
10695
10696 (define_split
10697   [(set (match_operand:DI 0 "register_operand" "")
10698         (ashift:DI (match_operand:DI 1 "register_operand" "")
10699                    (match_operand:QI 2 "nonmemory_operand" "")))
10700    (clobber (match_scratch:SI 3 ""))
10701    (clobber (reg:CC FLAGS_REG))]
10702   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10703   [(const_int 0)]
10704   "ix86_split_ashldi (operands, operands[3]); DONE;")
10705
10706 (define_split
10707   [(set (match_operand:DI 0 "register_operand" "")
10708         (ashift:DI (match_operand:DI 1 "register_operand" "")
10709                    (match_operand:QI 2 "nonmemory_operand" "")))
10710    (clobber (reg:CC FLAGS_REG))]
10711   "!TARGET_64BIT && reload_completed"
10712   [(const_int 0)]
10713   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10714
10715 (define_insn "x86_shld_1"
10716   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10717         (ior:SI (ashift:SI (match_dup 0)
10718                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10719                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10720                   (minus:QI (const_int 32) (match_dup 2)))))
10721    (clobber (reg:CC FLAGS_REG))]
10722   ""
10723   "@
10724    shld{l}\t{%2, %1, %0|%0, %1, %2}
10725    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10726   [(set_attr "type" "ishift")
10727    (set_attr "prefix_0f" "1")
10728    (set_attr "mode" "SI")
10729    (set_attr "pent_pair" "np")
10730    (set_attr "athlon_decode" "vector")])
10731
10732 (define_expand "x86_shift_adj_1"
10733   [(set (reg:CCZ FLAGS_REG)
10734         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10735                              (const_int 32))
10736                      (const_int 0)))
10737    (set (match_operand:SI 0 "register_operand" "")
10738         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10739                          (match_operand:SI 1 "register_operand" "")
10740                          (match_dup 0)))
10741    (set (match_dup 1)
10742         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10743                          (match_operand:SI 3 "register_operand" "r")
10744                          (match_dup 1)))]
10745   "TARGET_CMOVE"
10746   "")
10747
10748 (define_expand "x86_shift_adj_2"
10749   [(use (match_operand:SI 0 "register_operand" ""))
10750    (use (match_operand:SI 1 "register_operand" ""))
10751    (use (match_operand:QI 2 "register_operand" ""))]
10752   ""
10753 {
10754   rtx label = gen_label_rtx ();
10755   rtx tmp;
10756
10757   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10758
10759   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10760   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10761   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10762                               gen_rtx_LABEL_REF (VOIDmode, label),
10763                               pc_rtx);
10764   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10765   JUMP_LABEL (tmp) = label;
10766
10767   emit_move_insn (operands[0], operands[1]);
10768   emit_move_insn (operands[1], const0_rtx);
10769
10770   emit_label (label);
10771   LABEL_NUSES (label) = 1;
10772
10773   DONE;
10774 })
10775
10776 (define_expand "ashlsi3"
10777   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10778         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10779                    (match_operand:QI 2 "nonmemory_operand" "")))
10780    (clobber (reg:CC FLAGS_REG))]
10781   ""
10782   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10783
10784 (define_insn "*ashlsi3_1"
10785   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10786         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10787                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10788    (clobber (reg:CC FLAGS_REG))]
10789   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10790 {
10791   switch (get_attr_type (insn))
10792     {
10793     case TYPE_ALU:
10794       if (operands[2] != const1_rtx)
10795         abort ();
10796       if (!rtx_equal_p (operands[0], operands[1]))
10797         abort ();
10798       return "add{l}\t{%0, %0|%0, %0}";
10799
10800     case TYPE_LEA:
10801       return "#";
10802
10803     default:
10804       if (REG_P (operands[2]))
10805         return "sal{l}\t{%b2, %0|%0, %b2}";
10806       else if (operands[2] == const1_rtx
10807                && (TARGET_SHIFT1 || optimize_size))
10808         return "sal{l}\t%0";
10809       else
10810         return "sal{l}\t{%2, %0|%0, %2}";
10811     }
10812 }
10813   [(set (attr "type")
10814      (cond [(eq_attr "alternative" "1")
10815               (const_string "lea")
10816             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10817                           (const_int 0))
10818                       (match_operand 0 "register_operand" ""))
10819                  (match_operand 2 "const1_operand" ""))
10820               (const_string "alu")
10821            ]
10822            (const_string "ishift")))
10823    (set_attr "mode" "SI")])
10824
10825 ;; Convert lea to the lea pattern to avoid flags dependency.
10826 (define_split
10827   [(set (match_operand 0 "register_operand" "")
10828         (ashift (match_operand 1 "index_register_operand" "")
10829                 (match_operand:QI 2 "const_int_operand" "")))
10830    (clobber (reg:CC FLAGS_REG))]
10831   "reload_completed
10832    && true_regnum (operands[0]) != true_regnum (operands[1])"
10833   [(const_int 0)]
10834 {
10835   rtx pat;
10836   operands[0] = gen_lowpart (SImode, operands[0]);
10837   operands[1] = gen_lowpart (Pmode, operands[1]);
10838   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10839   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10840   if (Pmode != SImode)
10841     pat = gen_rtx_SUBREG (SImode, pat, 0);
10842   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10843   DONE;
10844 })
10845
10846 ;; Rare case of shifting RSP is handled by generating move and shift
10847 (define_split
10848   [(set (match_operand 0 "register_operand" "")
10849         (ashift (match_operand 1 "register_operand" "")
10850                 (match_operand:QI 2 "const_int_operand" "")))
10851    (clobber (reg:CC FLAGS_REG))]
10852   "reload_completed
10853    && true_regnum (operands[0]) != true_regnum (operands[1])"
10854   [(const_int 0)]
10855 {
10856   rtx pat, clob;
10857   emit_move_insn (operands[1], operands[0]);
10858   pat = gen_rtx_SET (VOIDmode, operands[0],
10859                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10860                                      operands[0], operands[2]));
10861   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10862   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10863   DONE;
10864 })
10865
10866 (define_insn "*ashlsi3_1_zext"
10867   [(set (match_operand:DI 0 "register_operand" "=r,r")
10868         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10869                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10870    (clobber (reg:CC FLAGS_REG))]
10871   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10872 {
10873   switch (get_attr_type (insn))
10874     {
10875     case TYPE_ALU:
10876       if (operands[2] != const1_rtx)
10877         abort ();
10878       return "add{l}\t{%k0, %k0|%k0, %k0}";
10879
10880     case TYPE_LEA:
10881       return "#";
10882
10883     default:
10884       if (REG_P (operands[2]))
10885         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10886       else if (operands[2] == const1_rtx
10887                && (TARGET_SHIFT1 || optimize_size))
10888         return "sal{l}\t%k0";
10889       else
10890         return "sal{l}\t{%2, %k0|%k0, %2}";
10891     }
10892 }
10893   [(set (attr "type")
10894      (cond [(eq_attr "alternative" "1")
10895               (const_string "lea")
10896             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10897                      (const_int 0))
10898                  (match_operand 2 "const1_operand" ""))
10899               (const_string "alu")
10900            ]
10901            (const_string "ishift")))
10902    (set_attr "mode" "SI")])
10903
10904 ;; Convert lea to the lea pattern to avoid flags dependency.
10905 (define_split
10906   [(set (match_operand:DI 0 "register_operand" "")
10907         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10908                                 (match_operand:QI 2 "const_int_operand" ""))))
10909    (clobber (reg:CC FLAGS_REG))]
10910   "TARGET_64BIT && reload_completed
10911    && true_regnum (operands[0]) != true_regnum (operands[1])"
10912   [(set (match_dup 0) (zero_extend:DI
10913                         (subreg:SI (mult:SI (match_dup 1)
10914                                             (match_dup 2)) 0)))]
10915 {
10916   operands[1] = gen_lowpart (Pmode, operands[1]);
10917   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10918 })
10919
10920 ;; This pattern can't accept a variable shift count, since shifts by
10921 ;; zero don't affect the flags.  We assume that shifts by constant
10922 ;; zero are optimized away.
10923 (define_insn "*ashlsi3_cmp"
10924   [(set (reg 17)
10925         (compare
10926           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10927                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10928           (const_int 0)))
10929    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10930         (ashift:SI (match_dup 1) (match_dup 2)))]
10931   "ix86_match_ccmode (insn, CCGOCmode)
10932    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10933 {
10934   switch (get_attr_type (insn))
10935     {
10936     case TYPE_ALU:
10937       if (operands[2] != const1_rtx)
10938         abort ();
10939       return "add{l}\t{%0, %0|%0, %0}";
10940
10941     default:
10942       if (REG_P (operands[2]))
10943         return "sal{l}\t{%b2, %0|%0, %b2}";
10944       else if (operands[2] == const1_rtx
10945                && (TARGET_SHIFT1 || optimize_size))
10946         return "sal{l}\t%0";
10947       else
10948         return "sal{l}\t{%2, %0|%0, %2}";
10949     }
10950 }
10951   [(set (attr "type")
10952      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10953                           (const_int 0))
10954                       (match_operand 0 "register_operand" ""))
10955                  (match_operand 2 "const1_operand" ""))
10956               (const_string "alu")
10957            ]
10958            (const_string "ishift")))
10959    (set_attr "mode" "SI")])
10960
10961 (define_insn "*ashlsi3_cmp_zext"
10962   [(set (reg 17)
10963         (compare
10964           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10965                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10966           (const_int 0)))
10967    (set (match_operand:DI 0 "register_operand" "=r")
10968         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10969   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10970    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10971 {
10972   switch (get_attr_type (insn))
10973     {
10974     case TYPE_ALU:
10975       if (operands[2] != const1_rtx)
10976         abort ();
10977       return "add{l}\t{%k0, %k0|%k0, %k0}";
10978
10979     default:
10980       if (REG_P (operands[2]))
10981         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10982       else if (operands[2] == const1_rtx
10983                && (TARGET_SHIFT1 || optimize_size))
10984         return "sal{l}\t%k0";
10985       else
10986         return "sal{l}\t{%2, %k0|%k0, %2}";
10987     }
10988 }
10989   [(set (attr "type")
10990      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10991                      (const_int 0))
10992                  (match_operand 2 "const1_operand" ""))
10993               (const_string "alu")
10994            ]
10995            (const_string "ishift")))
10996    (set_attr "mode" "SI")])
10997
10998 (define_expand "ashlhi3"
10999   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11000         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11001                    (match_operand:QI 2 "nonmemory_operand" "")))
11002    (clobber (reg:CC FLAGS_REG))]
11003   "TARGET_HIMODE_MATH"
11004   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11005
11006 (define_insn "*ashlhi3_1_lea"
11007   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11008         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11009                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11010    (clobber (reg:CC FLAGS_REG))]
11011   "!TARGET_PARTIAL_REG_STALL
11012    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11013 {
11014   switch (get_attr_type (insn))
11015     {
11016     case TYPE_LEA:
11017       return "#";
11018     case TYPE_ALU:
11019       if (operands[2] != const1_rtx)
11020         abort ();
11021       return "add{w}\t{%0, %0|%0, %0}";
11022
11023     default:
11024       if (REG_P (operands[2]))
11025         return "sal{w}\t{%b2, %0|%0, %b2}";
11026       else if (operands[2] == const1_rtx
11027                && (TARGET_SHIFT1 || optimize_size))
11028         return "sal{w}\t%0";
11029       else
11030         return "sal{w}\t{%2, %0|%0, %2}";
11031     }
11032 }
11033   [(set (attr "type")
11034      (cond [(eq_attr "alternative" "1")
11035               (const_string "lea")
11036             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11037                           (const_int 0))
11038                       (match_operand 0 "register_operand" ""))
11039                  (match_operand 2 "const1_operand" ""))
11040               (const_string "alu")
11041            ]
11042            (const_string "ishift")))
11043    (set_attr "mode" "HI,SI")])
11044
11045 (define_insn "*ashlhi3_1"
11046   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11047         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11048                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11049    (clobber (reg:CC FLAGS_REG))]
11050   "TARGET_PARTIAL_REG_STALL
11051    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11052 {
11053   switch (get_attr_type (insn))
11054     {
11055     case TYPE_ALU:
11056       if (operands[2] != const1_rtx)
11057         abort ();
11058       return "add{w}\t{%0, %0|%0, %0}";
11059
11060     default:
11061       if (REG_P (operands[2]))
11062         return "sal{w}\t{%b2, %0|%0, %b2}";
11063       else if (operands[2] == const1_rtx
11064                && (TARGET_SHIFT1 || optimize_size))
11065         return "sal{w}\t%0";
11066       else
11067         return "sal{w}\t{%2, %0|%0, %2}";
11068     }
11069 }
11070   [(set (attr "type")
11071      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11072                           (const_int 0))
11073                       (match_operand 0 "register_operand" ""))
11074                  (match_operand 2 "const1_operand" ""))
11075               (const_string "alu")
11076            ]
11077            (const_string "ishift")))
11078    (set_attr "mode" "HI")])
11079
11080 ;; This pattern can't accept a variable shift count, since shifts by
11081 ;; zero don't affect the flags.  We assume that shifts by constant
11082 ;; zero are optimized away.
11083 (define_insn "*ashlhi3_cmp"
11084   [(set (reg 17)
11085         (compare
11086           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11087                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11088           (const_int 0)))
11089    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11090         (ashift:HI (match_dup 1) (match_dup 2)))]
11091   "ix86_match_ccmode (insn, CCGOCmode)
11092    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11093 {
11094   switch (get_attr_type (insn))
11095     {
11096     case TYPE_ALU:
11097       if (operands[2] != const1_rtx)
11098         abort ();
11099       return "add{w}\t{%0, %0|%0, %0}";
11100
11101     default:
11102       if (REG_P (operands[2]))
11103         return "sal{w}\t{%b2, %0|%0, %b2}";
11104       else if (operands[2] == const1_rtx
11105                && (TARGET_SHIFT1 || optimize_size))
11106         return "sal{w}\t%0";
11107       else
11108         return "sal{w}\t{%2, %0|%0, %2}";
11109     }
11110 }
11111   [(set (attr "type")
11112      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11113                           (const_int 0))
11114                       (match_operand 0 "register_operand" ""))
11115                  (match_operand 2 "const1_operand" ""))
11116               (const_string "alu")
11117            ]
11118            (const_string "ishift")))
11119    (set_attr "mode" "HI")])
11120
11121 (define_expand "ashlqi3"
11122   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11123         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11124                    (match_operand:QI 2 "nonmemory_operand" "")))
11125    (clobber (reg:CC FLAGS_REG))]
11126   "TARGET_QIMODE_MATH"
11127   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11128
11129 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11130
11131 (define_insn "*ashlqi3_1_lea"
11132   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11133         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11134                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11135    (clobber (reg:CC FLAGS_REG))]
11136   "!TARGET_PARTIAL_REG_STALL
11137    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11138 {
11139   switch (get_attr_type (insn))
11140     {
11141     case TYPE_LEA:
11142       return "#";
11143     case TYPE_ALU:
11144       if (operands[2] != const1_rtx)
11145         abort ();
11146       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11147         return "add{l}\t{%k0, %k0|%k0, %k0}";
11148       else
11149         return "add{b}\t{%0, %0|%0, %0}";
11150
11151     default:
11152       if (REG_P (operands[2]))
11153         {
11154           if (get_attr_mode (insn) == MODE_SI)
11155             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11156           else
11157             return "sal{b}\t{%b2, %0|%0, %b2}";
11158         }
11159       else if (operands[2] == const1_rtx
11160                && (TARGET_SHIFT1 || optimize_size))
11161         {
11162           if (get_attr_mode (insn) == MODE_SI)
11163             return "sal{l}\t%0";
11164           else
11165             return "sal{b}\t%0";
11166         }
11167       else
11168         {
11169           if (get_attr_mode (insn) == MODE_SI)
11170             return "sal{l}\t{%2, %k0|%k0, %2}";
11171           else
11172             return "sal{b}\t{%2, %0|%0, %2}";
11173         }
11174     }
11175 }
11176   [(set (attr "type")
11177      (cond [(eq_attr "alternative" "2")
11178               (const_string "lea")
11179             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11180                           (const_int 0))
11181                       (match_operand 0 "register_operand" ""))
11182                  (match_operand 2 "const1_operand" ""))
11183               (const_string "alu")
11184            ]
11185            (const_string "ishift")))
11186    (set_attr "mode" "QI,SI,SI")])
11187
11188 (define_insn "*ashlqi3_1"
11189   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11190         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11191                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11192    (clobber (reg:CC FLAGS_REG))]
11193   "TARGET_PARTIAL_REG_STALL
11194    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11195 {
11196   switch (get_attr_type (insn))
11197     {
11198     case TYPE_ALU:
11199       if (operands[2] != const1_rtx)
11200         abort ();
11201       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11202         return "add{l}\t{%k0, %k0|%k0, %k0}";
11203       else
11204         return "add{b}\t{%0, %0|%0, %0}";
11205
11206     default:
11207       if (REG_P (operands[2]))
11208         {
11209           if (get_attr_mode (insn) == MODE_SI)
11210             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11211           else
11212             return "sal{b}\t{%b2, %0|%0, %b2}";
11213         }
11214       else if (operands[2] == const1_rtx
11215                && (TARGET_SHIFT1 || optimize_size))
11216         {
11217           if (get_attr_mode (insn) == MODE_SI)
11218             return "sal{l}\t%0";
11219           else
11220             return "sal{b}\t%0";
11221         }
11222       else
11223         {
11224           if (get_attr_mode (insn) == MODE_SI)
11225             return "sal{l}\t{%2, %k0|%k0, %2}";
11226           else
11227             return "sal{b}\t{%2, %0|%0, %2}";
11228         }
11229     }
11230 }
11231   [(set (attr "type")
11232      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11233                           (const_int 0))
11234                       (match_operand 0 "register_operand" ""))
11235                  (match_operand 2 "const1_operand" ""))
11236               (const_string "alu")
11237            ]
11238            (const_string "ishift")))
11239    (set_attr "mode" "QI,SI")])
11240
11241 ;; This pattern can't accept a variable shift count, since shifts by
11242 ;; zero don't affect the flags.  We assume that shifts by constant
11243 ;; zero are optimized away.
11244 (define_insn "*ashlqi3_cmp"
11245   [(set (reg 17)
11246         (compare
11247           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11248                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11249           (const_int 0)))
11250    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11251         (ashift:QI (match_dup 1) (match_dup 2)))]
11252   "ix86_match_ccmode (insn, CCGOCmode)
11253    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11254 {
11255   switch (get_attr_type (insn))
11256     {
11257     case TYPE_ALU:
11258       if (operands[2] != const1_rtx)
11259         abort ();
11260       return "add{b}\t{%0, %0|%0, %0}";
11261
11262     default:
11263       if (REG_P (operands[2]))
11264         return "sal{b}\t{%b2, %0|%0, %b2}";
11265       else if (operands[2] == const1_rtx
11266                && (TARGET_SHIFT1 || optimize_size))
11267         return "sal{b}\t%0";
11268       else
11269         return "sal{b}\t{%2, %0|%0, %2}";
11270     }
11271 }
11272   [(set (attr "type")
11273      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11274                           (const_int 0))
11275                       (match_operand 0 "register_operand" ""))
11276                  (match_operand 2 "const1_operand" ""))
11277               (const_string "alu")
11278            ]
11279            (const_string "ishift")))
11280    (set_attr "mode" "QI")])
11281
11282 ;; See comment above `ashldi3' about how this works.
11283
11284 (define_expand "ashrdi3"
11285   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11286                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11287                                 (match_operand:QI 2 "nonmemory_operand" "")))
11288               (clobber (reg:CC FLAGS_REG))])]
11289   ""
11290 {
11291   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11292     {
11293       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11294       DONE;
11295     }
11296   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11297   DONE;
11298 })
11299
11300 (define_insn "ashrdi3_63_rex64"
11301   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11302         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11303                      (match_operand:DI 2 "const_int_operand" "i,i")))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11306    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11307   "@
11308    {cqto|cqo}
11309    sar{q}\t{%2, %0|%0, %2}"
11310   [(set_attr "type" "imovx,ishift")
11311    (set_attr "prefix_0f" "0,*")
11312    (set_attr "length_immediate" "0,*")
11313    (set_attr "modrm" "0,1")
11314    (set_attr "mode" "DI")])
11315
11316 (define_insn "*ashrdi3_1_one_bit_rex64"
11317   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11318         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11319                      (match_operand:QI 2 "const1_operand" "")))
11320    (clobber (reg:CC FLAGS_REG))]
11321   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11322    && (TARGET_SHIFT1 || optimize_size)"
11323   "sar{q}\t%0"
11324   [(set_attr "type" "ishift")
11325    (set (attr "length") 
11326      (if_then_else (match_operand:DI 0 "register_operand" "") 
11327         (const_string "2")
11328         (const_string "*")))])
11329
11330 (define_insn "*ashrdi3_1_rex64"
11331   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11332         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11333                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11334    (clobber (reg:CC FLAGS_REG))]
11335   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11336   "@
11337    sar{q}\t{%2, %0|%0, %2}
11338    sar{q}\t{%b2, %0|%0, %b2}"
11339   [(set_attr "type" "ishift")
11340    (set_attr "mode" "DI")])
11341
11342 ;; This pattern can't accept a variable shift count, since shifts by
11343 ;; zero don't affect the flags.  We assume that shifts by constant
11344 ;; zero are optimized away.
11345 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11346   [(set (reg 17)
11347         (compare
11348           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11349                        (match_operand:QI 2 "const1_operand" ""))
11350           (const_int 0)))
11351    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11352         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11353   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11354    && (TARGET_SHIFT1 || optimize_size)
11355    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11356   "sar{q}\t%0"
11357   [(set_attr "type" "ishift")
11358    (set (attr "length") 
11359      (if_then_else (match_operand:DI 0 "register_operand" "") 
11360         (const_string "2")
11361         (const_string "*")))])
11362
11363 ;; This pattern can't accept a variable shift count, since shifts by
11364 ;; zero don't affect the flags.  We assume that shifts by constant
11365 ;; zero are optimized away.
11366 (define_insn "*ashrdi3_cmp_rex64"
11367   [(set (reg 17)
11368         (compare
11369           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11370                        (match_operand:QI 2 "const_int_operand" "n"))
11371           (const_int 0)))
11372    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11373         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11374   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11375    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11376   "sar{q}\t{%2, %0|%0, %2}"
11377   [(set_attr "type" "ishift")
11378    (set_attr "mode" "DI")])
11379
11380
11381 (define_insn "ashrdi3_1"
11382   [(set (match_operand:DI 0 "register_operand" "=r")
11383         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11384                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11385    (clobber (match_scratch:SI 3 "=&r"))
11386    (clobber (reg:CC FLAGS_REG))]
11387   "!TARGET_64BIT && TARGET_CMOVE"
11388   "#"
11389   [(set_attr "type" "multi")])
11390
11391 (define_insn "*ashrdi3_2"
11392   [(set (match_operand:DI 0 "register_operand" "=r")
11393         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11394                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11395    (clobber (reg:CC FLAGS_REG))]
11396   "!TARGET_64BIT"
11397   "#"
11398   [(set_attr "type" "multi")])
11399
11400 (define_split
11401   [(set (match_operand:DI 0 "register_operand" "")
11402         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11403                      (match_operand:QI 2 "nonmemory_operand" "")))
11404    (clobber (match_scratch:SI 3 ""))
11405    (clobber (reg:CC FLAGS_REG))]
11406   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11407   [(const_int 0)]
11408   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11409
11410 (define_split
11411   [(set (match_operand:DI 0 "register_operand" "")
11412         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11413                      (match_operand:QI 2 "nonmemory_operand" "")))
11414    (clobber (reg:CC FLAGS_REG))]
11415   "!TARGET_64BIT && reload_completed"
11416   [(const_int 0)]
11417   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11418
11419 (define_insn "x86_shrd_1"
11420   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11421         (ior:SI (ashiftrt:SI (match_dup 0)
11422                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11423                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11424                   (minus:QI (const_int 32) (match_dup 2)))))
11425    (clobber (reg:CC FLAGS_REG))]
11426   ""
11427   "@
11428    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11429    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11430   [(set_attr "type" "ishift")
11431    (set_attr "prefix_0f" "1")
11432    (set_attr "pent_pair" "np")
11433    (set_attr "mode" "SI")])
11434
11435 (define_expand "x86_shift_adj_3"
11436   [(use (match_operand:SI 0 "register_operand" ""))
11437    (use (match_operand:SI 1 "register_operand" ""))
11438    (use (match_operand:QI 2 "register_operand" ""))]
11439   ""
11440 {
11441   rtx label = gen_label_rtx ();
11442   rtx tmp;
11443
11444   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11445
11446   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11447   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11448   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11449                               gen_rtx_LABEL_REF (VOIDmode, label),
11450                               pc_rtx);
11451   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11452   JUMP_LABEL (tmp) = label;
11453
11454   emit_move_insn (operands[0], operands[1]);
11455   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11456
11457   emit_label (label);
11458   LABEL_NUSES (label) = 1;
11459
11460   DONE;
11461 })
11462
11463 (define_insn "ashrsi3_31"
11464   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11465         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11466                      (match_operand:SI 2 "const_int_operand" "i,i")))
11467    (clobber (reg:CC FLAGS_REG))]
11468   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11469    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11470   "@
11471    {cltd|cdq}
11472    sar{l}\t{%2, %0|%0, %2}"
11473   [(set_attr "type" "imovx,ishift")
11474    (set_attr "prefix_0f" "0,*")
11475    (set_attr "length_immediate" "0,*")
11476    (set_attr "modrm" "0,1")
11477    (set_attr "mode" "SI")])
11478
11479 (define_insn "*ashrsi3_31_zext"
11480   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11481         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11482                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11483    (clobber (reg:CC FLAGS_REG))]
11484   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11485    && INTVAL (operands[2]) == 31
11486    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11487   "@
11488    {cltd|cdq}
11489    sar{l}\t{%2, %k0|%k0, %2}"
11490   [(set_attr "type" "imovx,ishift")
11491    (set_attr "prefix_0f" "0,*")
11492    (set_attr "length_immediate" "0,*")
11493    (set_attr "modrm" "0,1")
11494    (set_attr "mode" "SI")])
11495
11496 (define_expand "ashrsi3"
11497   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11498         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11499                      (match_operand:QI 2 "nonmemory_operand" "")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   ""
11502   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11503
11504 (define_insn "*ashrsi3_1_one_bit"
11505   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11506         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11507                      (match_operand:QI 2 "const1_operand" "")))
11508    (clobber (reg:CC FLAGS_REG))]
11509   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11510    && (TARGET_SHIFT1 || optimize_size)"
11511   "sar{l}\t%0"
11512   [(set_attr "type" "ishift")
11513    (set (attr "length") 
11514      (if_then_else (match_operand:SI 0 "register_operand" "") 
11515         (const_string "2")
11516         (const_string "*")))])
11517
11518 (define_insn "*ashrsi3_1_one_bit_zext"
11519   [(set (match_operand:DI 0 "register_operand" "=r")
11520         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11521                                      (match_operand:QI 2 "const1_operand" ""))))
11522    (clobber (reg:CC FLAGS_REG))]
11523   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11524    && (TARGET_SHIFT1 || optimize_size)"
11525   "sar{l}\t%k0"
11526   [(set_attr "type" "ishift")
11527    (set_attr "length" "2")])
11528
11529 (define_insn "*ashrsi3_1"
11530   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11531         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11532                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11533    (clobber (reg:CC FLAGS_REG))]
11534   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11535   "@
11536    sar{l}\t{%2, %0|%0, %2}
11537    sar{l}\t{%b2, %0|%0, %b2}"
11538   [(set_attr "type" "ishift")
11539    (set_attr "mode" "SI")])
11540
11541 (define_insn "*ashrsi3_1_zext"
11542   [(set (match_operand:DI 0 "register_operand" "=r,r")
11543         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11544                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11545    (clobber (reg:CC FLAGS_REG))]
11546   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11547   "@
11548    sar{l}\t{%2, %k0|%k0, %2}
11549    sar{l}\t{%b2, %k0|%k0, %b2}"
11550   [(set_attr "type" "ishift")
11551    (set_attr "mode" "SI")])
11552
11553 ;; This pattern can't accept a variable shift count, since shifts by
11554 ;; zero don't affect the flags.  We assume that shifts by constant
11555 ;; zero are optimized away.
11556 (define_insn "*ashrsi3_one_bit_cmp"
11557   [(set (reg 17)
11558         (compare
11559           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11560                        (match_operand:QI 2 "const1_operand" ""))
11561           (const_int 0)))
11562    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11563         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11564   "ix86_match_ccmode (insn, CCGOCmode)
11565    && (TARGET_SHIFT1 || optimize_size)
11566    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11567   "sar{l}\t%0"
11568   [(set_attr "type" "ishift")
11569    (set (attr "length") 
11570      (if_then_else (match_operand:SI 0 "register_operand" "") 
11571         (const_string "2")
11572         (const_string "*")))])
11573
11574 (define_insn "*ashrsi3_one_bit_cmp_zext"
11575   [(set (reg 17)
11576         (compare
11577           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11578                        (match_operand:QI 2 "const1_operand" ""))
11579           (const_int 0)))
11580    (set (match_operand:DI 0 "register_operand" "=r")
11581         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11582   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11583    && (TARGET_SHIFT1 || optimize_size)
11584    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11585   "sar{l}\t%k0"
11586   [(set_attr "type" "ishift")
11587    (set_attr "length" "2")])
11588
11589 ;; This pattern can't accept a variable shift count, since shifts by
11590 ;; zero don't affect the flags.  We assume that shifts by constant
11591 ;; zero are optimized away.
11592 (define_insn "*ashrsi3_cmp"
11593   [(set (reg 17)
11594         (compare
11595           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11596                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11597           (const_int 0)))
11598    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11599         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11600   "ix86_match_ccmode (insn, CCGOCmode)
11601    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11602   "sar{l}\t{%2, %0|%0, %2}"
11603   [(set_attr "type" "ishift")
11604    (set_attr "mode" "SI")])
11605
11606 (define_insn "*ashrsi3_cmp_zext"
11607   [(set (reg 17)
11608         (compare
11609           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11610                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11611           (const_int 0)))
11612    (set (match_operand:DI 0 "register_operand" "=r")
11613         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11614   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11615    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11616   "sar{l}\t{%2, %k0|%k0, %2}"
11617   [(set_attr "type" "ishift")
11618    (set_attr "mode" "SI")])
11619
11620 (define_expand "ashrhi3"
11621   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11622         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11623                      (match_operand:QI 2 "nonmemory_operand" "")))
11624    (clobber (reg:CC FLAGS_REG))]
11625   "TARGET_HIMODE_MATH"
11626   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11627
11628 (define_insn "*ashrhi3_1_one_bit"
11629   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11630         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11631                      (match_operand:QI 2 "const1_operand" "")))
11632    (clobber (reg:CC FLAGS_REG))]
11633   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11634    && (TARGET_SHIFT1 || optimize_size)"
11635   "sar{w}\t%0"
11636   [(set_attr "type" "ishift")
11637    (set (attr "length") 
11638      (if_then_else (match_operand 0 "register_operand" "") 
11639         (const_string "2")
11640         (const_string "*")))])
11641
11642 (define_insn "*ashrhi3_1"
11643   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11644         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11645                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11646    (clobber (reg:CC FLAGS_REG))]
11647   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11648   "@
11649    sar{w}\t{%2, %0|%0, %2}
11650    sar{w}\t{%b2, %0|%0, %b2}"
11651   [(set_attr "type" "ishift")
11652    (set_attr "mode" "HI")])
11653
11654 ;; This pattern can't accept a variable shift count, since shifts by
11655 ;; zero don't affect the flags.  We assume that shifts by constant
11656 ;; zero are optimized away.
11657 (define_insn "*ashrhi3_one_bit_cmp"
11658   [(set (reg 17)
11659         (compare
11660           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11661                        (match_operand:QI 2 "const1_operand" ""))
11662           (const_int 0)))
11663    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11664         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11665   "ix86_match_ccmode (insn, CCGOCmode)
11666    && (TARGET_SHIFT1 || optimize_size)
11667    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11668   "sar{w}\t%0"
11669   [(set_attr "type" "ishift")
11670    (set (attr "length") 
11671      (if_then_else (match_operand 0 "register_operand" "") 
11672         (const_string "2")
11673         (const_string "*")))])
11674
11675 ;; This pattern can't accept a variable shift count, since shifts by
11676 ;; zero don't affect the flags.  We assume that shifts by constant
11677 ;; zero are optimized away.
11678 (define_insn "*ashrhi3_cmp"
11679   [(set (reg 17)
11680         (compare
11681           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11682                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11683           (const_int 0)))
11684    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11685         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11686   "ix86_match_ccmode (insn, CCGOCmode)
11687    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11688   "sar{w}\t{%2, %0|%0, %2}"
11689   [(set_attr "type" "ishift")
11690    (set_attr "mode" "HI")])
11691
11692 (define_expand "ashrqi3"
11693   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11694         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11695                      (match_operand:QI 2 "nonmemory_operand" "")))
11696    (clobber (reg:CC FLAGS_REG))]
11697   "TARGET_QIMODE_MATH"
11698   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11699
11700 (define_insn "*ashrqi3_1_one_bit"
11701   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11702         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11703                      (match_operand:QI 2 "const1_operand" "")))
11704    (clobber (reg:CC FLAGS_REG))]
11705   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11706    && (TARGET_SHIFT1 || optimize_size)"
11707   "sar{b}\t%0"
11708   [(set_attr "type" "ishift")
11709    (set (attr "length") 
11710      (if_then_else (match_operand 0 "register_operand" "") 
11711         (const_string "2")
11712         (const_string "*")))])
11713
11714 (define_insn "*ashrqi3_1_one_bit_slp"
11715   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11716         (ashiftrt:QI (match_dup 0)
11717                      (match_operand:QI 1 "const1_operand" "")))
11718    (clobber (reg:CC FLAGS_REG))]
11719   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11720    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11721    && (TARGET_SHIFT1 || optimize_size)"
11722   "sar{b}\t%0"
11723   [(set_attr "type" "ishift1")
11724    (set (attr "length") 
11725      (if_then_else (match_operand 0 "register_operand" "") 
11726         (const_string "2")
11727         (const_string "*")))])
11728
11729 (define_insn "*ashrqi3_1"
11730   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11731         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11732                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11733    (clobber (reg:CC FLAGS_REG))]
11734   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11735   "@
11736    sar{b}\t{%2, %0|%0, %2}
11737    sar{b}\t{%b2, %0|%0, %b2}"
11738   [(set_attr "type" "ishift")
11739    (set_attr "mode" "QI")])
11740
11741 (define_insn "*ashrqi3_1_slp"
11742   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11743         (ashiftrt:QI (match_dup 0)
11744                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11747    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11748   "@
11749    sar{b}\t{%1, %0|%0, %1}
11750    sar{b}\t{%b1, %0|%0, %b1}"
11751   [(set_attr "type" "ishift1")
11752    (set_attr "mode" "QI")])
11753
11754 ;; This pattern can't accept a variable shift count, since shifts by
11755 ;; zero don't affect the flags.  We assume that shifts by constant
11756 ;; zero are optimized away.
11757 (define_insn "*ashrqi3_one_bit_cmp"
11758   [(set (reg 17)
11759         (compare
11760           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11761                        (match_operand:QI 2 "const1_operand" "I"))
11762           (const_int 0)))
11763    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11764         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11765   "ix86_match_ccmode (insn, CCGOCmode)
11766    && (TARGET_SHIFT1 || optimize_size)
11767    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11768   "sar{b}\t%0"
11769   [(set_attr "type" "ishift")
11770    (set (attr "length") 
11771      (if_then_else (match_operand 0 "register_operand" "") 
11772         (const_string "2")
11773         (const_string "*")))])
11774
11775 ;; This pattern can't accept a variable shift count, since shifts by
11776 ;; zero don't affect the flags.  We assume that shifts by constant
11777 ;; zero are optimized away.
11778 (define_insn "*ashrqi3_cmp"
11779   [(set (reg 17)
11780         (compare
11781           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11782                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11783           (const_int 0)))
11784    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11785         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11786   "ix86_match_ccmode (insn, CCGOCmode)
11787    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11788   "sar{b}\t{%2, %0|%0, %2}"
11789   [(set_attr "type" "ishift")
11790    (set_attr "mode" "QI")])
11791 \f
11792 ;; Logical shift instructions
11793
11794 ;; See comment above `ashldi3' about how this works.
11795
11796 (define_expand "lshrdi3"
11797   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11798                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11799                                 (match_operand:QI 2 "nonmemory_operand" "")))
11800               (clobber (reg:CC FLAGS_REG))])]
11801   ""
11802 {
11803   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11804     {
11805       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11806       DONE;
11807     }
11808   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11809   DONE;
11810 })
11811
11812 (define_insn "*lshrdi3_1_one_bit_rex64"
11813   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11814         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11815                      (match_operand:QI 2 "const1_operand" "")))
11816    (clobber (reg:CC FLAGS_REG))]
11817   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11818    && (TARGET_SHIFT1 || optimize_size)"
11819   "shr{q}\t%0"
11820   [(set_attr "type" "ishift")
11821    (set (attr "length") 
11822      (if_then_else (match_operand:DI 0 "register_operand" "") 
11823         (const_string "2")
11824         (const_string "*")))])
11825
11826 (define_insn "*lshrdi3_1_rex64"
11827   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11828         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11829                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11830    (clobber (reg:CC FLAGS_REG))]
11831   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11832   "@
11833    shr{q}\t{%2, %0|%0, %2}
11834    shr{q}\t{%b2, %0|%0, %b2}"
11835   [(set_attr "type" "ishift")
11836    (set_attr "mode" "DI")])
11837
11838 ;; This pattern can't accept a variable shift count, since shifts by
11839 ;; zero don't affect the flags.  We assume that shifts by constant
11840 ;; zero are optimized away.
11841 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11842   [(set (reg 17)
11843         (compare
11844           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11845                        (match_operand:QI 2 "const1_operand" ""))
11846           (const_int 0)))
11847    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11848         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11849   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11850    && (TARGET_SHIFT1 || optimize_size)
11851    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11852   "shr{q}\t%0"
11853   [(set_attr "type" "ishift")
11854    (set (attr "length") 
11855      (if_then_else (match_operand:DI 0 "register_operand" "") 
11856         (const_string "2")
11857         (const_string "*")))])
11858
11859 ;; This pattern can't accept a variable shift count, since shifts by
11860 ;; zero don't affect the flags.  We assume that shifts by constant
11861 ;; zero are optimized away.
11862 (define_insn "*lshrdi3_cmp_rex64"
11863   [(set (reg 17)
11864         (compare
11865           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11866                        (match_operand:QI 2 "const_int_operand" "e"))
11867           (const_int 0)))
11868    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11869         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11870   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11871    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11872   "shr{q}\t{%2, %0|%0, %2}"
11873   [(set_attr "type" "ishift")
11874    (set_attr "mode" "DI")])
11875
11876 (define_insn "lshrdi3_1"
11877   [(set (match_operand:DI 0 "register_operand" "=r")
11878         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11879                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11880    (clobber (match_scratch:SI 3 "=&r"))
11881    (clobber (reg:CC FLAGS_REG))]
11882   "!TARGET_64BIT && TARGET_CMOVE"
11883   "#"
11884   [(set_attr "type" "multi")])
11885
11886 (define_insn "*lshrdi3_2"
11887   [(set (match_operand:DI 0 "register_operand" "=r")
11888         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11889                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11890    (clobber (reg:CC FLAGS_REG))]
11891   "!TARGET_64BIT"
11892   "#"
11893   [(set_attr "type" "multi")])
11894
11895 (define_split 
11896   [(set (match_operand:DI 0 "register_operand" "")
11897         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11898                      (match_operand:QI 2 "nonmemory_operand" "")))
11899    (clobber (match_scratch:SI 3 ""))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11902   [(const_int 0)]
11903   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11904
11905 (define_split 
11906   [(set (match_operand:DI 0 "register_operand" "")
11907         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11908                      (match_operand:QI 2 "nonmemory_operand" "")))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "!TARGET_64BIT && reload_completed"
11911   [(const_int 0)]
11912   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11913
11914 (define_expand "lshrsi3"
11915   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11916         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11917                      (match_operand:QI 2 "nonmemory_operand" "")))
11918    (clobber (reg:CC FLAGS_REG))]
11919   ""
11920   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11921
11922 (define_insn "*lshrsi3_1_one_bit"
11923   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11924         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11925                      (match_operand:QI 2 "const1_operand" "")))
11926    (clobber (reg:CC FLAGS_REG))]
11927   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11928    && (TARGET_SHIFT1 || optimize_size)"
11929   "shr{l}\t%0"
11930   [(set_attr "type" "ishift")
11931    (set (attr "length") 
11932      (if_then_else (match_operand:SI 0 "register_operand" "") 
11933         (const_string "2")
11934         (const_string "*")))])
11935
11936 (define_insn "*lshrsi3_1_one_bit_zext"
11937   [(set (match_operand:DI 0 "register_operand" "=r")
11938         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11939                      (match_operand:QI 2 "const1_operand" "")))
11940    (clobber (reg:CC FLAGS_REG))]
11941   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11942    && (TARGET_SHIFT1 || optimize_size)"
11943   "shr{l}\t%k0"
11944   [(set_attr "type" "ishift")
11945    (set_attr "length" "2")])
11946
11947 (define_insn "*lshrsi3_1"
11948   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11949         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11950                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11951    (clobber (reg:CC FLAGS_REG))]
11952   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11953   "@
11954    shr{l}\t{%2, %0|%0, %2}
11955    shr{l}\t{%b2, %0|%0, %b2}"
11956   [(set_attr "type" "ishift")
11957    (set_attr "mode" "SI")])
11958
11959 (define_insn "*lshrsi3_1_zext"
11960   [(set (match_operand:DI 0 "register_operand" "=r,r")
11961         (zero_extend:DI
11962           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11963                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11966   "@
11967    shr{l}\t{%2, %k0|%k0, %2}
11968    shr{l}\t{%b2, %k0|%k0, %b2}"
11969   [(set_attr "type" "ishift")
11970    (set_attr "mode" "SI")])
11971
11972 ;; This pattern can't accept a variable shift count, since shifts by
11973 ;; zero don't affect the flags.  We assume that shifts by constant
11974 ;; zero are optimized away.
11975 (define_insn "*lshrsi3_one_bit_cmp"
11976   [(set (reg 17)
11977         (compare
11978           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11979                        (match_operand:QI 2 "const1_operand" ""))
11980           (const_int 0)))
11981    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11982         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11983   "ix86_match_ccmode (insn, CCGOCmode)
11984    && (TARGET_SHIFT1 || optimize_size)
11985    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11986   "shr{l}\t%0"
11987   [(set_attr "type" "ishift")
11988    (set (attr "length") 
11989      (if_then_else (match_operand:SI 0 "register_operand" "") 
11990         (const_string "2")
11991         (const_string "*")))])
11992
11993 (define_insn "*lshrsi3_cmp_one_bit_zext"
11994   [(set (reg 17)
11995         (compare
11996           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11997                        (match_operand:QI 2 "const1_operand" ""))
11998           (const_int 0)))
11999    (set (match_operand:DI 0 "register_operand" "=r")
12000         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12001   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12002    && (TARGET_SHIFT1 || optimize_size)
12003    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12004   "shr{l}\t%k0"
12005   [(set_attr "type" "ishift")
12006    (set_attr "length" "2")])
12007
12008 ;; This pattern can't accept a variable shift count, since shifts by
12009 ;; zero don't affect the flags.  We assume that shifts by constant
12010 ;; zero are optimized away.
12011 (define_insn "*lshrsi3_cmp"
12012   [(set (reg 17)
12013         (compare
12014           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12015                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12016           (const_int 0)))
12017    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12018         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12019   "ix86_match_ccmode (insn, CCGOCmode)
12020    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12021   "shr{l}\t{%2, %0|%0, %2}"
12022   [(set_attr "type" "ishift")
12023    (set_attr "mode" "SI")])
12024
12025 (define_insn "*lshrsi3_cmp_zext"
12026   [(set (reg 17)
12027         (compare
12028           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12029                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12030           (const_int 0)))
12031    (set (match_operand:DI 0 "register_operand" "=r")
12032         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12033   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12034    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12035   "shr{l}\t{%2, %k0|%k0, %2}"
12036   [(set_attr "type" "ishift")
12037    (set_attr "mode" "SI")])
12038
12039 (define_expand "lshrhi3"
12040   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12041         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12042                      (match_operand:QI 2 "nonmemory_operand" "")))
12043    (clobber (reg:CC FLAGS_REG))]
12044   "TARGET_HIMODE_MATH"
12045   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12046
12047 (define_insn "*lshrhi3_1_one_bit"
12048   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12049         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12050                      (match_operand:QI 2 "const1_operand" "")))
12051    (clobber (reg:CC FLAGS_REG))]
12052   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12053    && (TARGET_SHIFT1 || optimize_size)"
12054   "shr{w}\t%0"
12055   [(set_attr "type" "ishift")
12056    (set (attr "length") 
12057      (if_then_else (match_operand 0 "register_operand" "") 
12058         (const_string "2")
12059         (const_string "*")))])
12060
12061 (define_insn "*lshrhi3_1"
12062   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12063         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12064                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12065    (clobber (reg:CC FLAGS_REG))]
12066   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12067   "@
12068    shr{w}\t{%2, %0|%0, %2}
12069    shr{w}\t{%b2, %0|%0, %b2}"
12070   [(set_attr "type" "ishift")
12071    (set_attr "mode" "HI")])
12072
12073 ;; This pattern can't accept a variable shift count, since shifts by
12074 ;; zero don't affect the flags.  We assume that shifts by constant
12075 ;; zero are optimized away.
12076 (define_insn "*lshrhi3_one_bit_cmp"
12077   [(set (reg 17)
12078         (compare
12079           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12080                        (match_operand:QI 2 "const1_operand" ""))
12081           (const_int 0)))
12082    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12083         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12084   "ix86_match_ccmode (insn, CCGOCmode)
12085    && (TARGET_SHIFT1 || optimize_size)
12086    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12087   "shr{w}\t%0"
12088   [(set_attr "type" "ishift")
12089    (set (attr "length") 
12090      (if_then_else (match_operand:SI 0 "register_operand" "") 
12091         (const_string "2")
12092         (const_string "*")))])
12093
12094 ;; This pattern can't accept a variable shift count, since shifts by
12095 ;; zero don't affect the flags.  We assume that shifts by constant
12096 ;; zero are optimized away.
12097 (define_insn "*lshrhi3_cmp"
12098   [(set (reg 17)
12099         (compare
12100           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12101                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12102           (const_int 0)))
12103    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12104         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12105   "ix86_match_ccmode (insn, CCGOCmode)
12106    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12107   "shr{w}\t{%2, %0|%0, %2}"
12108   [(set_attr "type" "ishift")
12109    (set_attr "mode" "HI")])
12110
12111 (define_expand "lshrqi3"
12112   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12113         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12114                      (match_operand:QI 2 "nonmemory_operand" "")))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "TARGET_QIMODE_MATH"
12117   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12118
12119 (define_insn "*lshrqi3_1_one_bit"
12120   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12121         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12122                      (match_operand:QI 2 "const1_operand" "")))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12125    && (TARGET_SHIFT1 || optimize_size)"
12126   "shr{b}\t%0"
12127   [(set_attr "type" "ishift")
12128    (set (attr "length") 
12129      (if_then_else (match_operand 0 "register_operand" "") 
12130         (const_string "2")
12131         (const_string "*")))])
12132
12133 (define_insn "*lshrqi3_1_one_bit_slp"
12134   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12135         (lshiftrt:QI (match_dup 0)
12136                      (match_operand:QI 1 "const1_operand" "")))
12137    (clobber (reg:CC FLAGS_REG))]
12138   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12139    && (TARGET_SHIFT1 || optimize_size)"
12140   "shr{b}\t%0"
12141   [(set_attr "type" "ishift1")
12142    (set (attr "length") 
12143      (if_then_else (match_operand 0 "register_operand" "") 
12144         (const_string "2")
12145         (const_string "*")))])
12146
12147 (define_insn "*lshrqi3_1"
12148   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12149         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12150                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12151    (clobber (reg:CC FLAGS_REG))]
12152   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12153   "@
12154    shr{b}\t{%2, %0|%0, %2}
12155    shr{b}\t{%b2, %0|%0, %b2}"
12156   [(set_attr "type" "ishift")
12157    (set_attr "mode" "QI")])
12158
12159 (define_insn "*lshrqi3_1_slp"
12160   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12161         (lshiftrt:QI (match_dup 0)
12162                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12163    (clobber (reg:CC FLAGS_REG))]
12164   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12165    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12166   "@
12167    shr{b}\t{%1, %0|%0, %1}
12168    shr{b}\t{%b1, %0|%0, %b1}"
12169   [(set_attr "type" "ishift1")
12170    (set_attr "mode" "QI")])
12171
12172 ;; This pattern can't accept a variable shift count, since shifts by
12173 ;; zero don't affect the flags.  We assume that shifts by constant
12174 ;; zero are optimized away.
12175 (define_insn "*lshrqi2_one_bit_cmp"
12176   [(set (reg 17)
12177         (compare
12178           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12179                        (match_operand:QI 2 "const1_operand" ""))
12180           (const_int 0)))
12181    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12182         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12183   "ix86_match_ccmode (insn, CCGOCmode)
12184    && (TARGET_SHIFT1 || optimize_size)
12185    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12186   "shr{b}\t%0"
12187   [(set_attr "type" "ishift")
12188    (set (attr "length") 
12189      (if_then_else (match_operand:SI 0 "register_operand" "") 
12190         (const_string "2")
12191         (const_string "*")))])
12192
12193 ;; This pattern can't accept a variable shift count, since shifts by
12194 ;; zero don't affect the flags.  We assume that shifts by constant
12195 ;; zero are optimized away.
12196 (define_insn "*lshrqi2_cmp"
12197   [(set (reg 17)
12198         (compare
12199           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12200                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12201           (const_int 0)))
12202    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12203         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12204   "ix86_match_ccmode (insn, CCGOCmode)
12205    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12206   "shr{b}\t{%2, %0|%0, %2}"
12207   [(set_attr "type" "ishift")
12208    (set_attr "mode" "QI")])
12209 \f
12210 ;; Rotate instructions
12211
12212 (define_expand "rotldi3"
12213   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12214         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12215                    (match_operand:QI 2 "nonmemory_operand" "")))
12216    (clobber (reg:CC FLAGS_REG))]
12217   "TARGET_64BIT"
12218   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12219
12220 (define_insn "*rotlsi3_1_one_bit_rex64"
12221   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12222         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12223                    (match_operand:QI 2 "const1_operand" "")))
12224    (clobber (reg:CC FLAGS_REG))]
12225   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12226    && (TARGET_SHIFT1 || optimize_size)"
12227   "rol{q}\t%0"
12228   [(set_attr "type" "rotate")
12229    (set (attr "length") 
12230      (if_then_else (match_operand:DI 0 "register_operand" "") 
12231         (const_string "2")
12232         (const_string "*")))])
12233
12234 (define_insn "*rotldi3_1_rex64"
12235   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12236         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12237                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12238    (clobber (reg:CC FLAGS_REG))]
12239   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12240   "@
12241    rol{q}\t{%2, %0|%0, %2}
12242    rol{q}\t{%b2, %0|%0, %b2}"
12243   [(set_attr "type" "rotate")
12244    (set_attr "mode" "DI")])
12245
12246 (define_expand "rotlsi3"
12247   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12248         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12249                    (match_operand:QI 2 "nonmemory_operand" "")))
12250    (clobber (reg:CC FLAGS_REG))]
12251   ""
12252   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12253
12254 (define_insn "*rotlsi3_1_one_bit"
12255   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12256         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12257                    (match_operand:QI 2 "const1_operand" "")))
12258    (clobber (reg:CC FLAGS_REG))]
12259   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12260    && (TARGET_SHIFT1 || optimize_size)"
12261   "rol{l}\t%0"
12262   [(set_attr "type" "rotate")
12263    (set (attr "length") 
12264      (if_then_else (match_operand:SI 0 "register_operand" "") 
12265         (const_string "2")
12266         (const_string "*")))])
12267
12268 (define_insn "*rotlsi3_1_one_bit_zext"
12269   [(set (match_operand:DI 0 "register_operand" "=r")
12270         (zero_extend:DI
12271           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12272                      (match_operand:QI 2 "const1_operand" ""))))
12273    (clobber (reg:CC FLAGS_REG))]
12274   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12275    && (TARGET_SHIFT1 || optimize_size)"
12276   "rol{l}\t%k0"
12277   [(set_attr "type" "rotate")
12278    (set_attr "length" "2")])
12279
12280 (define_insn "*rotlsi3_1"
12281   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12282         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12283                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12284    (clobber (reg:CC FLAGS_REG))]
12285   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12286   "@
12287    rol{l}\t{%2, %0|%0, %2}
12288    rol{l}\t{%b2, %0|%0, %b2}"
12289   [(set_attr "type" "rotate")
12290    (set_attr "mode" "SI")])
12291
12292 (define_insn "*rotlsi3_1_zext"
12293   [(set (match_operand:DI 0 "register_operand" "=r,r")
12294         (zero_extend:DI
12295           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12296                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12297    (clobber (reg:CC FLAGS_REG))]
12298   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12299   "@
12300    rol{l}\t{%2, %k0|%k0, %2}
12301    rol{l}\t{%b2, %k0|%k0, %b2}"
12302   [(set_attr "type" "rotate")
12303    (set_attr "mode" "SI")])
12304
12305 (define_expand "rotlhi3"
12306   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12307         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12308                    (match_operand:QI 2 "nonmemory_operand" "")))
12309    (clobber (reg:CC FLAGS_REG))]
12310   "TARGET_HIMODE_MATH"
12311   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12312
12313 (define_insn "*rotlhi3_1_one_bit"
12314   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12315         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12316                    (match_operand:QI 2 "const1_operand" "")))
12317    (clobber (reg:CC FLAGS_REG))]
12318   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12319    && (TARGET_SHIFT1 || optimize_size)"
12320   "rol{w}\t%0"
12321   [(set_attr "type" "rotate")
12322    (set (attr "length") 
12323      (if_then_else (match_operand 0 "register_operand" "") 
12324         (const_string "2")
12325         (const_string "*")))])
12326
12327 (define_insn "*rotlhi3_1"
12328   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12329         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12330                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12331    (clobber (reg:CC FLAGS_REG))]
12332   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12333   "@
12334    rol{w}\t{%2, %0|%0, %2}
12335    rol{w}\t{%b2, %0|%0, %b2}"
12336   [(set_attr "type" "rotate")
12337    (set_attr "mode" "HI")])
12338
12339 (define_expand "rotlqi3"
12340   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12341         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12342                    (match_operand:QI 2 "nonmemory_operand" "")))
12343    (clobber (reg:CC FLAGS_REG))]
12344   "TARGET_QIMODE_MATH"
12345   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12346
12347 (define_insn "*rotlqi3_1_one_bit_slp"
12348   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12349         (rotate:QI (match_dup 0)
12350                    (match_operand:QI 1 "const1_operand" "")))
12351    (clobber (reg:CC FLAGS_REG))]
12352   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12353    && (TARGET_SHIFT1 || optimize_size)"
12354   "rol{b}\t%0"
12355   [(set_attr "type" "rotate1")
12356    (set (attr "length") 
12357      (if_then_else (match_operand 0 "register_operand" "") 
12358         (const_string "2")
12359         (const_string "*")))])
12360
12361 (define_insn "*rotlqi3_1_one_bit"
12362   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12363         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12364                    (match_operand:QI 2 "const1_operand" "")))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12367    && (TARGET_SHIFT1 || optimize_size)"
12368   "rol{b}\t%0"
12369   [(set_attr "type" "rotate")
12370    (set (attr "length") 
12371      (if_then_else (match_operand 0 "register_operand" "") 
12372         (const_string "2")
12373         (const_string "*")))])
12374
12375 (define_insn "*rotlqi3_1_slp"
12376   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12377         (rotate:QI (match_dup 0)
12378                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12379    (clobber (reg:CC FLAGS_REG))]
12380   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12381    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12382   "@
12383    rol{b}\t{%1, %0|%0, %1}
12384    rol{b}\t{%b1, %0|%0, %b1}"
12385   [(set_attr "type" "rotate1")
12386    (set_attr "mode" "QI")])
12387
12388 (define_insn "*rotlqi3_1"
12389   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12390         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12391                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12392    (clobber (reg:CC FLAGS_REG))]
12393   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12394   "@
12395    rol{b}\t{%2, %0|%0, %2}
12396    rol{b}\t{%b2, %0|%0, %b2}"
12397   [(set_attr "type" "rotate")
12398    (set_attr "mode" "QI")])
12399
12400 (define_expand "rotrdi3"
12401   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12402         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12403                      (match_operand:QI 2 "nonmemory_operand" "")))
12404    (clobber (reg:CC FLAGS_REG))]
12405   "TARGET_64BIT"
12406   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12407
12408 (define_insn "*rotrdi3_1_one_bit_rex64"
12409   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12410         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12411                      (match_operand:QI 2 "const1_operand" "")))
12412    (clobber (reg:CC FLAGS_REG))]
12413   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12414    && (TARGET_SHIFT1 || optimize_size)"
12415   "ror{q}\t%0"
12416   [(set_attr "type" "rotate")
12417    (set (attr "length") 
12418      (if_then_else (match_operand:DI 0 "register_operand" "") 
12419         (const_string "2")
12420         (const_string "*")))])
12421
12422 (define_insn "*rotrdi3_1_rex64"
12423   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12424         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12425                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12426    (clobber (reg:CC FLAGS_REG))]
12427   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12428   "@
12429    ror{q}\t{%2, %0|%0, %2}
12430    ror{q}\t{%b2, %0|%0, %b2}"
12431   [(set_attr "type" "rotate")
12432    (set_attr "mode" "DI")])
12433
12434 (define_expand "rotrsi3"
12435   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12436         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12437                      (match_operand:QI 2 "nonmemory_operand" "")))
12438    (clobber (reg:CC FLAGS_REG))]
12439   ""
12440   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12441
12442 (define_insn "*rotrsi3_1_one_bit"
12443   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12444         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12445                      (match_operand:QI 2 "const1_operand" "")))
12446    (clobber (reg:CC FLAGS_REG))]
12447   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12448    && (TARGET_SHIFT1 || optimize_size)"
12449   "ror{l}\t%0"
12450   [(set_attr "type" "rotate")
12451    (set (attr "length") 
12452      (if_then_else (match_operand:SI 0 "register_operand" "") 
12453         (const_string "2")
12454         (const_string "*")))])
12455
12456 (define_insn "*rotrsi3_1_one_bit_zext"
12457   [(set (match_operand:DI 0 "register_operand" "=r")
12458         (zero_extend:DI
12459           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12460                        (match_operand:QI 2 "const1_operand" ""))))
12461    (clobber (reg:CC FLAGS_REG))]
12462   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12463    && (TARGET_SHIFT1 || optimize_size)"
12464   "ror{l}\t%k0"
12465   [(set_attr "type" "rotate")
12466    (set (attr "length") 
12467      (if_then_else (match_operand:SI 0 "register_operand" "") 
12468         (const_string "2")
12469         (const_string "*")))])
12470
12471 (define_insn "*rotrsi3_1"
12472   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12473         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12474                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12475    (clobber (reg:CC FLAGS_REG))]
12476   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12477   "@
12478    ror{l}\t{%2, %0|%0, %2}
12479    ror{l}\t{%b2, %0|%0, %b2}"
12480   [(set_attr "type" "rotate")
12481    (set_attr "mode" "SI")])
12482
12483 (define_insn "*rotrsi3_1_zext"
12484   [(set (match_operand:DI 0 "register_operand" "=r,r")
12485         (zero_extend:DI
12486           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12487                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12488    (clobber (reg:CC FLAGS_REG))]
12489   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12490   "@
12491    ror{l}\t{%2, %k0|%k0, %2}
12492    ror{l}\t{%b2, %k0|%k0, %b2}"
12493   [(set_attr "type" "rotate")
12494    (set_attr "mode" "SI")])
12495
12496 (define_expand "rotrhi3"
12497   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12498         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12499                      (match_operand:QI 2 "nonmemory_operand" "")))
12500    (clobber (reg:CC FLAGS_REG))]
12501   "TARGET_HIMODE_MATH"
12502   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12503
12504 (define_insn "*rotrhi3_one_bit"
12505   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12506         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12507                      (match_operand:QI 2 "const1_operand" "")))
12508    (clobber (reg:CC FLAGS_REG))]
12509   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12510    && (TARGET_SHIFT1 || optimize_size)"
12511   "ror{w}\t%0"
12512   [(set_attr "type" "rotate")
12513    (set (attr "length") 
12514      (if_then_else (match_operand 0 "register_operand" "") 
12515         (const_string "2")
12516         (const_string "*")))])
12517
12518 (define_insn "*rotrhi3"
12519   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12520         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12521                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12522    (clobber (reg:CC FLAGS_REG))]
12523   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12524   "@
12525    ror{w}\t{%2, %0|%0, %2}
12526    ror{w}\t{%b2, %0|%0, %b2}"
12527   [(set_attr "type" "rotate")
12528    (set_attr "mode" "HI")])
12529
12530 (define_expand "rotrqi3"
12531   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12532         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12533                      (match_operand:QI 2 "nonmemory_operand" "")))
12534    (clobber (reg:CC FLAGS_REG))]
12535   "TARGET_QIMODE_MATH"
12536   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12537
12538 (define_insn "*rotrqi3_1_one_bit"
12539   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12540         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12541                      (match_operand:QI 2 "const1_operand" "")))
12542    (clobber (reg:CC FLAGS_REG))]
12543   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12544    && (TARGET_SHIFT1 || optimize_size)"
12545   "ror{b}\t%0"
12546   [(set_attr "type" "rotate")
12547    (set (attr "length") 
12548      (if_then_else (match_operand 0 "register_operand" "") 
12549         (const_string "2")
12550         (const_string "*")))])
12551
12552 (define_insn "*rotrqi3_1_one_bit_slp"
12553   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12554         (rotatert:QI (match_dup 0)
12555                      (match_operand:QI 1 "const1_operand" "")))
12556    (clobber (reg:CC FLAGS_REG))]
12557   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12558    && (TARGET_SHIFT1 || optimize_size)"
12559   "ror{b}\t%0"
12560   [(set_attr "type" "rotate1")
12561    (set (attr "length") 
12562      (if_then_else (match_operand 0 "register_operand" "") 
12563         (const_string "2")
12564         (const_string "*")))])
12565
12566 (define_insn "*rotrqi3_1"
12567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12568         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12569                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12570    (clobber (reg:CC FLAGS_REG))]
12571   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12572   "@
12573    ror{b}\t{%2, %0|%0, %2}
12574    ror{b}\t{%b2, %0|%0, %b2}"
12575   [(set_attr "type" "rotate")
12576    (set_attr "mode" "QI")])
12577
12578 (define_insn "*rotrqi3_1_slp"
12579   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12580         (rotatert:QI (match_dup 0)
12581                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12582    (clobber (reg:CC FLAGS_REG))]
12583   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12584    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12585   "@
12586    ror{b}\t{%1, %0|%0, %1}
12587    ror{b}\t{%b1, %0|%0, %b1}"
12588   [(set_attr "type" "rotate1")
12589    (set_attr "mode" "QI")])
12590 \f
12591 ;; Bit set / bit test instructions
12592
12593 (define_expand "extv"
12594   [(set (match_operand:SI 0 "register_operand" "")
12595         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12596                          (match_operand:SI 2 "immediate_operand" "")
12597                          (match_operand:SI 3 "immediate_operand" "")))]
12598   ""
12599 {
12600   /* Handle extractions from %ah et al.  */
12601   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12602     FAIL;
12603
12604   /* From mips.md: extract_bit_field doesn't verify that our source
12605      matches the predicate, so check it again here.  */
12606   if (! register_operand (operands[1], VOIDmode))
12607     FAIL;
12608 })
12609
12610 (define_expand "extzv"
12611   [(set (match_operand:SI 0 "register_operand" "")
12612         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12613                          (match_operand:SI 2 "immediate_operand" "")
12614                          (match_operand:SI 3 "immediate_operand" "")))]
12615   ""
12616 {
12617   /* Handle extractions from %ah et al.  */
12618   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12619     FAIL;
12620
12621   /* From mips.md: extract_bit_field doesn't verify that our source
12622      matches the predicate, so check it again here.  */
12623   if (! register_operand (operands[1], VOIDmode))
12624     FAIL;
12625 })
12626
12627 (define_expand "insv"
12628   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12629                       (match_operand 1 "immediate_operand" "")
12630                       (match_operand 2 "immediate_operand" ""))
12631         (match_operand 3 "register_operand" ""))]
12632   ""
12633 {
12634   /* Handle extractions from %ah et al.  */
12635   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12636     FAIL;
12637
12638   /* From mips.md: insert_bit_field doesn't verify that our source
12639      matches the predicate, so check it again here.  */
12640   if (! register_operand (operands[0], VOIDmode))
12641     FAIL;
12642
12643   if (TARGET_64BIT)
12644     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12645   else
12646     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12647
12648   DONE;
12649 })
12650
12651 ;; %%% bts, btr, btc, bt.
12652 \f
12653 ;; Store-flag instructions.
12654
12655 ;; For all sCOND expanders, also expand the compare or test insn that
12656 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12657
12658 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12659 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12660 ;; way, which can later delete the movzx if only QImode is needed.
12661
12662 (define_expand "seq"
12663   [(set (match_operand:QI 0 "register_operand" "")
12664         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12665   ""
12666   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12667
12668 (define_expand "sne"
12669   [(set (match_operand:QI 0 "register_operand" "")
12670         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12671   ""
12672   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12673
12674 (define_expand "sgt"
12675   [(set (match_operand:QI 0 "register_operand" "")
12676         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12677   ""
12678   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12679
12680 (define_expand "sgtu"
12681   [(set (match_operand:QI 0 "register_operand" "")
12682         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12683   ""
12684   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12685
12686 (define_expand "slt"
12687   [(set (match_operand:QI 0 "register_operand" "")
12688         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12689   ""
12690   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12691
12692 (define_expand "sltu"
12693   [(set (match_operand:QI 0 "register_operand" "")
12694         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12695   ""
12696   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12697
12698 (define_expand "sge"
12699   [(set (match_operand:QI 0 "register_operand" "")
12700         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12701   ""
12702   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12703
12704 (define_expand "sgeu"
12705   [(set (match_operand:QI 0 "register_operand" "")
12706         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12707   ""
12708   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12709
12710 (define_expand "sle"
12711   [(set (match_operand:QI 0 "register_operand" "")
12712         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713   ""
12714   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "sleu"
12717   [(set (match_operand:QI 0 "register_operand" "")
12718         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719   ""
12720   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sunordered"
12723   [(set (match_operand:QI 0 "register_operand" "")
12724         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725   "TARGET_80387 || TARGET_SSE"
12726   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sordered"
12729   [(set (match_operand:QI 0 "register_operand" "")
12730         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731   "TARGET_80387"
12732   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "suneq"
12735   [(set (match_operand:QI 0 "register_operand" "")
12736         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737   "TARGET_80387 || TARGET_SSE"
12738   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sunge"
12741   [(set (match_operand:QI 0 "register_operand" "")
12742         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12743   "TARGET_80387 || TARGET_SSE"
12744   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12745
12746 (define_expand "sungt"
12747   [(set (match_operand:QI 0 "register_operand" "")
12748         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12749   "TARGET_80387 || TARGET_SSE"
12750   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12751
12752 (define_expand "sunle"
12753   [(set (match_operand:QI 0 "register_operand" "")
12754         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12755   "TARGET_80387 || TARGET_SSE"
12756   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12757
12758 (define_expand "sunlt"
12759   [(set (match_operand:QI 0 "register_operand" "")
12760         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12761   "TARGET_80387 || TARGET_SSE"
12762   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12763
12764 (define_expand "sltgt"
12765   [(set (match_operand:QI 0 "register_operand" "")
12766         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12767   "TARGET_80387 || TARGET_SSE"
12768   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12769
12770 (define_insn "*setcc_1"
12771   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12772         (match_operator:QI 1 "ix86_comparison_operator"
12773           [(reg 17) (const_int 0)]))]
12774   ""
12775   "set%C1\t%0"
12776   [(set_attr "type" "setcc")
12777    (set_attr "mode" "QI")])
12778
12779 (define_insn "setcc_2"
12780   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12781         (match_operator:QI 1 "ix86_comparison_operator"
12782           [(reg 17) (const_int 0)]))]
12783   ""
12784   "set%C1\t%0"
12785   [(set_attr "type" "setcc")
12786    (set_attr "mode" "QI")])
12787
12788 ;; In general it is not safe to assume too much about CCmode registers,
12789 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12790 ;; conditions this is safe on x86, so help combine not create
12791 ;;
12792 ;;      seta    %al
12793 ;;      testb   %al, %al
12794 ;;      sete    %al
12795
12796 (define_split 
12797   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12798         (ne:QI (match_operator 1 "ix86_comparison_operator"
12799                  [(reg 17) (const_int 0)])
12800             (const_int 0)))]
12801   ""
12802   [(set (match_dup 0) (match_dup 1))]
12803 {
12804   PUT_MODE (operands[1], QImode);
12805 })
12806
12807 (define_split 
12808   [(set (strict_low_part (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 (match_operand:QI 0 "nonimmediate_operand" "")
12820         (eq: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   rtx new_op1 = copy_rtx (operands[1]);
12827   operands[1] = new_op1;
12828   PUT_MODE (new_op1, QImode);
12829   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12830                                              GET_MODE (XEXP (new_op1, 0))));
12831
12832   /* Make sure that (a) the CCmode we have for the flags is strong
12833      enough for the reversed compare or (b) we have a valid FP compare.  */
12834   if (! ix86_comparison_operator (new_op1, VOIDmode))
12835     FAIL;
12836 })
12837
12838 (define_split 
12839   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12840         (eq:QI (match_operator 1 "ix86_comparison_operator"
12841                  [(reg 17) (const_int 0)])
12842             (const_int 0)))]
12843   ""
12844   [(set (match_dup 0) (match_dup 1))]
12845 {
12846   rtx new_op1 = copy_rtx (operands[1]);
12847   operands[1] = new_op1;
12848   PUT_MODE (new_op1, QImode);
12849   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12850                                              GET_MODE (XEXP (new_op1, 0))));
12851
12852   /* Make sure that (a) the CCmode we have for the flags is strong
12853      enough for the reversed compare or (b) we have a valid FP compare.  */
12854   if (! ix86_comparison_operator (new_op1, VOIDmode))
12855     FAIL;
12856 })
12857
12858 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12859 ;; subsequent logical operations are used to imitate conditional moves.
12860 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12861 ;; it directly.  Further holding this value in pseudo register might bring
12862 ;; problem in implicit normalization in spill code.
12863 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12864 ;; instructions after reload by splitting the conditional move patterns.
12865
12866 (define_insn "*sse_setccsf"
12867   [(set (match_operand:SF 0 "register_operand" "=x")
12868         (match_operator:SF 1 "sse_comparison_operator"
12869           [(match_operand:SF 2 "register_operand" "0")
12870            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12871   "TARGET_SSE && reload_completed"
12872   "cmp%D1ss\t{%3, %0|%0, %3}"
12873   [(set_attr "type" "ssecmp")
12874    (set_attr "mode" "SF")])
12875
12876 (define_insn "*sse_setccdf"
12877   [(set (match_operand:DF 0 "register_operand" "=Y")
12878         (match_operator:DF 1 "sse_comparison_operator"
12879           [(match_operand:DF 2 "register_operand" "0")
12880            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12881   "TARGET_SSE2 && reload_completed"
12882   "cmp%D1sd\t{%3, %0|%0, %3}"
12883   [(set_attr "type" "ssecmp")
12884    (set_attr "mode" "DF")])
12885 \f
12886 ;; Basic conditional jump instructions.
12887 ;; We ignore the overflow flag for signed branch instructions.
12888
12889 ;; For all bCOND expanders, also expand the compare or test insn that
12890 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12891
12892 (define_expand "beq"
12893   [(set (pc)
12894         (if_then_else (match_dup 1)
12895                       (label_ref (match_operand 0 "" ""))
12896                       (pc)))]
12897   ""
12898   "ix86_expand_branch (EQ, operands[0]); DONE;")
12899
12900 (define_expand "bne"
12901   [(set (pc)
12902         (if_then_else (match_dup 1)
12903                       (label_ref (match_operand 0 "" ""))
12904                       (pc)))]
12905   ""
12906   "ix86_expand_branch (NE, operands[0]); DONE;")
12907
12908 (define_expand "bgt"
12909   [(set (pc)
12910         (if_then_else (match_dup 1)
12911                       (label_ref (match_operand 0 "" ""))
12912                       (pc)))]
12913   ""
12914   "ix86_expand_branch (GT, operands[0]); DONE;")
12915
12916 (define_expand "bgtu"
12917   [(set (pc)
12918         (if_then_else (match_dup 1)
12919                       (label_ref (match_operand 0 "" ""))
12920                       (pc)))]
12921   ""
12922   "ix86_expand_branch (GTU, operands[0]); DONE;")
12923
12924 (define_expand "blt"
12925   [(set (pc)
12926         (if_then_else (match_dup 1)
12927                       (label_ref (match_operand 0 "" ""))
12928                       (pc)))]
12929   ""
12930   "ix86_expand_branch (LT, operands[0]); DONE;")
12931
12932 (define_expand "bltu"
12933   [(set (pc)
12934         (if_then_else (match_dup 1)
12935                       (label_ref (match_operand 0 "" ""))
12936                       (pc)))]
12937   ""
12938   "ix86_expand_branch (LTU, operands[0]); DONE;")
12939
12940 (define_expand "bge"
12941   [(set (pc)
12942         (if_then_else (match_dup 1)
12943                       (label_ref (match_operand 0 "" ""))
12944                       (pc)))]
12945   ""
12946   "ix86_expand_branch (GE, operands[0]); DONE;")
12947
12948 (define_expand "bgeu"
12949   [(set (pc)
12950         (if_then_else (match_dup 1)
12951                       (label_ref (match_operand 0 "" ""))
12952                       (pc)))]
12953   ""
12954   "ix86_expand_branch (GEU, operands[0]); DONE;")
12955
12956 (define_expand "ble"
12957   [(set (pc)
12958         (if_then_else (match_dup 1)
12959                       (label_ref (match_operand 0 "" ""))
12960                       (pc)))]
12961   ""
12962   "ix86_expand_branch (LE, operands[0]); DONE;")
12963
12964 (define_expand "bleu"
12965   [(set (pc)
12966         (if_then_else (match_dup 1)
12967                       (label_ref (match_operand 0 "" ""))
12968                       (pc)))]
12969   ""
12970   "ix86_expand_branch (LEU, operands[0]); DONE;")
12971
12972 (define_expand "bunordered"
12973   [(set (pc)
12974         (if_then_else (match_dup 1)
12975                       (label_ref (match_operand 0 "" ""))
12976                       (pc)))]
12977   "TARGET_80387 || TARGET_SSE"
12978   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12979
12980 (define_expand "bordered"
12981   [(set (pc)
12982         (if_then_else (match_dup 1)
12983                       (label_ref (match_operand 0 "" ""))
12984                       (pc)))]
12985   "TARGET_80387 || TARGET_SSE"
12986   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12987
12988 (define_expand "buneq"
12989   [(set (pc)
12990         (if_then_else (match_dup 1)
12991                       (label_ref (match_operand 0 "" ""))
12992                       (pc)))]
12993   "TARGET_80387 || TARGET_SSE"
12994   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12995
12996 (define_expand "bunge"
12997   [(set (pc)
12998         (if_then_else (match_dup 1)
12999                       (label_ref (match_operand 0 "" ""))
13000                       (pc)))]
13001   "TARGET_80387 || TARGET_SSE"
13002   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13003
13004 (define_expand "bungt"
13005   [(set (pc)
13006         (if_then_else (match_dup 1)
13007                       (label_ref (match_operand 0 "" ""))
13008                       (pc)))]
13009   "TARGET_80387 || TARGET_SSE"
13010   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13011
13012 (define_expand "bunle"
13013   [(set (pc)
13014         (if_then_else (match_dup 1)
13015                       (label_ref (match_operand 0 "" ""))
13016                       (pc)))]
13017   "TARGET_80387 || TARGET_SSE"
13018   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13019
13020 (define_expand "bunlt"
13021   [(set (pc)
13022         (if_then_else (match_dup 1)
13023                       (label_ref (match_operand 0 "" ""))
13024                       (pc)))]
13025   "TARGET_80387 || TARGET_SSE"
13026   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13027
13028 (define_expand "bltgt"
13029   [(set (pc)
13030         (if_then_else (match_dup 1)
13031                       (label_ref (match_operand 0 "" ""))
13032                       (pc)))]
13033   "TARGET_80387 || TARGET_SSE"
13034   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13035
13036 (define_insn "*jcc_1"
13037   [(set (pc)
13038         (if_then_else (match_operator 1 "ix86_comparison_operator"
13039                                       [(reg 17) (const_int 0)])
13040                       (label_ref (match_operand 0 "" ""))
13041                       (pc)))]
13042   ""
13043   "%+j%C1\t%l0"
13044   [(set_attr "type" "ibr")
13045    (set_attr "modrm" "0")
13046    (set (attr "length")
13047            (if_then_else (and (ge (minus (match_dup 0) (pc))
13048                                   (const_int -126))
13049                               (lt (minus (match_dup 0) (pc))
13050                                   (const_int 128)))
13051              (const_int 2)
13052              (const_int 6)))])
13053
13054 (define_insn "*jcc_2"
13055   [(set (pc)
13056         (if_then_else (match_operator 1 "ix86_comparison_operator"
13057                                       [(reg 17) (const_int 0)])
13058                       (pc)
13059                       (label_ref (match_operand 0 "" ""))))]
13060   ""
13061   "%+j%c1\t%l0"
13062   [(set_attr "type" "ibr")
13063    (set_attr "modrm" "0")
13064    (set (attr "length")
13065            (if_then_else (and (ge (minus (match_dup 0) (pc))
13066                                   (const_int -126))
13067                               (lt (minus (match_dup 0) (pc))
13068                                   (const_int 128)))
13069              (const_int 2)
13070              (const_int 6)))])
13071
13072 ;; In general it is not safe to assume too much about CCmode registers,
13073 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13074 ;; conditions this is safe on x86, so help combine not create
13075 ;;
13076 ;;      seta    %al
13077 ;;      testb   %al, %al
13078 ;;      je      Lfoo
13079
13080 (define_split 
13081   [(set (pc)
13082         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13083                                       [(reg 17) (const_int 0)])
13084                           (const_int 0))
13085                       (label_ref (match_operand 1 "" ""))
13086                       (pc)))]
13087   ""
13088   [(set (pc)
13089         (if_then_else (match_dup 0)
13090                       (label_ref (match_dup 1))
13091                       (pc)))]
13092 {
13093   PUT_MODE (operands[0], VOIDmode);
13094 })
13095   
13096 (define_split 
13097   [(set (pc)
13098         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13099                                       [(reg 17) (const_int 0)])
13100                           (const_int 0))
13101                       (label_ref (match_operand 1 "" ""))
13102                       (pc)))]
13103   ""
13104   [(set (pc)
13105         (if_then_else (match_dup 0)
13106                       (label_ref (match_dup 1))
13107                       (pc)))]
13108 {
13109   rtx new_op0 = copy_rtx (operands[0]);
13110   operands[0] = new_op0;
13111   PUT_MODE (new_op0, VOIDmode);
13112   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13113                                              GET_MODE (XEXP (new_op0, 0))));
13114
13115   /* Make sure that (a) the CCmode we have for the flags is strong
13116      enough for the reversed compare or (b) we have a valid FP compare.  */
13117   if (! ix86_comparison_operator (new_op0, VOIDmode))
13118     FAIL;
13119 })
13120
13121 ;; Define combination compare-and-branch fp compare instructions to use
13122 ;; during early optimization.  Splitting the operation apart early makes
13123 ;; for bad code when we want to reverse the operation.
13124
13125 (define_insn "*fp_jcc_1"
13126   [(set (pc)
13127         (if_then_else (match_operator 0 "comparison_operator"
13128                         [(match_operand 1 "register_operand" "f")
13129                          (match_operand 2 "register_operand" "f")])
13130           (label_ref (match_operand 3 "" ""))
13131           (pc)))
13132    (clobber (reg:CCFP FPSR_REG))
13133    (clobber (reg:CCFP FLAGS_REG))]
13134   "TARGET_CMOVE && TARGET_80387
13135    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13136    && FLOAT_MODE_P (GET_MODE (operands[1]))
13137    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13138    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13139   "#")
13140
13141 (define_insn "*fp_jcc_1_sse"
13142   [(set (pc)
13143         (if_then_else (match_operator 0 "comparison_operator"
13144                         [(match_operand 1 "register_operand" "f#x,x#f")
13145                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13146           (label_ref (match_operand 3 "" ""))
13147           (pc)))
13148    (clobber (reg:CCFP FPSR_REG))
13149    (clobber (reg:CCFP FLAGS_REG))]
13150   "TARGET_80387
13151    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13152    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13153    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13154   "#")
13155
13156 (define_insn "*fp_jcc_1_sse_only"
13157   [(set (pc)
13158         (if_then_else (match_operator 0 "comparison_operator"
13159                         [(match_operand 1 "register_operand" "x")
13160                          (match_operand 2 "nonimmediate_operand" "xm")])
13161           (label_ref (match_operand 3 "" ""))
13162           (pc)))
13163    (clobber (reg:CCFP FPSR_REG))
13164    (clobber (reg:CCFP FLAGS_REG))]
13165   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13166    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13167    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13168   "#")
13169
13170 (define_insn "*fp_jcc_2"
13171   [(set (pc)
13172         (if_then_else (match_operator 0 "comparison_operator"
13173                         [(match_operand 1 "register_operand" "f")
13174                          (match_operand 2 "register_operand" "f")])
13175           (pc)
13176           (label_ref (match_operand 3 "" ""))))
13177    (clobber (reg:CCFP FPSR_REG))
13178    (clobber (reg:CCFP FLAGS_REG))]
13179   "TARGET_CMOVE && TARGET_80387
13180    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13181    && FLOAT_MODE_P (GET_MODE (operands[1]))
13182    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13183    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13184   "#")
13185
13186 (define_insn "*fp_jcc_2_sse"
13187   [(set (pc)
13188         (if_then_else (match_operator 0 "comparison_operator"
13189                         [(match_operand 1 "register_operand" "f#x,x#f")
13190                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13191           (pc)
13192           (label_ref (match_operand 3 "" ""))))
13193    (clobber (reg:CCFP FPSR_REG))
13194    (clobber (reg:CCFP FLAGS_REG))]
13195   "TARGET_80387
13196    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13197    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13198    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13199   "#")
13200
13201 (define_insn "*fp_jcc_2_sse_only"
13202   [(set (pc)
13203         (if_then_else (match_operator 0 "comparison_operator"
13204                         [(match_operand 1 "register_operand" "x")
13205                          (match_operand 2 "nonimmediate_operand" "xm")])
13206           (pc)
13207           (label_ref (match_operand 3 "" ""))))
13208    (clobber (reg:CCFP FPSR_REG))
13209    (clobber (reg:CCFP FLAGS_REG))]
13210   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13211    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13212    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13213   "#")
13214
13215 (define_insn "*fp_jcc_3"
13216   [(set (pc)
13217         (if_then_else (match_operator 0 "comparison_operator"
13218                         [(match_operand 1 "register_operand" "f")
13219                          (match_operand 2 "nonimmediate_operand" "fm")])
13220           (label_ref (match_operand 3 "" ""))
13221           (pc)))
13222    (clobber (reg:CCFP FPSR_REG))
13223    (clobber (reg:CCFP FLAGS_REG))
13224    (clobber (match_scratch:HI 4 "=a"))]
13225   "TARGET_80387
13226    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13227    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13228    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13229    && SELECT_CC_MODE (GET_CODE (operands[0]),
13230                       operands[1], operands[2]) == CCFPmode
13231    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13232   "#")
13233
13234 (define_insn "*fp_jcc_4"
13235   [(set (pc)
13236         (if_then_else (match_operator 0 "comparison_operator"
13237                         [(match_operand 1 "register_operand" "f")
13238                          (match_operand 2 "nonimmediate_operand" "fm")])
13239           (pc)
13240           (label_ref (match_operand 3 "" ""))))
13241    (clobber (reg:CCFP FPSR_REG))
13242    (clobber (reg:CCFP FLAGS_REG))
13243    (clobber (match_scratch:HI 4 "=a"))]
13244   "TARGET_80387
13245    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13246    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13247    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13248    && SELECT_CC_MODE (GET_CODE (operands[0]),
13249                       operands[1], operands[2]) == CCFPmode
13250    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13251   "#")
13252
13253 (define_insn "*fp_jcc_5"
13254   [(set (pc)
13255         (if_then_else (match_operator 0 "comparison_operator"
13256                         [(match_operand 1 "register_operand" "f")
13257                          (match_operand 2 "register_operand" "f")])
13258           (label_ref (match_operand 3 "" ""))
13259           (pc)))
13260    (clobber (reg:CCFP FPSR_REG))
13261    (clobber (reg:CCFP FLAGS_REG))
13262    (clobber (match_scratch:HI 4 "=a"))]
13263   "TARGET_80387
13264    && FLOAT_MODE_P (GET_MODE (operands[1]))
13265    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13266    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13267   "#")
13268
13269 (define_insn "*fp_jcc_6"
13270   [(set (pc)
13271         (if_then_else (match_operator 0 "comparison_operator"
13272                         [(match_operand 1 "register_operand" "f")
13273                          (match_operand 2 "register_operand" "f")])
13274           (pc)
13275           (label_ref (match_operand 3 "" ""))))
13276    (clobber (reg:CCFP FPSR_REG))
13277    (clobber (reg:CCFP FLAGS_REG))
13278    (clobber (match_scratch:HI 4 "=a"))]
13279   "TARGET_80387
13280    && FLOAT_MODE_P (GET_MODE (operands[1]))
13281    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13282    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13283   "#")
13284
13285 (define_split
13286   [(set (pc)
13287         (if_then_else (match_operator 0 "comparison_operator"
13288                         [(match_operand 1 "register_operand" "")
13289                          (match_operand 2 "nonimmediate_operand" "")])
13290           (match_operand 3 "" "")
13291           (match_operand 4 "" "")))
13292    (clobber (reg:CCFP FPSR_REG))
13293    (clobber (reg:CCFP FLAGS_REG))]
13294   "reload_completed"
13295   [(const_int 0)]
13296 {
13297   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13298                         operands[3], operands[4], NULL_RTX);
13299   DONE;
13300 })
13301
13302 (define_split
13303   [(set (pc)
13304         (if_then_else (match_operator 0 "comparison_operator"
13305                         [(match_operand 1 "register_operand" "")
13306                          (match_operand 2 "nonimmediate_operand" "")])
13307           (match_operand 3 "" "")
13308           (match_operand 4 "" "")))
13309    (clobber (reg:CCFP FPSR_REG))
13310    (clobber (reg:CCFP FLAGS_REG))
13311    (clobber (match_scratch:HI 5 "=a"))]
13312   "reload_completed"
13313   [(set (pc)
13314         (if_then_else (match_dup 6)
13315           (match_dup 3)
13316           (match_dup 4)))]
13317 {
13318   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13319                         operands[3], operands[4], operands[5]);
13320   DONE;
13321 })
13322 \f
13323 ;; Unconditional and other jump instructions
13324
13325 (define_insn "jump"
13326   [(set (pc)
13327         (label_ref (match_operand 0 "" "")))]
13328   ""
13329   "jmp\t%l0"
13330   [(set_attr "type" "ibr")
13331    (set (attr "length")
13332            (if_then_else (and (ge (minus (match_dup 0) (pc))
13333                                   (const_int -126))
13334                               (lt (minus (match_dup 0) (pc))
13335                                   (const_int 128)))
13336              (const_int 2)
13337              (const_int 5)))
13338    (set_attr "modrm" "0")])
13339
13340 (define_expand "indirect_jump"
13341   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13342   ""
13343   "")
13344
13345 (define_insn "*indirect_jump"
13346   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13347   "!TARGET_64BIT"
13348   "jmp\t%A0"
13349   [(set_attr "type" "ibr")
13350    (set_attr "length_immediate" "0")])
13351
13352 (define_insn "*indirect_jump_rtx64"
13353   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13354   "TARGET_64BIT"
13355   "jmp\t%A0"
13356   [(set_attr "type" "ibr")
13357    (set_attr "length_immediate" "0")])
13358
13359 (define_expand "tablejump"
13360   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13361               (use (label_ref (match_operand 1 "" "")))])]
13362   ""
13363 {
13364   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13365      relative.  Convert the relative address to an absolute address.  */
13366   if (flag_pic)
13367     {
13368       rtx op0, op1;
13369       enum rtx_code code;
13370
13371       if (TARGET_64BIT)
13372         {
13373           code = PLUS;
13374           op0 = operands[0];
13375           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13376         }
13377       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13378         {
13379           code = PLUS;
13380           op0 = operands[0];
13381           op1 = pic_offset_table_rtx;
13382         }
13383       else
13384         {
13385           code = MINUS;
13386           op0 = pic_offset_table_rtx;
13387           op1 = operands[0];
13388         }
13389
13390       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13391                                          OPTAB_DIRECT);
13392     }
13393 })
13394
13395 (define_insn "*tablejump_1"
13396   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13397    (use (label_ref (match_operand 1 "" "")))]
13398   "!TARGET_64BIT"
13399   "jmp\t%A0"
13400   [(set_attr "type" "ibr")
13401    (set_attr "length_immediate" "0")])
13402
13403 (define_insn "*tablejump_1_rtx64"
13404   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13405    (use (label_ref (match_operand 1 "" "")))]
13406   "TARGET_64BIT"
13407   "jmp\t%A0"
13408   [(set_attr "type" "ibr")
13409    (set_attr "length_immediate" "0")])
13410 \f
13411 ;; Loop instruction
13412 ;;
13413 ;; This is all complicated by the fact that since this is a jump insn
13414 ;; we must handle our own reloads.
13415
13416 (define_expand "doloop_end"
13417   [(use (match_operand 0 "" ""))        ; loop pseudo
13418    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13419    (use (match_operand 2 "" ""))        ; max iterations
13420    (use (match_operand 3 "" ""))        ; loop level 
13421    (use (match_operand 4 "" ""))]       ; label
13422   "!TARGET_64BIT && TARGET_USE_LOOP"
13423   "                                 
13424 {
13425   /* Only use cloop on innermost loops.  */
13426   if (INTVAL (operands[3]) > 1)
13427     FAIL;
13428   if (GET_MODE (operands[0]) != SImode)
13429     FAIL;
13430   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13431                                            operands[0]));
13432   DONE;
13433 }")
13434
13435 (define_insn "doloop_end_internal"
13436   [(set (pc)
13437         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13438                           (const_int 1))
13439                       (label_ref (match_operand 0 "" ""))
13440                       (pc)))
13441    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13442         (plus:SI (match_dup 1)
13443                  (const_int -1)))
13444    (clobber (match_scratch:SI 3 "=X,X,r"))
13445    (clobber (reg:CC FLAGS_REG))]
13446   "!TARGET_64BIT && TARGET_USE_LOOP
13447    && (reload_in_progress || reload_completed
13448        || register_operand (operands[2], VOIDmode))"
13449 {
13450   if (which_alternative != 0)
13451     return "#";
13452   if (get_attr_length (insn) == 2)
13453     return "%+loop\t%l0";
13454   else
13455     return "dec{l}\t%1\;%+jne\t%l0";
13456 }
13457   [(set (attr "length")
13458         (if_then_else (and (eq_attr "alternative" "0")
13459                            (and (ge (minus (match_dup 0) (pc))
13460                                     (const_int -126))
13461                                 (lt (minus (match_dup 0) (pc))
13462                                     (const_int 128))))
13463                       (const_int 2)
13464                       (const_int 16)))
13465    ;; We don't know the type before shorten branches.  Optimistically expect
13466    ;; the loop instruction to match.
13467    (set (attr "type") (const_string "ibr"))])
13468
13469 (define_split
13470   [(set (pc)
13471         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13472                           (const_int 1))
13473                       (match_operand 0 "" "")
13474                       (pc)))
13475    (set (match_dup 1)
13476         (plus:SI (match_dup 1)
13477                  (const_int -1)))
13478    (clobber (match_scratch:SI 2 ""))
13479    (clobber (reg:CC FLAGS_REG))]
13480   "!TARGET_64BIT && TARGET_USE_LOOP
13481    && reload_completed
13482    && REGNO (operands[1]) != 2"
13483   [(parallel [(set (reg:CCZ FLAGS_REG)
13484                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13485                                  (const_int 0)))
13486               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13487    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13488                            (match_dup 0)
13489                            (pc)))]
13490   "")
13491   
13492 (define_split
13493   [(set (pc)
13494         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13495                           (const_int 1))
13496                       (match_operand 0 "" "")
13497                       (pc)))
13498    (set (match_operand:SI 2 "nonimmediate_operand" "")
13499         (plus:SI (match_dup 1)
13500                  (const_int -1)))
13501    (clobber (match_scratch:SI 3 ""))
13502    (clobber (reg:CC FLAGS_REG))]
13503   "!TARGET_64BIT && TARGET_USE_LOOP
13504    && reload_completed
13505    && (! REG_P (operands[2])
13506        || ! rtx_equal_p (operands[1], operands[2]))"
13507   [(set (match_dup 3) (match_dup 1))
13508    (parallel [(set (reg:CCZ FLAGS_REG)
13509                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13510                                 (const_int 0)))
13511               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13512    (set (match_dup 2) (match_dup 3))
13513    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13514                            (match_dup 0)
13515                            (pc)))]
13516   "")
13517
13518 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13519
13520 (define_peephole2
13521   [(set (reg 17) (match_operand 0 "" ""))
13522    (set (match_operand:QI 1 "register_operand" "")
13523         (match_operator:QI 2 "ix86_comparison_operator"
13524           [(reg 17) (const_int 0)]))
13525    (set (match_operand 3 "q_regs_operand" "")
13526         (zero_extend (match_dup 1)))]
13527   "(peep2_reg_dead_p (3, operands[1])
13528     || operands_match_p (operands[1], operands[3]))
13529    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13530   [(set (match_dup 4) (match_dup 0))
13531    (set (strict_low_part (match_dup 5))
13532         (match_dup 2))]
13533 {
13534   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13535   operands[5] = gen_lowpart (QImode, operands[3]);
13536   ix86_expand_clear (operands[3]);
13537 })
13538
13539 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13540
13541 (define_peephole2
13542   [(set (reg 17) (match_operand 0 "" ""))
13543    (set (match_operand:QI 1 "register_operand" "")
13544         (match_operator:QI 2 "ix86_comparison_operator"
13545           [(reg 17) (const_int 0)]))
13546    (parallel [(set (match_operand 3 "q_regs_operand" "")
13547                    (zero_extend (match_dup 1)))
13548               (clobber (reg:CC FLAGS_REG))])]
13549   "(peep2_reg_dead_p (3, operands[1])
13550     || operands_match_p (operands[1], operands[3]))
13551    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13552   [(set (match_dup 4) (match_dup 0))
13553    (set (strict_low_part (match_dup 5))
13554         (match_dup 2))]
13555 {
13556   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13557   operands[5] = gen_lowpart (QImode, operands[3]);
13558   ix86_expand_clear (operands[3]);
13559 })
13560 \f
13561 ;; Call instructions.
13562
13563 ;; The predicates normally associated with named expanders are not properly
13564 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13565 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13566
13567 ;; Call subroutine returning no value.
13568
13569 (define_expand "call_pop"
13570   [(parallel [(call (match_operand:QI 0 "" "")
13571                     (match_operand:SI 1 "" ""))
13572               (set (reg:SI SP_REG)
13573                    (plus:SI (reg:SI SP_REG)
13574                             (match_operand:SI 3 "" "")))])]
13575   "!TARGET_64BIT"
13576 {
13577   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13578   DONE;
13579 })
13580
13581 (define_insn "*call_pop_0"
13582   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13583          (match_operand:SI 1 "" ""))
13584    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13585                             (match_operand:SI 2 "immediate_operand" "")))]
13586   "!TARGET_64BIT"
13587 {
13588   if (SIBLING_CALL_P (insn))
13589     return "jmp\t%P0";
13590   else
13591     return "call\t%P0";
13592 }
13593   [(set_attr "type" "call")])
13594   
13595 (define_insn "*call_pop_1"
13596   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13597          (match_operand:SI 1 "" ""))
13598    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13599                             (match_operand:SI 2 "immediate_operand" "i")))]
13600   "!TARGET_64BIT"
13601 {
13602   if (constant_call_address_operand (operands[0], Pmode))
13603     {
13604       if (SIBLING_CALL_P (insn))
13605         return "jmp\t%P0";
13606       else
13607         return "call\t%P0";
13608     }
13609   if (SIBLING_CALL_P (insn))
13610     return "jmp\t%A0";
13611   else
13612     return "call\t%A0";
13613 }
13614   [(set_attr "type" "call")])
13615
13616 (define_expand "call"
13617   [(call (match_operand:QI 0 "" "")
13618          (match_operand 1 "" ""))
13619    (use (match_operand 2 "" ""))]
13620   ""
13621 {
13622   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13623   DONE;
13624 })
13625
13626 (define_expand "sibcall"
13627   [(call (match_operand:QI 0 "" "")
13628          (match_operand 1 "" ""))
13629    (use (match_operand 2 "" ""))]
13630   ""
13631 {
13632   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13633   DONE;
13634 })
13635
13636 (define_insn "*call_0"
13637   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13638          (match_operand 1 "" ""))]
13639   ""
13640 {
13641   if (SIBLING_CALL_P (insn))
13642     return "jmp\t%P0";
13643   else
13644     return "call\t%P0";
13645 }
13646   [(set_attr "type" "call")])
13647
13648 (define_insn "*call_1"
13649   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13650          (match_operand 1 "" ""))]
13651   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13652 {
13653   if (constant_call_address_operand (operands[0], QImode))
13654     return "call\t%P0";
13655   return "call\t%A0";
13656 }
13657   [(set_attr "type" "call")])
13658
13659 (define_insn "*sibcall_1"
13660   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13661          (match_operand 1 "" ""))]
13662   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13663 {
13664   if (constant_call_address_operand (operands[0], QImode))
13665     return "jmp\t%P0";
13666   return "jmp\t%A0";
13667 }
13668   [(set_attr "type" "call")])
13669
13670 (define_insn "*call_1_rex64"
13671   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13672          (match_operand 1 "" ""))]
13673   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13674 {
13675   if (constant_call_address_operand (operands[0], QImode))
13676     return "call\t%P0";
13677   return "call\t%A0";
13678 }
13679   [(set_attr "type" "call")])
13680
13681 (define_insn "*sibcall_1_rex64"
13682   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13683          (match_operand 1 "" ""))]
13684   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13685   "jmp\t%P0"
13686   [(set_attr "type" "call")])
13687
13688 (define_insn "*sibcall_1_rex64_v"
13689   [(call (mem:QI (reg:DI 40))
13690          (match_operand 0 "" ""))]
13691   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13692   "jmp\t*%%r11"
13693   [(set_attr "type" "call")])
13694
13695
13696 ;; Call subroutine, returning value in operand 0
13697
13698 (define_expand "call_value_pop"
13699   [(parallel [(set (match_operand 0 "" "")
13700                    (call (match_operand:QI 1 "" "")
13701                          (match_operand:SI 2 "" "")))
13702               (set (reg:SI SP_REG)
13703                    (plus:SI (reg:SI SP_REG)
13704                             (match_operand:SI 4 "" "")))])]
13705   "!TARGET_64BIT"
13706 {
13707   ix86_expand_call (operands[0], operands[1], operands[2],
13708                     operands[3], operands[4], 0);
13709   DONE;
13710 })
13711
13712 (define_expand "call_value"
13713   [(set (match_operand 0 "" "")
13714         (call (match_operand:QI 1 "" "")
13715               (match_operand:SI 2 "" "")))
13716    (use (match_operand:SI 3 "" ""))]
13717   ;; Operand 2 not used on the i386.
13718   ""
13719 {
13720   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13721   DONE;
13722 })
13723
13724 (define_expand "sibcall_value"
13725   [(set (match_operand 0 "" "")
13726         (call (match_operand:QI 1 "" "")
13727               (match_operand:SI 2 "" "")))
13728    (use (match_operand:SI 3 "" ""))]
13729   ;; Operand 2 not used on the i386.
13730   ""
13731 {
13732   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13733   DONE;
13734 })
13735
13736 ;; Call subroutine returning any type.
13737
13738 (define_expand "untyped_call"
13739   [(parallel [(call (match_operand 0 "" "")
13740                     (const_int 0))
13741               (match_operand 1 "" "")
13742               (match_operand 2 "" "")])]
13743   ""
13744 {
13745   int i;
13746
13747   /* In order to give reg-stack an easier job in validating two
13748      coprocessor registers as containing a possible return value,
13749      simply pretend the untyped call returns a complex long double
13750      value.  */
13751
13752   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13753                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13754                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13755                     NULL, 0);
13756
13757   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13758     {
13759       rtx set = XVECEXP (operands[2], 0, i);
13760       emit_move_insn (SET_DEST (set), SET_SRC (set));
13761     }
13762
13763   /* The optimizer does not know that the call sets the function value
13764      registers we stored in the result block.  We avoid problems by
13765      claiming that all hard registers are used and clobbered at this
13766      point.  */
13767   emit_insn (gen_blockage (const0_rtx));
13768
13769   DONE;
13770 })
13771 \f
13772 ;; Prologue and epilogue instructions
13773
13774 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13775 ;; all of memory.  This blocks insns from being moved across this point.
13776
13777 (define_insn "blockage"
13778   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13779   ""
13780   ""
13781   [(set_attr "length" "0")])
13782
13783 ;; Insn emitted into the body of a function to return from a function.
13784 ;; This is only done if the function's epilogue is known to be simple.
13785 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13786
13787 (define_expand "return"
13788   [(return)]
13789   "ix86_can_use_return_insn_p ()"
13790 {
13791   if (current_function_pops_args)
13792     {
13793       rtx popc = GEN_INT (current_function_pops_args);
13794       emit_jump_insn (gen_return_pop_internal (popc));
13795       DONE;
13796     }
13797 })
13798
13799 (define_insn "return_internal"
13800   [(return)]
13801   "reload_completed"
13802   "ret"
13803   [(set_attr "length" "1")
13804    (set_attr "length_immediate" "0")
13805    (set_attr "modrm" "0")])
13806
13807 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13808 ;; instruction Athlon and K8 have.
13809
13810 (define_insn "return_internal_long"
13811   [(return)
13812    (unspec [(const_int 0)] UNSPEC_REP)]
13813   "reload_completed"
13814   "rep {;} ret"
13815   [(set_attr "length" "1")
13816    (set_attr "length_immediate" "0")
13817    (set_attr "prefix_rep" "1")
13818    (set_attr "modrm" "0")])
13819
13820 (define_insn "return_pop_internal"
13821   [(return)
13822    (use (match_operand:SI 0 "const_int_operand" ""))]
13823   "reload_completed"
13824   "ret\t%0"
13825   [(set_attr "length" "3")
13826    (set_attr "length_immediate" "2")
13827    (set_attr "modrm" "0")])
13828
13829 (define_insn "return_indirect_internal"
13830   [(return)
13831    (use (match_operand:SI 0 "register_operand" "r"))]
13832   "reload_completed"
13833   "jmp\t%A0"
13834   [(set_attr "type" "ibr")
13835    (set_attr "length_immediate" "0")])
13836
13837 (define_insn "nop"
13838   [(const_int 0)]
13839   ""
13840   "nop"
13841   [(set_attr "length" "1")
13842    (set_attr "length_immediate" "0")
13843    (set_attr "modrm" "0")])
13844
13845 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13846 ;; branch prediction penalty for the third jump in a 16-byte
13847 ;; block on K8.
13848
13849 (define_insn "align"
13850   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13851   ""
13852 {
13853 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13854   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13855 #else
13856   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13857      The align insn is used to avoid 3 jump instructions in the row to improve
13858      branch prediction and the benefits hardly outweight the cost of extra 8
13859      nops on the average inserted by full alignment pseudo operation.  */
13860 #endif
13861   return "";
13862 }
13863   [(set_attr "length" "16")])
13864
13865 (define_expand "prologue"
13866   [(const_int 1)]
13867   ""
13868   "ix86_expand_prologue (); DONE;")
13869
13870 (define_insn "set_got"
13871   [(set (match_operand:SI 0 "register_operand" "=r")
13872         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13873    (clobber (reg:CC FLAGS_REG))]
13874   "!TARGET_64BIT"
13875   { return output_set_got (operands[0]); }
13876   [(set_attr "type" "multi")
13877    (set_attr "length" "12")])
13878
13879 (define_expand "epilogue"
13880   [(const_int 1)]
13881   ""
13882   "ix86_expand_epilogue (1); DONE;")
13883
13884 (define_expand "sibcall_epilogue"
13885   [(const_int 1)]
13886   ""
13887   "ix86_expand_epilogue (0); DONE;")
13888
13889 (define_expand "eh_return"
13890   [(use (match_operand 0 "register_operand" ""))]
13891   ""
13892 {
13893   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13894
13895   /* Tricky bit: we write the address of the handler to which we will
13896      be returning into someone else's stack frame, one word below the
13897      stack address we wish to restore.  */
13898   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13899   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13900   tmp = gen_rtx_MEM (Pmode, tmp);
13901   emit_move_insn (tmp, ra);
13902
13903   if (Pmode == SImode)
13904     emit_jump_insn (gen_eh_return_si (sa));
13905   else
13906     emit_jump_insn (gen_eh_return_di (sa));
13907   emit_barrier ();
13908   DONE;
13909 })
13910
13911 (define_insn_and_split "eh_return_si"
13912   [(set (pc) 
13913         (unspec [(match_operand:SI 0 "register_operand" "c")]
13914                  UNSPEC_EH_RETURN))]
13915   "!TARGET_64BIT"
13916   "#"
13917   "reload_completed"
13918   [(const_int 1)]
13919   "ix86_expand_epilogue (2); DONE;")
13920
13921 (define_insn_and_split "eh_return_di"
13922   [(set (pc) 
13923         (unspec [(match_operand:DI 0 "register_operand" "c")]
13924                  UNSPEC_EH_RETURN))]
13925   "TARGET_64BIT"
13926   "#"
13927   "reload_completed"
13928   [(const_int 1)]
13929   "ix86_expand_epilogue (2); DONE;")
13930
13931 (define_insn "leave"
13932   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13933    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13934    (clobber (mem:BLK (scratch)))]
13935   "!TARGET_64BIT"
13936   "leave"
13937   [(set_attr "type" "leave")])
13938
13939 (define_insn "leave_rex64"
13940   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13941    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13942    (clobber (mem:BLK (scratch)))]
13943   "TARGET_64BIT"
13944   "leave"
13945   [(set_attr "type" "leave")])
13946 \f
13947 (define_expand "ffssi2"
13948   [(parallel
13949      [(set (match_operand:SI 0 "register_operand" "") 
13950            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13951       (clobber (match_scratch:SI 2 ""))
13952       (clobber (reg:CC FLAGS_REG))])]
13953   ""
13954   "")
13955
13956 (define_insn_and_split "*ffs_cmove"
13957   [(set (match_operand:SI 0 "register_operand" "=r") 
13958         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13959    (clobber (match_scratch:SI 2 "=&r"))
13960    (clobber (reg:CC FLAGS_REG))]
13961   "TARGET_CMOVE"
13962   "#"
13963   "&& reload_completed"
13964   [(set (match_dup 2) (const_int -1))
13965    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13966               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13967    (set (match_dup 0) (if_then_else:SI
13968                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13969                         (match_dup 2)
13970                         (match_dup 0)))
13971    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13972               (clobber (reg:CC FLAGS_REG))])]
13973   "")
13974
13975 (define_insn_and_split "*ffs_no_cmove"
13976   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13977         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13978    (clobber (match_scratch:SI 2 "=&q"))
13979    (clobber (reg:CC FLAGS_REG))]
13980   ""
13981   "#"
13982   "reload_completed"
13983   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13984               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13985    (set (strict_low_part (match_dup 3))
13986         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13987    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13988               (clobber (reg:CC FLAGS_REG))])
13989    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13990               (clobber (reg:CC FLAGS_REG))])
13991    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13992               (clobber (reg:CC FLAGS_REG))])]
13993 {
13994   operands[3] = gen_lowpart (QImode, operands[2]);
13995   ix86_expand_clear (operands[2]);
13996 })
13997
13998 (define_insn "*ffssi_1"
13999   [(set (reg:CCZ FLAGS_REG)
14000         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14001                      (const_int 0)))
14002    (set (match_operand:SI 0 "register_operand" "=r")
14003         (ctz:SI (match_dup 1)))]
14004   ""
14005   "bsf{l}\t{%1, %0|%0, %1}"
14006   [(set_attr "prefix_0f" "1")])
14007
14008 (define_expand "ffsdi2"
14009   [(parallel
14010      [(set (match_operand:DI 0 "register_operand" "") 
14011            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14012       (clobber (match_scratch:DI 2 ""))
14013       (clobber (reg:CC 17))])]
14014   "TARGET_64BIT && TARGET_CMOVE"
14015   "")
14016
14017 (define_insn_and_split "*ffs_rex64"
14018   [(set (match_operand:DI 0 "register_operand" "=r") 
14019         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14020    (clobber (match_scratch:DI 2 "=&r"))
14021    (clobber (reg:CC 17))]
14022   "TARGET_64BIT && TARGET_CMOVE"
14023   "#"
14024   "&& reload_completed"
14025   [(set (match_dup 2) (const_int -1))
14026    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14027               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14028    (set (match_dup 0) (if_then_else:DI
14029                         (eq (reg:CCZ 17) (const_int 0))
14030                         (match_dup 2)
14031                         (match_dup 0)))
14032    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14033               (clobber (reg:CC 17))])]
14034   "")
14035
14036 (define_insn "*ffsdi_1"
14037   [(set (reg:CCZ 17)
14038         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14039                      (const_int 0)))
14040    (set (match_operand:DI 0 "register_operand" "=r")
14041         (ctz:DI (match_dup 1)))]
14042   "TARGET_64BIT"
14043   "bsf{q}\t{%1, %0|%0, %1}"
14044   [(set_attr "prefix_0f" "1")])
14045
14046 (define_insn "ctzsi2"
14047   [(set (match_operand:SI 0 "register_operand" "=r")
14048         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14049    (clobber (reg:CC FLAGS_REG))]
14050   ""
14051   "bsf{l}\t{%1, %0|%0, %1}"
14052   [(set_attr "prefix_0f" "1")])
14053
14054 (define_insn "ctzdi2"
14055   [(set (match_operand:DI 0 "register_operand" "=r")
14056         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14057    (clobber (reg:CC 17))]
14058   "TARGET_64BIT"
14059   "bsf{q}\t{%1, %0|%0, %1}"
14060   [(set_attr "prefix_0f" "1")])
14061
14062 (define_expand "clzsi2"
14063   [(parallel
14064      [(set (match_operand:SI 0 "register_operand" "")
14065            (minus:SI (const_int 31)
14066                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14067       (clobber (reg:CC FLAGS_REG))])
14068    (parallel
14069      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14070       (clobber (reg:CC FLAGS_REG))])]
14071   ""
14072   "")
14073
14074 (define_insn "*bsr"
14075   [(set (match_operand:SI 0 "register_operand" "=r")
14076         (minus:SI (const_int 31)
14077                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14078    (clobber (reg:CC FLAGS_REG))]
14079   ""
14080   "bsr{l}\t{%1, %0|%0, %1}"
14081   [(set_attr "prefix_0f" "1")])
14082
14083 (define_expand "clzdi2"
14084   [(parallel
14085      [(set (match_operand:DI 0 "register_operand" "")
14086            (minus:DI (const_int 63)
14087                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14088       (clobber (reg:CC 17))])
14089    (parallel
14090      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14091       (clobber (reg:CC 17))])]
14092   "TARGET_64BIT"
14093   "")
14094
14095 (define_insn "*bsr_rex64"
14096   [(set (match_operand:DI 0 "register_operand" "=r")
14097         (minus:DI (const_int 63)
14098                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14099    (clobber (reg:CC 17))]
14100   "TARGET_64BIT"
14101   "bsr{q}\t{%1, %0|%0, %1}"
14102   [(set_attr "prefix_0f" "1")])
14103 \f
14104 ;; Thread-local storage patterns for ELF.
14105 ;;
14106 ;; Note that these code sequences must appear exactly as shown
14107 ;; in order to allow linker relaxation.
14108
14109 (define_insn "*tls_global_dynamic_32_gnu"
14110   [(set (match_operand:SI 0 "register_operand" "=a")
14111         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14112                     (match_operand:SI 2 "tls_symbolic_operand" "")
14113                     (match_operand:SI 3 "call_insn_operand" "")]
14114                     UNSPEC_TLS_GD))
14115    (clobber (match_scratch:SI 4 "=d"))
14116    (clobber (match_scratch:SI 5 "=c"))
14117    (clobber (reg:CC FLAGS_REG))]
14118   "!TARGET_64BIT && TARGET_GNU_TLS"
14119   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14120   [(set_attr "type" "multi")
14121    (set_attr "length" "12")])
14122
14123 (define_insn "*tls_global_dynamic_32_sun"
14124   [(set (match_operand:SI 0 "register_operand" "=a")
14125         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14126                     (match_operand:SI 2 "tls_symbolic_operand" "")
14127                     (match_operand:SI 3 "call_insn_operand" "")]
14128                     UNSPEC_TLS_GD))
14129    (clobber (match_scratch:SI 4 "=d"))
14130    (clobber (match_scratch:SI 5 "=c"))
14131    (clobber (reg:CC FLAGS_REG))]
14132   "!TARGET_64BIT && TARGET_SUN_TLS"
14133   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14134         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14135   [(set_attr "type" "multi")
14136    (set_attr "length" "14")])
14137
14138 (define_expand "tls_global_dynamic_32"
14139   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14140                    (unspec:SI
14141                     [(match_dup 2)
14142                      (match_operand:SI 1 "tls_symbolic_operand" "")
14143                      (match_dup 3)]
14144                     UNSPEC_TLS_GD))
14145               (clobber (match_scratch:SI 4 ""))
14146               (clobber (match_scratch:SI 5 ""))
14147               (clobber (reg:CC FLAGS_REG))])]
14148   ""
14149 {
14150   if (flag_pic)
14151     operands[2] = pic_offset_table_rtx;
14152   else
14153     {
14154       operands[2] = gen_reg_rtx (Pmode);
14155       emit_insn (gen_set_got (operands[2]));
14156     }
14157   operands[3] = ix86_tls_get_addr ();
14158 })
14159
14160 (define_insn "*tls_global_dynamic_64"
14161   [(set (match_operand:DI 0 "register_operand" "=a")
14162         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14163                       (match_operand:DI 3 "" "")))
14164    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14165               UNSPEC_TLS_GD)]
14166   "TARGET_64BIT"
14167   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14168   [(set_attr "type" "multi")
14169    (set_attr "length" "16")])
14170
14171 (define_expand "tls_global_dynamic_64"
14172   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14173                    (call (mem:QI (match_dup 2)) (const_int 0)))
14174               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14175                          UNSPEC_TLS_GD)])]
14176   ""
14177 {
14178   operands[2] = ix86_tls_get_addr ();
14179 })
14180
14181 (define_insn "*tls_local_dynamic_base_32_gnu"
14182   [(set (match_operand:SI 0 "register_operand" "=a")
14183         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14184                     (match_operand:SI 2 "call_insn_operand" "")]
14185                    UNSPEC_TLS_LD_BASE))
14186    (clobber (match_scratch:SI 3 "=d"))
14187    (clobber (match_scratch:SI 4 "=c"))
14188    (clobber (reg:CC FLAGS_REG))]
14189   "!TARGET_64BIT && TARGET_GNU_TLS"
14190   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14191   [(set_attr "type" "multi")
14192    (set_attr "length" "11")])
14193
14194 (define_insn "*tls_local_dynamic_base_32_sun"
14195   [(set (match_operand:SI 0 "register_operand" "=a")
14196         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14197                     (match_operand:SI 2 "call_insn_operand" "")]
14198                    UNSPEC_TLS_LD_BASE))
14199    (clobber (match_scratch:SI 3 "=d"))
14200    (clobber (match_scratch:SI 4 "=c"))
14201    (clobber (reg:CC FLAGS_REG))]
14202   "!TARGET_64BIT && TARGET_SUN_TLS"
14203   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14204         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14205   [(set_attr "type" "multi")
14206    (set_attr "length" "13")])
14207
14208 (define_expand "tls_local_dynamic_base_32"
14209   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14210                    (unspec:SI [(match_dup 1) (match_dup 2)]
14211                               UNSPEC_TLS_LD_BASE))
14212               (clobber (match_scratch:SI 3 ""))
14213               (clobber (match_scratch:SI 4 ""))
14214               (clobber (reg:CC FLAGS_REG))])]
14215   ""
14216 {
14217   if (flag_pic)
14218     operands[1] = pic_offset_table_rtx;
14219   else
14220     {
14221       operands[1] = gen_reg_rtx (Pmode);
14222       emit_insn (gen_set_got (operands[1]));
14223     }
14224   operands[2] = ix86_tls_get_addr ();
14225 })
14226
14227 (define_insn "*tls_local_dynamic_base_64"
14228   [(set (match_operand:DI 0 "register_operand" "=a")
14229         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14230                       (match_operand:DI 2 "" "")))
14231    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14232   "TARGET_64BIT"
14233   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14234   [(set_attr "type" "multi")
14235    (set_attr "length" "12")])
14236
14237 (define_expand "tls_local_dynamic_base_64"
14238   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14239                    (call (mem:QI (match_dup 1)) (const_int 0)))
14240               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14241   ""
14242 {
14243   operands[1] = ix86_tls_get_addr ();
14244 })
14245
14246 ;; Local dynamic of a single variable is a lose.  Show combine how
14247 ;; to convert that back to global dynamic.
14248
14249 (define_insn_and_split "*tls_local_dynamic_32_once"
14250   [(set (match_operand:SI 0 "register_operand" "=a")
14251         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14252                              (match_operand:SI 2 "call_insn_operand" "")]
14253                             UNSPEC_TLS_LD_BASE)
14254                  (const:SI (unspec:SI
14255                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14256                             UNSPEC_DTPOFF))))
14257    (clobber (match_scratch:SI 4 "=d"))
14258    (clobber (match_scratch:SI 5 "=c"))
14259    (clobber (reg:CC FLAGS_REG))]
14260   ""
14261   "#"
14262   ""
14263   [(parallel [(set (match_dup 0)
14264                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14265                               UNSPEC_TLS_GD))
14266               (clobber (match_dup 4))
14267               (clobber (match_dup 5))
14268               (clobber (reg:CC FLAGS_REG))])]
14269   "")
14270
14271 ;; Load and add the thread base pointer from %gs:0.
14272
14273 (define_insn "*load_tp_si"
14274   [(set (match_operand:SI 0 "register_operand" "=r")
14275         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14276   "!TARGET_64BIT"
14277   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14278   [(set_attr "type" "imov")
14279    (set_attr "modrm" "0")
14280    (set_attr "length" "7")
14281    (set_attr "memory" "load")
14282    (set_attr "imm_disp" "false")])
14283
14284 (define_insn "*add_tp_si"
14285   [(set (match_operand:SI 0 "register_operand" "=r")
14286         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14287                  (match_operand:SI 1 "register_operand" "0")))
14288    (clobber (reg:CC FLAGS_REG))]
14289   "!TARGET_64BIT"
14290   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14291   [(set_attr "type" "alu")
14292    (set_attr "modrm" "0")
14293    (set_attr "length" "7")
14294    (set_attr "memory" "load")
14295    (set_attr "imm_disp" "false")])
14296
14297 (define_insn "*load_tp_di"
14298   [(set (match_operand:DI 0 "register_operand" "=r")
14299         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14300   "TARGET_64BIT"
14301   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14302   [(set_attr "type" "imov")
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 "*add_tp_di"
14309   [(set (match_operand:DI 0 "register_operand" "=r")
14310         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14311                  (match_operand:DI 1 "register_operand" "0")))
14312    (clobber (reg:CC FLAGS_REG))]
14313   "TARGET_64BIT"
14314   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14315   [(set_attr "type" "alu")
14316    (set_attr "modrm" "0")
14317    (set_attr "length" "7")
14318    (set_attr "memory" "load")
14319    (set_attr "imm_disp" "false")])
14320 \f
14321 ;; These patterns match the binary 387 instructions for addM3, subM3,
14322 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14323 ;; SFmode.  The first is the normal insn, the second the same insn but
14324 ;; with one operand a conversion, and the third the same insn but with
14325 ;; the other operand a conversion.  The conversion may be SFmode or
14326 ;; SImode if the target mode DFmode, but only SImode if the target mode
14327 ;; is SFmode.
14328
14329 ;; Gcc is slightly more smart about handling normal two address instructions
14330 ;; so use special patterns for add and mull.
14331 (define_insn "*fop_sf_comm_nosse"
14332   [(set (match_operand:SF 0 "register_operand" "=f")
14333         (match_operator:SF 3 "binary_fp_operator"
14334                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14335                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14336   "TARGET_80387 && !TARGET_SSE_MATH
14337    && COMMUTATIVE_ARITH_P (operands[3])
14338    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14339   "* return output_387_binary_op (insn, operands);"
14340   [(set (attr "type") 
14341         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14342            (const_string "fmul")
14343            (const_string "fop")))
14344    (set_attr "mode" "SF")])
14345
14346 (define_insn "*fop_sf_comm"
14347   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14348         (match_operator:SF 3 "binary_fp_operator"
14349                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14350                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14351   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14352    && COMMUTATIVE_ARITH_P (operands[3])
14353    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14354   "* return output_387_binary_op (insn, operands);"
14355   [(set (attr "type") 
14356         (if_then_else (eq_attr "alternative" "1")
14357            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14358               (const_string "ssemul")
14359               (const_string "sseadd"))
14360            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14361               (const_string "fmul")
14362               (const_string "fop"))))
14363    (set_attr "mode" "SF")])
14364
14365 (define_insn "*fop_sf_comm_sse"
14366   [(set (match_operand:SF 0 "register_operand" "=x")
14367         (match_operator:SF 3 "binary_fp_operator"
14368                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14369                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14370   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14371    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14372   "* return output_387_binary_op (insn, operands);"
14373   [(set (attr "type") 
14374         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14375            (const_string "ssemul")
14376            (const_string "sseadd")))
14377    (set_attr "mode" "SF")])
14378
14379 (define_insn "*fop_df_comm_nosse"
14380   [(set (match_operand:DF 0 "register_operand" "=f")
14381         (match_operator:DF 3 "binary_fp_operator"
14382                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14383                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14384   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14385    && COMMUTATIVE_ARITH_P (operands[3])
14386    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14387   "* return output_387_binary_op (insn, operands);"
14388   [(set (attr "type") 
14389         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14390            (const_string "fmul")
14391            (const_string "fop")))
14392    (set_attr "mode" "DF")])
14393
14394 (define_insn "*fop_df_comm"
14395   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14396         (match_operator:DF 3 "binary_fp_operator"
14397                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14398                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14399   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14400    && COMMUTATIVE_ARITH_P (operands[3])
14401    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14402   "* return output_387_binary_op (insn, operands);"
14403   [(set (attr "type") 
14404         (if_then_else (eq_attr "alternative" "1")
14405            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14406               (const_string "ssemul")
14407               (const_string "sseadd"))
14408            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14409               (const_string "fmul")
14410               (const_string "fop"))))
14411    (set_attr "mode" "DF")])
14412
14413 (define_insn "*fop_df_comm_sse"
14414   [(set (match_operand:DF 0 "register_operand" "=Y")
14415         (match_operator:DF 3 "binary_fp_operator"
14416                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14417                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14418   "TARGET_SSE2 && TARGET_SSE_MATH
14419    && COMMUTATIVE_ARITH_P (operands[3])
14420    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14421   "* return output_387_binary_op (insn, operands);"
14422   [(set (attr "type") 
14423         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14424            (const_string "ssemul")
14425            (const_string "sseadd")))
14426    (set_attr "mode" "DF")])
14427
14428 (define_insn "*fop_xf_comm"
14429   [(set (match_operand:XF 0 "register_operand" "=f")
14430         (match_operator:XF 3 "binary_fp_operator"
14431                         [(match_operand:XF 1 "register_operand" "%0")
14432                          (match_operand:XF 2 "register_operand" "f")]))]
14433   "TARGET_80387
14434    && COMMUTATIVE_ARITH_P (operands[3])"
14435   "* return output_387_binary_op (insn, operands);"
14436   [(set (attr "type") 
14437         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14438            (const_string "fmul")
14439            (const_string "fop")))
14440    (set_attr "mode" "XF")])
14441
14442 (define_insn "*fop_sf_1_nosse"
14443   [(set (match_operand:SF 0 "register_operand" "=f,f")
14444         (match_operator:SF 3 "binary_fp_operator"
14445                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14446                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14447   "TARGET_80387 && !TARGET_SSE_MATH
14448    && !COMMUTATIVE_ARITH_P (operands[3])
14449    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14450   "* return output_387_binary_op (insn, operands);"
14451   [(set (attr "type") 
14452         (cond [(match_operand:SF 3 "mult_operator" "") 
14453                  (const_string "fmul")
14454                (match_operand:SF 3 "div_operator" "") 
14455                  (const_string "fdiv")
14456               ]
14457               (const_string "fop")))
14458    (set_attr "mode" "SF")])
14459
14460 (define_insn "*fop_sf_1"
14461   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14462         (match_operator:SF 3 "binary_fp_operator"
14463                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14464                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14465   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14466    && !COMMUTATIVE_ARITH_P (operands[3])
14467    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14468   "* return output_387_binary_op (insn, operands);"
14469   [(set (attr "type") 
14470         (cond [(and (eq_attr "alternative" "2")
14471                     (match_operand:SF 3 "mult_operator" ""))
14472                  (const_string "ssemul")
14473                (and (eq_attr "alternative" "2")
14474                     (match_operand:SF 3 "div_operator" ""))
14475                  (const_string "ssediv")
14476                (eq_attr "alternative" "2")
14477                  (const_string "sseadd")
14478                (match_operand:SF 3 "mult_operator" "") 
14479                  (const_string "fmul")
14480                (match_operand:SF 3 "div_operator" "") 
14481                  (const_string "fdiv")
14482               ]
14483               (const_string "fop")))
14484    (set_attr "mode" "SF")])
14485
14486 (define_insn "*fop_sf_1_sse"
14487   [(set (match_operand:SF 0 "register_operand" "=x")
14488         (match_operator:SF 3 "binary_fp_operator"
14489                         [(match_operand:SF 1 "register_operand" "0")
14490                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14491   "TARGET_SSE_MATH
14492    && !COMMUTATIVE_ARITH_P (operands[3])"
14493   "* return output_387_binary_op (insn, operands);"
14494   [(set (attr "type") 
14495         (cond [(match_operand:SF 3 "mult_operator" "")
14496                  (const_string "ssemul")
14497                (match_operand:SF 3 "div_operator" "")
14498                  (const_string "ssediv")
14499               ]
14500               (const_string "sseadd")))
14501    (set_attr "mode" "SF")])
14502
14503 ;; ??? Add SSE splitters for these!
14504 (define_insn "*fop_sf_2"
14505   [(set (match_operand:SF 0 "register_operand" "=f,f")
14506         (match_operator:SF 3 "binary_fp_operator"
14507           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14508            (match_operand:SF 2 "register_operand" "0,0")]))]
14509   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14510   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14511   [(set (attr "type") 
14512         (cond [(match_operand:SF 3 "mult_operator" "") 
14513                  (const_string "fmul")
14514                (match_operand:SF 3 "div_operator" "") 
14515                  (const_string "fdiv")
14516               ]
14517               (const_string "fop")))
14518    (set_attr "fp_int_src" "true")
14519    (set_attr "mode" "SI")])
14520
14521 (define_insn "*fop_sf_3"
14522   [(set (match_operand:SF 0 "register_operand" "=f,f")
14523         (match_operator:SF 3 "binary_fp_operator"
14524           [(match_operand:SF 1 "register_operand" "0,0")
14525            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14526   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14527   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14528   [(set (attr "type") 
14529         (cond [(match_operand:SF 3 "mult_operator" "") 
14530                  (const_string "fmul")
14531                (match_operand:SF 3 "div_operator" "") 
14532                  (const_string "fdiv")
14533               ]
14534               (const_string "fop")))
14535    (set_attr "fp_int_src" "true")
14536    (set_attr "mode" "SI")])
14537
14538 (define_insn "*fop_df_1_nosse"
14539   [(set (match_operand:DF 0 "register_operand" "=f,f")
14540         (match_operator:DF 3 "binary_fp_operator"
14541                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14542                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14543   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14544    && !COMMUTATIVE_ARITH_P (operands[3])
14545    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14546   "* return output_387_binary_op (insn, operands);"
14547   [(set (attr "type") 
14548         (cond [(match_operand:DF 3 "mult_operator" "") 
14549                  (const_string "fmul")
14550                (match_operand:DF 3 "div_operator" "")
14551                  (const_string "fdiv")
14552               ]
14553               (const_string "fop")))
14554    (set_attr "mode" "DF")])
14555
14556
14557 (define_insn "*fop_df_1"
14558   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14559         (match_operator:DF 3 "binary_fp_operator"
14560                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14561                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14562   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14563    && !COMMUTATIVE_ARITH_P (operands[3])
14564    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14565   "* return output_387_binary_op (insn, operands);"
14566   [(set (attr "type") 
14567         (cond [(and (eq_attr "alternative" "2")
14568                     (match_operand:SF 3 "mult_operator" ""))
14569                  (const_string "ssemul")
14570                (and (eq_attr "alternative" "2")
14571                     (match_operand:SF 3 "div_operator" ""))
14572                  (const_string "ssediv")
14573                (eq_attr "alternative" "2")
14574                  (const_string "sseadd")
14575                (match_operand:DF 3 "mult_operator" "") 
14576                  (const_string "fmul")
14577                (match_operand:DF 3 "div_operator" "") 
14578                  (const_string "fdiv")
14579               ]
14580               (const_string "fop")))
14581    (set_attr "mode" "DF")])
14582
14583 (define_insn "*fop_df_1_sse"
14584   [(set (match_operand:DF 0 "register_operand" "=Y")
14585         (match_operator:DF 3 "binary_fp_operator"
14586                         [(match_operand:DF 1 "register_operand" "0")
14587                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14588   "TARGET_SSE2 && TARGET_SSE_MATH
14589    && !COMMUTATIVE_ARITH_P (operands[3])"
14590   "* return output_387_binary_op (insn, operands);"
14591   [(set_attr "mode" "DF")
14592    (set (attr "type") 
14593         (cond [(match_operand:SF 3 "mult_operator" "")
14594                  (const_string "ssemul")
14595                (match_operand:SF 3 "div_operator" "")
14596                  (const_string "ssediv")
14597               ]
14598               (const_string "sseadd")))])
14599
14600 ;; ??? Add SSE splitters for these!
14601 (define_insn "*fop_df_2"
14602   [(set (match_operand:DF 0 "register_operand" "=f,f")
14603         (match_operator:DF 3 "binary_fp_operator"
14604            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14605             (match_operand:DF 2 "register_operand" "0,0")]))]
14606   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14607   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14608   [(set (attr "type") 
14609         (cond [(match_operand:DF 3 "mult_operator" "") 
14610                  (const_string "fmul")
14611                (match_operand:DF 3 "div_operator" "") 
14612                  (const_string "fdiv")
14613               ]
14614               (const_string "fop")))
14615    (set_attr "fp_int_src" "true")
14616    (set_attr "mode" "SI")])
14617
14618 (define_insn "*fop_df_3"
14619   [(set (match_operand:DF 0 "register_operand" "=f,f")
14620         (match_operator:DF 3 "binary_fp_operator"
14621            [(match_operand:DF 1 "register_operand" "0,0")
14622             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14623   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14624   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14625   [(set (attr "type") 
14626         (cond [(match_operand:DF 3 "mult_operator" "") 
14627                  (const_string "fmul")
14628                (match_operand:DF 3 "div_operator" "") 
14629                  (const_string "fdiv")
14630               ]
14631               (const_string "fop")))
14632    (set_attr "fp_int_src" "true")
14633    (set_attr "mode" "SI")])
14634
14635 (define_insn "*fop_df_4"
14636   [(set (match_operand:DF 0 "register_operand" "=f,f")
14637         (match_operator:DF 3 "binary_fp_operator"
14638            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14639             (match_operand:DF 2 "register_operand" "0,f")]))]
14640   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14641    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14642   "* return output_387_binary_op (insn, operands);"
14643   [(set (attr "type") 
14644         (cond [(match_operand:DF 3 "mult_operator" "") 
14645                  (const_string "fmul")
14646                (match_operand:DF 3 "div_operator" "") 
14647                  (const_string "fdiv")
14648               ]
14649               (const_string "fop")))
14650    (set_attr "mode" "SF")])
14651
14652 (define_insn "*fop_df_5"
14653   [(set (match_operand:DF 0 "register_operand" "=f,f")
14654         (match_operator:DF 3 "binary_fp_operator"
14655           [(match_operand:DF 1 "register_operand" "0,f")
14656            (float_extend:DF
14657             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14658   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14659   "* return output_387_binary_op (insn, operands);"
14660   [(set (attr "type") 
14661         (cond [(match_operand:DF 3 "mult_operator" "") 
14662                  (const_string "fmul")
14663                (match_operand:DF 3 "div_operator" "") 
14664                  (const_string "fdiv")
14665               ]
14666               (const_string "fop")))
14667    (set_attr "mode" "SF")])
14668
14669 (define_insn "*fop_df_6"
14670   [(set (match_operand:DF 0 "register_operand" "=f,f")
14671         (match_operator:DF 3 "binary_fp_operator"
14672           [(float_extend:DF
14673             (match_operand:SF 1 "register_operand" "0,f"))
14674            (float_extend:DF
14675             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14676   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14677   "* return output_387_binary_op (insn, operands);"
14678   [(set (attr "type") 
14679         (cond [(match_operand:DF 3 "mult_operator" "") 
14680                  (const_string "fmul")
14681                (match_operand:DF 3 "div_operator" "") 
14682                  (const_string "fdiv")
14683               ]
14684               (const_string "fop")))
14685    (set_attr "mode" "SF")])
14686
14687 (define_insn "*fop_xf_1"
14688   [(set (match_operand:XF 0 "register_operand" "=f,f")
14689         (match_operator:XF 3 "binary_fp_operator"
14690                         [(match_operand:XF 1 "register_operand" "0,f")
14691                          (match_operand:XF 2 "register_operand" "f,0")]))]
14692   "TARGET_80387
14693    && !COMMUTATIVE_ARITH_P (operands[3])"
14694   "* return output_387_binary_op (insn, operands);"
14695   [(set (attr "type") 
14696         (cond [(match_operand:XF 3 "mult_operator" "") 
14697                  (const_string "fmul")
14698                (match_operand:XF 3 "div_operator" "") 
14699                  (const_string "fdiv")
14700               ]
14701               (const_string "fop")))
14702    (set_attr "mode" "XF")])
14703
14704 (define_insn "*fop_xf_2"
14705   [(set (match_operand:XF 0 "register_operand" "=f,f")
14706         (match_operator:XF 3 "binary_fp_operator"
14707            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14708             (match_operand:XF 2 "register_operand" "0,0")]))]
14709   "TARGET_80387 && TARGET_USE_FIOP"
14710   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14711   [(set (attr "type") 
14712         (cond [(match_operand:XF 3 "mult_operator" "") 
14713                  (const_string "fmul")
14714                (match_operand:XF 3 "div_operator" "") 
14715                  (const_string "fdiv")
14716               ]
14717               (const_string "fop")))
14718    (set_attr "fp_int_src" "true")
14719    (set_attr "mode" "SI")])
14720
14721 (define_insn "*fop_xf_3"
14722   [(set (match_operand:XF 0 "register_operand" "=f,f")
14723         (match_operator:XF 3 "binary_fp_operator"
14724           [(match_operand:XF 1 "register_operand" "0,0")
14725            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14726   "TARGET_80387 && TARGET_USE_FIOP"
14727   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14728   [(set (attr "type") 
14729         (cond [(match_operand:XF 3 "mult_operator" "") 
14730                  (const_string "fmul")
14731                (match_operand:XF 3 "div_operator" "") 
14732                  (const_string "fdiv")
14733               ]
14734               (const_string "fop")))
14735    (set_attr "fp_int_src" "true")
14736    (set_attr "mode" "SI")])
14737
14738 (define_insn "*fop_xf_4"
14739   [(set (match_operand:XF 0 "register_operand" "=f,f")
14740         (match_operator:XF 3 "binary_fp_operator"
14741            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14742             (match_operand:XF 2 "register_operand" "0,f")]))]
14743   "TARGET_80387"
14744   "* return output_387_binary_op (insn, operands);"
14745   [(set (attr "type") 
14746         (cond [(match_operand:XF 3 "mult_operator" "") 
14747                  (const_string "fmul")
14748                (match_operand:XF 3 "div_operator" "") 
14749                  (const_string "fdiv")
14750               ]
14751               (const_string "fop")))
14752    (set_attr "mode" "SF")])
14753
14754 (define_insn "*fop_xf_5"
14755   [(set (match_operand:XF 0 "register_operand" "=f,f")
14756         (match_operator:XF 3 "binary_fp_operator"
14757           [(match_operand:XF 1 "register_operand" "0,f")
14758            (float_extend:XF
14759             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14760   "TARGET_80387"
14761   "* return output_387_binary_op (insn, operands);"
14762   [(set (attr "type") 
14763         (cond [(match_operand:XF 3 "mult_operator" "") 
14764                  (const_string "fmul")
14765                (match_operand:XF 3 "div_operator" "") 
14766                  (const_string "fdiv")
14767               ]
14768               (const_string "fop")))
14769    (set_attr "mode" "SF")])
14770
14771 (define_insn "*fop_xf_6"
14772   [(set (match_operand:XF 0 "register_operand" "=f,f")
14773         (match_operator:XF 3 "binary_fp_operator"
14774           [(float_extend:XF
14775             (match_operand 1 "register_operand" "0,f"))
14776            (float_extend:XF
14777             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14778   "TARGET_80387"
14779   "* return output_387_binary_op (insn, operands);"
14780   [(set (attr "type") 
14781         (cond [(match_operand:XF 3 "mult_operator" "") 
14782                  (const_string "fmul")
14783                (match_operand:XF 3 "div_operator" "") 
14784                  (const_string "fdiv")
14785               ]
14786               (const_string "fop")))
14787    (set_attr "mode" "SF")])
14788
14789 (define_split
14790   [(set (match_operand 0 "register_operand" "")
14791         (match_operator 3 "binary_fp_operator"
14792            [(float (match_operand:SI 1 "register_operand" ""))
14793             (match_operand 2 "register_operand" "")]))]
14794   "TARGET_80387 && reload_completed
14795    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14796   [(const_int 0)]
14797
14798   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14799   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14800   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14801                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14802                                           GET_MODE (operands[3]),
14803                                           operands[4],
14804                                           operands[2])));
14805   ix86_free_from_memory (GET_MODE (operands[1]));
14806   DONE;
14807 })
14808
14809 (define_split
14810   [(set (match_operand 0 "register_operand" "")
14811         (match_operator 3 "binary_fp_operator"
14812            [(match_operand 1 "register_operand" "")
14813             (float (match_operand:SI 2 "register_operand" ""))]))]
14814   "TARGET_80387 && reload_completed
14815    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14816   [(const_int 0)]
14817 {
14818   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14819   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14820   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14821                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14822                                           GET_MODE (operands[3]),
14823                                           operands[1],
14824                                           operands[4])));
14825   ix86_free_from_memory (GET_MODE (operands[2]));
14826   DONE;
14827 })
14828 \f
14829 ;; FPU special functions.
14830
14831 (define_expand "sqrtsf2"
14832   [(set (match_operand:SF 0 "register_operand" "")
14833         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14834   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14835 {
14836   if (!TARGET_SSE_MATH)
14837     operands[1] = force_reg (SFmode, operands[1]);
14838 })
14839
14840 (define_insn "sqrtsf2_1"
14841   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14842         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14843   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14844    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14845   "@
14846    fsqrt
14847    sqrtss\t{%1, %0|%0, %1}"
14848   [(set_attr "type" "fpspc,sse")
14849    (set_attr "mode" "SF,SF")
14850    (set_attr "athlon_decode" "direct,*")])
14851
14852 (define_insn "sqrtsf2_1_sse_only"
14853   [(set (match_operand:SF 0 "register_operand" "=x")
14854         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14855   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14856   "sqrtss\t{%1, %0|%0, %1}"
14857   [(set_attr "type" "sse")
14858    (set_attr "mode" "SF")
14859    (set_attr "athlon_decode" "*")])
14860
14861 (define_insn "sqrtsf2_i387"
14862   [(set (match_operand:SF 0 "register_operand" "=f")
14863         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14864   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14865    && !TARGET_SSE_MATH"
14866   "fsqrt"
14867   [(set_attr "type" "fpspc")
14868    (set_attr "mode" "SF")
14869    (set_attr "athlon_decode" "direct")])
14870
14871 (define_expand "sqrtdf2"
14872   [(set (match_operand:DF 0 "register_operand" "")
14873         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14874   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14875    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14876 {
14877   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14878     operands[1] = force_reg (DFmode, operands[1]);
14879 })
14880
14881 (define_insn "sqrtdf2_1"
14882   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14883         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14884   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14885    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14886   "@
14887    fsqrt
14888    sqrtsd\t{%1, %0|%0, %1}"
14889   [(set_attr "type" "fpspc,sse")
14890    (set_attr "mode" "DF,DF")
14891    (set_attr "athlon_decode" "direct,*")])
14892
14893 (define_insn "sqrtdf2_1_sse_only"
14894   [(set (match_operand:DF 0 "register_operand" "=Y")
14895         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14896   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14897   "sqrtsd\t{%1, %0|%0, %1}"
14898   [(set_attr "type" "sse")
14899    (set_attr "mode" "DF")
14900    (set_attr "athlon_decode" "*")])
14901
14902 (define_insn "sqrtdf2_i387"
14903   [(set (match_operand:DF 0 "register_operand" "=f")
14904         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14905   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14906    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14907   "fsqrt"
14908   [(set_attr "type" "fpspc")
14909    (set_attr "mode" "DF")
14910    (set_attr "athlon_decode" "direct")])
14911
14912 (define_insn "*sqrtextendsfdf2"
14913   [(set (match_operand:DF 0 "register_operand" "=f")
14914         (sqrt:DF (float_extend:DF
14915                   (match_operand:SF 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 "sqrtxf2"
14924   [(set (match_operand:XF 0 "register_operand" "=f")
14925         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14926   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14927    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14928   "fsqrt"
14929   [(set_attr "type" "fpspc")
14930    (set_attr "mode" "XF")
14931    (set_attr "athlon_decode" "direct")])
14932
14933 (define_insn "*sqrtextenddfxf2"
14934   [(set (match_operand:XF 0 "register_operand" "=f")
14935         (sqrt:XF (float_extend:XF
14936                   (match_operand:DF 1 "register_operand" "0"))))]
14937   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14938   "fsqrt"
14939   [(set_attr "type" "fpspc")
14940    (set_attr "mode" "XF")
14941    (set_attr "athlon_decode" "direct")])
14942
14943 (define_insn "*sqrtextendsfxf2"
14944   [(set (match_operand:XF 0 "register_operand" "=f")
14945         (sqrt:XF (float_extend:XF
14946                   (match_operand:SF 1 "register_operand" "0"))))]
14947   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14948   "fsqrt"
14949   [(set_attr "type" "fpspc")
14950    (set_attr "mode" "XF")
14951    (set_attr "athlon_decode" "direct")])
14952
14953 (define_insn "fpremxf4"
14954   [(set (match_operand:XF 0 "register_operand" "=f")
14955         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14956                     (match_operand:XF 3 "register_operand" "1")]
14957                    UNSPEC_FPREM_F))
14958    (set (match_operand:XF 1 "register_operand" "=u")
14959         (unspec:XF [(match_dup 2) (match_dup 3)]
14960                    UNSPEC_FPREM_U))
14961    (set (reg:CCFP FPSR_REG)
14962         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14963   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14964    && flag_unsafe_math_optimizations"
14965   "fprem"
14966   [(set_attr "type" "fpspc")
14967    (set_attr "mode" "XF")])
14968
14969 (define_expand "fmodsf3"
14970   [(use (match_operand:SF 0 "register_operand" ""))
14971    (use (match_operand:SF 1 "register_operand" ""))
14972    (use (match_operand:SF 2 "register_operand" ""))]
14973   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14974    && flag_unsafe_math_optimizations"
14975 {
14976   rtx label = gen_label_rtx ();
14977
14978   rtx op1 = gen_reg_rtx (XFmode);
14979   rtx op2 = gen_reg_rtx (XFmode);
14980
14981   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14982   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14983
14984   emit_label (label);
14985
14986   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14987   ix86_emit_fp_unordered_jump (label);
14988
14989   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14990   DONE;
14991 })
14992
14993 (define_expand "fmoddf3"
14994   [(use (match_operand:DF 0 "register_operand" ""))
14995    (use (match_operand:DF 1 "register_operand" ""))
14996    (use (match_operand:DF 2 "register_operand" ""))]
14997   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14998    && flag_unsafe_math_optimizations"
14999 {
15000   rtx label = gen_label_rtx ();
15001
15002   rtx op1 = gen_reg_rtx (XFmode);
15003   rtx op2 = gen_reg_rtx (XFmode);
15004
15005   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15006   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15007
15008   emit_label (label);
15009
15010   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15011   ix86_emit_fp_unordered_jump (label);
15012
15013   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15014   DONE;
15015 })
15016
15017 (define_expand "fmodxf3"
15018   [(use (match_operand:XF 0 "register_operand" ""))
15019    (use (match_operand:XF 1 "register_operand" ""))
15020    (use (match_operand:XF 2 "register_operand" ""))]
15021   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15022    && flag_unsafe_math_optimizations"
15023 {
15024   rtx label = gen_label_rtx ();
15025
15026   emit_label (label);
15027
15028   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15029                            operands[1], operands[2]));
15030   ix86_emit_fp_unordered_jump (label);
15031
15032   emit_move_insn (operands[0], operands[1]);
15033   DONE;
15034 })
15035
15036 (define_insn "fprem1xf4"
15037   [(set (match_operand:XF 0 "register_operand" "=f")
15038         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15039                     (match_operand:XF 3 "register_operand" "1")]
15040                    UNSPEC_FPREM1_F))
15041    (set (match_operand:XF 1 "register_operand" "=u")
15042         (unspec:XF [(match_dup 2) (match_dup 3)]
15043                    UNSPEC_FPREM1_U))
15044    (set (reg:CCFP FPSR_REG)
15045         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15046   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15047    && flag_unsafe_math_optimizations"
15048   "fprem1"
15049   [(set_attr "type" "fpspc")
15050    (set_attr "mode" "XF")])
15051
15052 (define_expand "dremsf3"
15053   [(use (match_operand:SF 0 "register_operand" ""))
15054    (use (match_operand:SF 1 "register_operand" ""))
15055    (use (match_operand:SF 2 "register_operand" ""))]
15056   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15057    && flag_unsafe_math_optimizations"
15058 {
15059   rtx label = gen_label_rtx ();
15060
15061   rtx op1 = gen_reg_rtx (XFmode);
15062   rtx op2 = gen_reg_rtx (XFmode);
15063
15064   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15065   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15066
15067   emit_label (label);
15068
15069   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15070   ix86_emit_fp_unordered_jump (label);
15071
15072   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15073   DONE;
15074 })
15075
15076 (define_expand "dremdf3"
15077   [(use (match_operand:DF 0 "register_operand" ""))
15078    (use (match_operand:DF 1 "register_operand" ""))
15079    (use (match_operand:DF 2 "register_operand" ""))]
15080   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15081    && flag_unsafe_math_optimizations"
15082 {
15083   rtx label = gen_label_rtx ();
15084
15085   rtx op1 = gen_reg_rtx (XFmode);
15086   rtx op2 = gen_reg_rtx (XFmode);
15087
15088   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15089   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15090
15091   emit_label (label);
15092
15093   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15094   ix86_emit_fp_unordered_jump (label);
15095
15096   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15097   DONE;
15098 })
15099
15100 (define_expand "dremxf3"
15101   [(use (match_operand:XF 0 "register_operand" ""))
15102    (use (match_operand:XF 1 "register_operand" ""))
15103    (use (match_operand:XF 2 "register_operand" ""))]
15104   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15105    && flag_unsafe_math_optimizations"
15106 {
15107   rtx label = gen_label_rtx ();
15108
15109   emit_label (label);
15110
15111   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15112                             operands[1], operands[2]));
15113   ix86_emit_fp_unordered_jump (label);
15114
15115   emit_move_insn (operands[0], operands[1]);
15116   DONE;
15117 })
15118
15119 (define_insn "*sindf2"
15120   [(set (match_operand:DF 0 "register_operand" "=f")
15121         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15122   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15123    && flag_unsafe_math_optimizations"
15124   "fsin"
15125   [(set_attr "type" "fpspc")
15126    (set_attr "mode" "DF")])
15127
15128 (define_insn "*sinsf2"
15129   [(set (match_operand:SF 0 "register_operand" "=f")
15130         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15131   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15132    && flag_unsafe_math_optimizations"
15133   "fsin"
15134   [(set_attr "type" "fpspc")
15135    (set_attr "mode" "SF")])
15136
15137 (define_insn "*sinextendsfdf2"
15138   [(set (match_operand:DF 0 "register_operand" "=f")
15139         (unspec:DF [(float_extend:DF
15140                      (match_operand:SF 1 "register_operand" "0"))]
15141                    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" "DF")])
15147
15148 (define_insn "*sinxf2"
15149   [(set (match_operand:XF 0 "register_operand" "=f")
15150         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15151   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15152    && flag_unsafe_math_optimizations"
15153   "fsin"
15154   [(set_attr "type" "fpspc")
15155    (set_attr "mode" "XF")])
15156
15157 (define_insn "*cosdf2"
15158   [(set (match_operand:DF 0 "register_operand" "=f")
15159         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15160   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15161    && flag_unsafe_math_optimizations"
15162   "fcos"
15163   [(set_attr "type" "fpspc")
15164    (set_attr "mode" "DF")])
15165
15166 (define_insn "*cossf2"
15167   [(set (match_operand:SF 0 "register_operand" "=f")
15168         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15169   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15170    && flag_unsafe_math_optimizations"
15171   "fcos"
15172   [(set_attr "type" "fpspc")
15173    (set_attr "mode" "SF")])
15174
15175 (define_insn "*cosextendsfdf2"
15176   [(set (match_operand:DF 0 "register_operand" "=f")
15177         (unspec:DF [(float_extend:DF
15178                      (match_operand:SF 1 "register_operand" "0"))]
15179                    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" "DF")])
15185
15186 (define_insn "*cosxf2"
15187   [(set (match_operand:XF 0 "register_operand" "=f")
15188         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15189   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15190    && flag_unsafe_math_optimizations"
15191   "fcos"
15192   [(set_attr "type" "fpspc")
15193    (set_attr "mode" "XF")])
15194
15195 ;; With sincos pattern defined, sin and cos builtin function will be
15196 ;; expanded to sincos pattern with one of its outputs left unused. 
15197 ;; Cse pass  will detected, if two sincos patterns can be combined,
15198 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15199 ;; depending on the unused output.
15200
15201 (define_insn "sincosdf3"
15202   [(set (match_operand:DF 0 "register_operand" "=f")
15203         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15204                    UNSPEC_SINCOS_COS))
15205    (set (match_operand:DF 1 "register_operand" "=u")
15206         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15207   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15208    && flag_unsafe_math_optimizations"
15209   "fsincos"
15210   [(set_attr "type" "fpspc")
15211    (set_attr "mode" "DF")])
15212
15213 (define_split
15214   [(set (match_operand:DF 0 "register_operand" "")
15215         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15216                    UNSPEC_SINCOS_COS))
15217    (set (match_operand:DF 1 "register_operand" "")
15218         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15219   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15220    && !reload_completed && !reload_in_progress"
15221   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15222   "")
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[1]))
15231    && !reload_completed && !reload_in_progress"
15232   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15233   "")
15234
15235 (define_insn "sincossf3"
15236   [(set (match_operand:SF 0 "register_operand" "=f")
15237         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15238                    UNSPEC_SINCOS_COS))
15239    (set (match_operand:SF 1 "register_operand" "=u")
15240         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15241   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15242    && flag_unsafe_math_optimizations"
15243   "fsincos"
15244   [(set_attr "type" "fpspc")
15245    (set_attr "mode" "SF")])
15246
15247 (define_split
15248   [(set (match_operand:SF 0 "register_operand" "")
15249         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15250                    UNSPEC_SINCOS_COS))
15251    (set (match_operand:SF 1 "register_operand" "")
15252         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15253   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15254    && !reload_completed && !reload_in_progress"
15255   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15256   "")
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[1]))
15265    && !reload_completed && !reload_in_progress"
15266   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15267   "")
15268
15269 (define_insn "*sincosextendsfdf3"
15270   [(set (match_operand:DF 0 "register_operand" "=f")
15271         (unspec:DF [(float_extend:DF
15272                      (match_operand:SF 2 "register_operand" "0"))]
15273                    UNSPEC_SINCOS_COS))
15274    (set (match_operand:DF 1 "register_operand" "=u")
15275         (unspec:DF [(float_extend:DF
15276                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15277   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15278    && flag_unsafe_math_optimizations"
15279   "fsincos"
15280   [(set_attr "type" "fpspc")
15281    (set_attr "mode" "DF")])
15282
15283 (define_split
15284   [(set (match_operand:DF 0 "register_operand" "")
15285         (unspec:DF [(float_extend:DF
15286                      (match_operand:SF 2 "register_operand" ""))]
15287                    UNSPEC_SINCOS_COS))
15288    (set (match_operand:DF 1 "register_operand" "")
15289         (unspec:DF [(float_extend:DF
15290                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15291   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15292    && !reload_completed && !reload_in_progress"
15293   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15294                                    (match_dup 2))] UNSPEC_SIN))]
15295   "")
15296
15297 (define_split
15298   [(set (match_operand:DF 0 "register_operand" "")
15299         (unspec:DF [(float_extend:DF
15300                      (match_operand:SF 2 "register_operand" ""))]
15301                    UNSPEC_SINCOS_COS))
15302    (set (match_operand:DF 1 "register_operand" "")
15303         (unspec:DF [(float_extend:DF
15304                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15305   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15306    && !reload_completed && !reload_in_progress"
15307   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15308                                    (match_dup 2))] UNSPEC_COS))]
15309   "")
15310
15311 (define_insn "sincosxf3"
15312   [(set (match_operand:XF 0 "register_operand" "=f")
15313         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15314                    UNSPEC_SINCOS_COS))
15315    (set (match_operand:XF 1 "register_operand" "=u")
15316         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15317   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15318    && flag_unsafe_math_optimizations"
15319   "fsincos"
15320   [(set_attr "type" "fpspc")
15321    (set_attr "mode" "XF")])
15322
15323 (define_split
15324   [(set (match_operand:XF 0 "register_operand" "")
15325         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15326                    UNSPEC_SINCOS_COS))
15327    (set (match_operand:XF 1 "register_operand" "")
15328         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15329   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15330    && !reload_completed && !reload_in_progress"
15331   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15332   "")
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[1]))
15341    && !reload_completed && !reload_in_progress"
15342   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15343   "")
15344
15345 (define_insn "*tandf3_1"
15346   [(set (match_operand:DF 0 "register_operand" "=f")
15347         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15348                    UNSPEC_TAN_ONE))
15349    (set (match_operand:DF 1 "register_operand" "=u")
15350         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15351   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15352    && flag_unsafe_math_optimizations"
15353   "fptan"
15354   [(set_attr "type" "fpspc")
15355    (set_attr "mode" "DF")])
15356
15357 ;; optimize sequence: fptan
15358 ;;                    fstp    %st(0)
15359 ;;                    fld1
15360 ;; into fptan insn.
15361
15362 (define_peephole2
15363   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15364                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15365                              UNSPEC_TAN_ONE))
15366              (set (match_operand:DF 1 "register_operand" "")
15367                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15368    (set (match_dup 0)
15369         (match_operand:DF 3 "immediate_operand" ""))]
15370   "standard_80387_constant_p (operands[3]) == 2"
15371   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15372              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15373   "")
15374
15375 (define_expand "tandf2"
15376   [(parallel [(set (match_dup 2)
15377                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15378                               UNSPEC_TAN_ONE))
15379               (set (match_operand:DF 0 "register_operand" "")
15380                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15381   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15382    && flag_unsafe_math_optimizations"
15383 {
15384   operands[2] = gen_reg_rtx (DFmode);
15385 })
15386
15387 (define_insn "*tansf3_1"
15388   [(set (match_operand:SF 0 "register_operand" "=f")
15389         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15390                    UNSPEC_TAN_ONE))
15391    (set (match_operand:SF 1 "register_operand" "=u")
15392         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15393   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15394    && flag_unsafe_math_optimizations"
15395   "fptan"
15396   [(set_attr "type" "fpspc")
15397    (set_attr "mode" "SF")])
15398
15399 ;; optimize sequence: fptan
15400 ;;                    fstp    %st(0)
15401 ;;                    fld1
15402 ;; into fptan insn.
15403
15404 (define_peephole2
15405   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15406                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15407                              UNSPEC_TAN_ONE))
15408              (set (match_operand:SF 1 "register_operand" "")
15409                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15410    (set (match_dup 0)
15411         (match_operand:SF 3 "immediate_operand" ""))]
15412   "standard_80387_constant_p (operands[3]) == 2"
15413   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15414              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15415   "")
15416
15417 (define_expand "tansf2"
15418   [(parallel [(set (match_dup 2)
15419                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15420                               UNSPEC_TAN_ONE))
15421               (set (match_operand:SF 0 "register_operand" "")
15422                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15423   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15424    && flag_unsafe_math_optimizations"
15425 {
15426   operands[2] = gen_reg_rtx (SFmode);
15427 })
15428
15429 (define_insn "*tanxf3_1"
15430   [(set (match_operand:XF 0 "register_operand" "=f")
15431         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15432                    UNSPEC_TAN_ONE))
15433    (set (match_operand:XF 1 "register_operand" "=u")
15434         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15435   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15436    && flag_unsafe_math_optimizations"
15437   "fptan"
15438   [(set_attr "type" "fpspc")
15439    (set_attr "mode" "XF")])
15440
15441 ;; optimize sequence: fptan
15442 ;;                    fstp    %st(0)
15443 ;;                    fld1
15444 ;; into fptan insn.
15445
15446 (define_peephole2
15447   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15448                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15449                              UNSPEC_TAN_ONE))
15450              (set (match_operand:XF 1 "register_operand" "")
15451                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15452    (set (match_dup 0)
15453         (match_operand:XF 3 "immediate_operand" ""))]
15454   "standard_80387_constant_p (operands[3]) == 2"
15455   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15456              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15457   "")
15458
15459 (define_expand "tanxf2"
15460   [(parallel [(set (match_dup 2)
15461                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15462                               UNSPEC_TAN_ONE))
15463               (set (match_operand:XF 0 "register_operand" "")
15464                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15465   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15466    && flag_unsafe_math_optimizations"
15467 {
15468   operands[2] = gen_reg_rtx (XFmode);
15469 })
15470
15471 (define_insn "atan2df3_1"
15472   [(set (match_operand:DF 0 "register_operand" "=f")
15473         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15474                     (match_operand:DF 1 "register_operand" "u")]
15475                    UNSPEC_FPATAN))
15476    (clobber (match_scratch:DF 3 "=1"))]
15477   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15478    && flag_unsafe_math_optimizations"
15479   "fpatan"
15480   [(set_attr "type" "fpspc")
15481    (set_attr "mode" "DF")])
15482
15483 (define_expand "atan2df3"
15484   [(use (match_operand:DF 0 "register_operand" "=f"))
15485    (use (match_operand:DF 2 "register_operand" "0"))
15486    (use (match_operand:DF 1 "register_operand" "u"))]
15487   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15488    && flag_unsafe_math_optimizations"
15489 {
15490   rtx copy = gen_reg_rtx (DFmode);
15491   emit_move_insn (copy, operands[1]);
15492   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15493   DONE;
15494 })
15495
15496 (define_expand "atandf2"
15497   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15498                    (unspec:DF [(match_dup 2)
15499                                (match_operand:DF 1 "register_operand" "")]
15500                     UNSPEC_FPATAN))
15501               (clobber (match_scratch:DF 3 ""))])]
15502   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15503    && flag_unsafe_math_optimizations"
15504 {
15505   operands[2] = gen_reg_rtx (DFmode);
15506   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15507 })
15508
15509 (define_insn "atan2sf3_1"
15510   [(set (match_operand:SF 0 "register_operand" "=f")
15511         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15512                     (match_operand:SF 1 "register_operand" "u")]
15513                    UNSPEC_FPATAN))
15514    (clobber (match_scratch:SF 3 "=1"))]
15515   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15516    && flag_unsafe_math_optimizations"
15517   "fpatan"
15518   [(set_attr "type" "fpspc")
15519    (set_attr "mode" "SF")])
15520
15521 (define_expand "atan2sf3"
15522   [(use (match_operand:SF 0 "register_operand" "=f"))
15523    (use (match_operand:SF 2 "register_operand" "0"))
15524    (use (match_operand:SF 1 "register_operand" "u"))]
15525   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15526    && flag_unsafe_math_optimizations"
15527 {
15528   rtx copy = gen_reg_rtx (SFmode);
15529   emit_move_insn (copy, operands[1]);
15530   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15531   DONE;
15532 })
15533
15534 (define_expand "atansf2"
15535   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15536                    (unspec:SF [(match_dup 2)
15537                                (match_operand:SF 1 "register_operand" "")]
15538                     UNSPEC_FPATAN))
15539               (clobber (match_scratch:SF 3 ""))])]
15540   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15541    && flag_unsafe_math_optimizations"
15542 {
15543   operands[2] = gen_reg_rtx (SFmode);
15544   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15545 })
15546
15547 (define_insn "atan2xf3_1"
15548   [(set (match_operand:XF 0 "register_operand" "=f")
15549         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15550                     (match_operand:XF 1 "register_operand" "u")]
15551                    UNSPEC_FPATAN))
15552    (clobber (match_scratch:XF 3 "=1"))]
15553   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15554    && flag_unsafe_math_optimizations"
15555   "fpatan"
15556   [(set_attr "type" "fpspc")
15557    (set_attr "mode" "XF")])
15558
15559 (define_expand "atan2xf3"
15560   [(use (match_operand:XF 0 "register_operand" "=f"))
15561    (use (match_operand:XF 2 "register_operand" "0"))
15562    (use (match_operand:XF 1 "register_operand" "u"))]
15563   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15564    && flag_unsafe_math_optimizations"
15565 {
15566   rtx copy = gen_reg_rtx (XFmode);
15567   emit_move_insn (copy, operands[1]);
15568   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15569   DONE;
15570 })
15571
15572 (define_expand "atanxf2"
15573   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15574                    (unspec:XF [(match_dup 2)
15575                                (match_operand:XF 1 "register_operand" "")]
15576                     UNSPEC_FPATAN))
15577               (clobber (match_scratch:XF 3 ""))])]
15578   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15579    && flag_unsafe_math_optimizations"
15580 {
15581   operands[2] = gen_reg_rtx (XFmode);
15582   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15583 })
15584
15585 (define_expand "asindf2"
15586   [(set (match_dup 2)
15587         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15588    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15589    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15590    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15591    (parallel [(set (match_dup 7)
15592                    (unspec:XF [(match_dup 6) (match_dup 2)]
15593                               UNSPEC_FPATAN))
15594               (clobber (match_scratch:XF 8 ""))])
15595    (set (match_operand:DF 0 "register_operand" "")
15596         (float_truncate:DF (match_dup 7)))]
15597   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15598    && flag_unsafe_math_optimizations"
15599 {
15600   int i;
15601
15602   for (i=2; i<8; i++)
15603     operands[i] = gen_reg_rtx (XFmode);
15604
15605   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15606 })
15607
15608 (define_expand "asinsf2"
15609   [(set (match_dup 2)
15610         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15611    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15612    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15613    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15614    (parallel [(set (match_dup 7)
15615                    (unspec:XF [(match_dup 6) (match_dup 2)]
15616                               UNSPEC_FPATAN))
15617               (clobber (match_scratch:XF 8 ""))])
15618    (set (match_operand:SF 0 "register_operand" "")
15619         (float_truncate:SF (match_dup 7)))]
15620   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15621    && flag_unsafe_math_optimizations"
15622 {
15623   int i;
15624
15625   for (i=2; i<8; i++)
15626     operands[i] = gen_reg_rtx (XFmode);
15627
15628   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15629 })
15630
15631 (define_expand "asinxf2"
15632   [(set (match_dup 2)
15633         (mult:XF (match_operand:XF 1 "register_operand" "")
15634                  (match_dup 1)))
15635    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15636    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15637    (parallel [(set (match_operand:XF 0 "register_operand" "")
15638                    (unspec:XF [(match_dup 5) (match_dup 1)]
15639                               UNSPEC_FPATAN))
15640               (clobber (match_scratch:XF 6 ""))])]
15641   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15642    && flag_unsafe_math_optimizations"
15643 {
15644   int i;
15645
15646   for (i=2; i<6; i++)
15647     operands[i] = gen_reg_rtx (XFmode);
15648
15649   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15650 })
15651
15652 (define_expand "acosdf2"
15653   [(set (match_dup 2)
15654         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15655    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15656    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15657    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15658    (parallel [(set (match_dup 7)
15659                    (unspec:XF [(match_dup 2) (match_dup 6)]
15660                               UNSPEC_FPATAN))
15661               (clobber (match_scratch:XF 8 ""))])
15662    (set (match_operand:DF 0 "register_operand" "")
15663         (float_truncate:DF (match_dup 7)))]
15664   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15665    && flag_unsafe_math_optimizations"
15666 {
15667   int i;
15668
15669   for (i=2; i<8; i++)
15670     operands[i] = gen_reg_rtx (XFmode);
15671
15672   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15673 })
15674
15675 (define_expand "acossf2"
15676   [(set (match_dup 2)
15677         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15678    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15679    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15680    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15681    (parallel [(set (match_dup 7)
15682                    (unspec:XF [(match_dup 2) (match_dup 6)]
15683                               UNSPEC_FPATAN))
15684               (clobber (match_scratch:XF 8 ""))])
15685    (set (match_operand:SF 0 "register_operand" "")
15686         (float_truncate:SF (match_dup 7)))]
15687   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15688    && flag_unsafe_math_optimizations"
15689 {
15690   int i;
15691
15692   for (i=2; i<8; i++)
15693     operands[i] = gen_reg_rtx (XFmode);
15694
15695   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15696 })
15697
15698 (define_expand "acosxf2"
15699   [(set (match_dup 2)
15700         (mult:XF (match_operand:XF 1 "register_operand" "")
15701                  (match_dup 1)))
15702    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15703    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15704    (parallel [(set (match_operand:XF 0 "register_operand" "")
15705                    (unspec:XF [(match_dup 1) (match_dup 5)]
15706                               UNSPEC_FPATAN))
15707               (clobber (match_scratch:XF 6 ""))])]
15708   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15709    && flag_unsafe_math_optimizations"
15710 {
15711   int i;
15712
15713   for (i=2; i<6; i++)
15714     operands[i] = gen_reg_rtx (XFmode);
15715
15716   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15717 })
15718
15719 (define_insn "fyl2x_xf3"
15720   [(set (match_operand:XF 0 "register_operand" "=f")
15721         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15722                     (match_operand:XF 1 "register_operand" "u")]
15723                    UNSPEC_FYL2X))
15724    (clobber (match_scratch:XF 3 "=1"))]
15725   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15726    && flag_unsafe_math_optimizations"
15727   "fyl2x"
15728   [(set_attr "type" "fpspc")
15729    (set_attr "mode" "XF")])
15730
15731 (define_expand "logsf2"
15732   [(set (match_dup 2)
15733         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15734    (parallel [(set (match_dup 4)
15735                    (unspec:XF [(match_dup 2)
15736                                (match_dup 3)] UNSPEC_FYL2X))
15737               (clobber (match_scratch:XF 5 ""))])
15738    (set (match_operand:SF 0 "register_operand" "")
15739         (float_truncate:SF (match_dup 4)))]
15740   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15741    && flag_unsafe_math_optimizations"
15742 {
15743   rtx temp;
15744
15745   operands[2] = gen_reg_rtx (XFmode);
15746   operands[3] = gen_reg_rtx (XFmode);
15747   operands[4] = gen_reg_rtx (XFmode);
15748
15749   temp = standard_80387_constant_rtx (4); /* fldln2 */
15750   emit_move_insn (operands[3], temp);
15751 })
15752
15753 (define_expand "logdf2"
15754   [(set (match_dup 2)
15755         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15756    (parallel [(set (match_dup 4)
15757                    (unspec:XF [(match_dup 2)
15758                                (match_dup 3)] UNSPEC_FYL2X))
15759               (clobber (match_scratch:XF 5 ""))])
15760    (set (match_operand:DF 0 "register_operand" "")
15761         (float_truncate:DF (match_dup 4)))]
15762   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15763    && flag_unsafe_math_optimizations"
15764 {
15765   rtx temp;
15766
15767   operands[2] = gen_reg_rtx (XFmode);
15768   operands[3] = gen_reg_rtx (XFmode);
15769   operands[4] = gen_reg_rtx (XFmode);
15770
15771   temp = standard_80387_constant_rtx (4); /* fldln2 */
15772   emit_move_insn (operands[3], temp);
15773 })
15774
15775 (define_expand "logxf2"
15776   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15777                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15778                                (match_dup 2)] UNSPEC_FYL2X))
15779               (clobber (match_scratch:XF 3 ""))])]
15780   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15781    && flag_unsafe_math_optimizations"
15782 {
15783   rtx temp;
15784
15785   operands[2] = gen_reg_rtx (XFmode);
15786   temp = standard_80387_constant_rtx (4); /* fldln2 */
15787   emit_move_insn (operands[2], temp);
15788 })
15789
15790 (define_expand "log10sf2"
15791   [(set (match_dup 2)
15792         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15793    (parallel [(set (match_dup 4)
15794                    (unspec:XF [(match_dup 2)
15795                                (match_dup 3)] UNSPEC_FYL2X))
15796               (clobber (match_scratch:XF 5 ""))])
15797    (set (match_operand:SF 0 "register_operand" "")
15798         (float_truncate:SF (match_dup 4)))]
15799   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15800    && flag_unsafe_math_optimizations"
15801 {
15802   rtx temp;
15803
15804   operands[2] = gen_reg_rtx (XFmode);
15805   operands[3] = gen_reg_rtx (XFmode);
15806   operands[4] = gen_reg_rtx (XFmode);
15807
15808   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15809   emit_move_insn (operands[3], temp);
15810 })
15811
15812 (define_expand "log10df2"
15813   [(set (match_dup 2)
15814         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15815    (parallel [(set (match_dup 4)
15816                    (unspec:XF [(match_dup 2)
15817                                (match_dup 3)] UNSPEC_FYL2X))
15818               (clobber (match_scratch:XF 5 ""))])
15819    (set (match_operand:DF 0 "register_operand" "")
15820         (float_truncate:DF (match_dup 4)))]
15821   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15822    && flag_unsafe_math_optimizations"
15823 {
15824   rtx temp;
15825
15826   operands[2] = gen_reg_rtx (XFmode);
15827   operands[3] = gen_reg_rtx (XFmode);
15828   operands[4] = gen_reg_rtx (XFmode);
15829
15830   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15831   emit_move_insn (operands[3], temp);
15832 })
15833
15834 (define_expand "log10xf2"
15835   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15836                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15837                                (match_dup 2)] UNSPEC_FYL2X))
15838               (clobber (match_scratch:XF 3 ""))])]
15839   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15840    && flag_unsafe_math_optimizations"
15841 {
15842   rtx temp;
15843
15844   operands[2] = gen_reg_rtx (XFmode);
15845   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15846   emit_move_insn (operands[2], temp);
15847 })
15848
15849 (define_expand "log2sf2"
15850   [(set (match_dup 2)
15851         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15852    (parallel [(set (match_dup 4)
15853                    (unspec:XF [(match_dup 2)
15854                                (match_dup 3)] UNSPEC_FYL2X))
15855               (clobber (match_scratch:XF 5 ""))])
15856    (set (match_operand:SF 0 "register_operand" "")
15857         (float_truncate:SF (match_dup 4)))]
15858   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15859    && flag_unsafe_math_optimizations"
15860 {
15861   operands[2] = gen_reg_rtx (XFmode);
15862   operands[3] = gen_reg_rtx (XFmode);
15863   operands[4] = gen_reg_rtx (XFmode);
15864
15865   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15866 })
15867
15868 (define_expand "log2df2"
15869   [(set (match_dup 2)
15870         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15871    (parallel [(set (match_dup 4)
15872                    (unspec:XF [(match_dup 2)
15873                                (match_dup 3)] UNSPEC_FYL2X))
15874               (clobber (match_scratch:XF 5 ""))])
15875    (set (match_operand:DF 0 "register_operand" "")
15876         (float_truncate:DF (match_dup 4)))]
15877   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15878    && flag_unsafe_math_optimizations"
15879 {
15880   operands[2] = gen_reg_rtx (XFmode);
15881   operands[3] = gen_reg_rtx (XFmode);
15882   operands[4] = gen_reg_rtx (XFmode);
15883
15884   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15885 })
15886
15887 (define_expand "log2xf2"
15888   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15889                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15890                                (match_dup 2)] UNSPEC_FYL2X))
15891               (clobber (match_scratch:XF 3 ""))])]
15892   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15893    && flag_unsafe_math_optimizations"
15894 {
15895   operands[2] = gen_reg_rtx (XFmode);
15896   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15897 })
15898
15899 (define_insn "fyl2xp1_xf3"
15900   [(set (match_operand:XF 0 "register_operand" "=f")
15901         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15902                     (match_operand:XF 1 "register_operand" "u")]
15903                    UNSPEC_FYL2XP1))
15904    (clobber (match_scratch:XF 3 "=1"))]
15905   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15906    && flag_unsafe_math_optimizations"
15907   "fyl2xp1"
15908   [(set_attr "type" "fpspc")
15909    (set_attr "mode" "XF")])
15910
15911 (define_expand "log1psf2"
15912   [(use (match_operand:XF 0 "register_operand" ""))
15913    (use (match_operand:XF 1 "register_operand" ""))]
15914   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15915    && flag_unsafe_math_optimizations"
15916 {
15917   rtx op0 = gen_reg_rtx (XFmode);
15918   rtx op1 = gen_reg_rtx (XFmode);
15919
15920   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15921   ix86_emit_i387_log1p (op0, op1);
15922   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15923   DONE;
15924 })
15925
15926 (define_expand "log1pdf2"
15927   [(use (match_operand:XF 0 "register_operand" ""))
15928    (use (match_operand:XF 1 "register_operand" ""))]
15929   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15930    && flag_unsafe_math_optimizations"
15931 {
15932   rtx op0 = gen_reg_rtx (XFmode);
15933   rtx op1 = gen_reg_rtx (XFmode);
15934
15935   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15936   ix86_emit_i387_log1p (op0, op1);
15937   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15938   DONE;
15939 })
15940
15941 (define_expand "log1pxf2"
15942   [(use (match_operand:XF 0 "register_operand" ""))
15943    (use (match_operand:XF 1 "register_operand" ""))]
15944   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15945    && flag_unsafe_math_optimizations"
15946 {
15947   ix86_emit_i387_log1p (operands[0], operands[1]);
15948   DONE;
15949 })
15950
15951 (define_insn "*fxtractxf3"
15952   [(set (match_operand:XF 0 "register_operand" "=f")
15953         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15954                    UNSPEC_XTRACT_FRACT))
15955    (set (match_operand:XF 1 "register_operand" "=u")
15956         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15957   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15958    && flag_unsafe_math_optimizations"
15959   "fxtract"
15960   [(set_attr "type" "fpspc")
15961    (set_attr "mode" "XF")])
15962
15963 (define_expand "logbsf2"
15964   [(set (match_dup 2)
15965         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15966    (parallel [(set (match_dup 3)
15967                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15968               (set (match_dup 4)
15969                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15970    (set (match_operand:SF 0 "register_operand" "")
15971         (float_truncate:SF (match_dup 4)))]
15972   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15973    && flag_unsafe_math_optimizations"
15974 {
15975   operands[2] = gen_reg_rtx (XFmode);
15976   operands[3] = gen_reg_rtx (XFmode);
15977   operands[4] = gen_reg_rtx (XFmode);
15978 })
15979
15980 (define_expand "logbdf2"
15981   [(set (match_dup 2)
15982         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15983    (parallel [(set (match_dup 3)
15984                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15985               (set (match_dup 4)
15986                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15987    (set (match_operand:DF 0 "register_operand" "")
15988         (float_truncate:DF (match_dup 4)))]
15989   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15990    && flag_unsafe_math_optimizations"
15991 {
15992   operands[2] = gen_reg_rtx (XFmode);
15993   operands[3] = gen_reg_rtx (XFmode);
15994   operands[4] = gen_reg_rtx (XFmode);
15995 })
15996
15997 (define_expand "logbxf2"
15998   [(parallel [(set (match_dup 2)
15999                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16000                               UNSPEC_XTRACT_FRACT))
16001               (set (match_operand:XF 0 "register_operand" "")
16002                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16003   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16004    && flag_unsafe_math_optimizations"
16005 {
16006   operands[2] = gen_reg_rtx (XFmode);
16007 })
16008
16009 (define_expand "ilogbsi2"
16010   [(parallel [(set (match_dup 2)
16011                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16012                               UNSPEC_XTRACT_FRACT))
16013               (set (match_operand:XF 3 "register_operand" "")
16014                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16015    (parallel [(set (match_operand:SI 0 "register_operand" "")
16016                    (fix:SI (match_dup 3)))
16017               (clobber (reg:CC FLAGS_REG))])]
16018   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16019    && flag_unsafe_math_optimizations"
16020 {
16021   operands[2] = gen_reg_rtx (XFmode);
16022   operands[3] = gen_reg_rtx (XFmode);
16023 })
16024
16025 (define_insn "*frndintxf2"
16026   [(set (match_operand:XF 0 "register_operand" "=f")
16027         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16028          UNSPEC_FRNDINT))]
16029   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16030    && flag_unsafe_math_optimizations"
16031   "frndint"
16032   [(set_attr "type" "fpspc")
16033    (set_attr "mode" "XF")])
16034
16035 (define_insn "*f2xm1xf2"
16036   [(set (match_operand:XF 0 "register_operand" "=f")
16037         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16038          UNSPEC_F2XM1))]
16039   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16040    && flag_unsafe_math_optimizations"
16041   "f2xm1"
16042   [(set_attr "type" "fpspc")
16043    (set_attr "mode" "XF")])
16044
16045 (define_insn "*fscalexf4"
16046   [(set (match_operand:XF 0 "register_operand" "=f")
16047         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16048                     (match_operand:XF 3 "register_operand" "1")]
16049                    UNSPEC_FSCALE_FRACT))
16050    (set (match_operand:XF 1 "register_operand" "=u")
16051         (unspec:XF [(match_dup 2) (match_dup 3)]
16052                    UNSPEC_FSCALE_EXP))]
16053   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16054    && flag_unsafe_math_optimizations"
16055   "fscale"
16056   [(set_attr "type" "fpspc")
16057    (set_attr "mode" "XF")])
16058
16059 (define_expand "expsf2"
16060   [(set (match_dup 2)
16061         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16062    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16063    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16064    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16065    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16066    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16067    (parallel [(set (match_dup 10)
16068                    (unspec:XF [(match_dup 9) (match_dup 5)]
16069                               UNSPEC_FSCALE_FRACT))
16070               (set (match_dup 11)
16071                    (unspec:XF [(match_dup 9) (match_dup 5)]
16072                               UNSPEC_FSCALE_EXP))])
16073    (set (match_operand:SF 0 "register_operand" "")
16074         (float_truncate:SF (match_dup 10)))]
16075   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16076    && flag_unsafe_math_optimizations"
16077 {
16078   rtx temp;
16079   int i;
16080
16081   for (i=2; i<12; i++)
16082     operands[i] = gen_reg_rtx (XFmode);
16083   temp = standard_80387_constant_rtx (5); /* fldl2e */
16084   emit_move_insn (operands[3], temp);
16085   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16086 })
16087
16088 (define_expand "expdf2"
16089   [(set (match_dup 2)
16090         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16091    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16092    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16093    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16094    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16095    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16096    (parallel [(set (match_dup 10)
16097                    (unspec:XF [(match_dup 9) (match_dup 5)]
16098                               UNSPEC_FSCALE_FRACT))
16099               (set (match_dup 11)
16100                    (unspec:XF [(match_dup 9) (match_dup 5)]
16101                               UNSPEC_FSCALE_EXP))])
16102    (set (match_operand:DF 0 "register_operand" "")
16103         (float_truncate:DF (match_dup 10)))]
16104   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16105    && flag_unsafe_math_optimizations"
16106 {
16107   rtx temp;
16108   int i;
16109
16110   for (i=2; i<12; i++)
16111     operands[i] = gen_reg_rtx (XFmode);
16112   temp = standard_80387_constant_rtx (5); /* fldl2e */
16113   emit_move_insn (operands[3], temp);
16114   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16115 })
16116
16117 (define_expand "expxf2"
16118   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16119                                (match_dup 2)))
16120    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16121    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16122    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16123    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16124    (parallel [(set (match_operand:XF 0 "register_operand" "")
16125                    (unspec:XF [(match_dup 8) (match_dup 4)]
16126                               UNSPEC_FSCALE_FRACT))
16127               (set (match_dup 9)
16128                    (unspec:XF [(match_dup 8) (match_dup 4)]
16129                               UNSPEC_FSCALE_EXP))])]
16130   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16131    && flag_unsafe_math_optimizations"
16132 {
16133   rtx temp;
16134   int i;
16135
16136   for (i=2; i<10; i++)
16137     operands[i] = gen_reg_rtx (XFmode);
16138   temp = standard_80387_constant_rtx (5); /* fldl2e */
16139   emit_move_insn (operands[2], temp);
16140   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16141 })
16142
16143 (define_expand "exp10sf2"
16144   [(set (match_dup 2)
16145         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16146    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16147    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16148    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16149    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16150    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16151    (parallel [(set (match_dup 10)
16152                    (unspec:XF [(match_dup 9) (match_dup 5)]
16153                               UNSPEC_FSCALE_FRACT))
16154               (set (match_dup 11)
16155                    (unspec:XF [(match_dup 9) (match_dup 5)]
16156                               UNSPEC_FSCALE_EXP))])
16157    (set (match_operand:SF 0 "register_operand" "")
16158         (float_truncate:SF (match_dup 10)))]
16159   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16160    && flag_unsafe_math_optimizations"
16161 {
16162   rtx temp;
16163   int i;
16164
16165   for (i=2; i<12; i++)
16166     operands[i] = gen_reg_rtx (XFmode);
16167   temp = standard_80387_constant_rtx (6); /* fldl2t */
16168   emit_move_insn (operands[3], temp);
16169   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16170 })
16171
16172 (define_expand "exp10df2"
16173   [(set (match_dup 2)
16174         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16175    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16176    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16177    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16178    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16179    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16180    (parallel [(set (match_dup 10)
16181                    (unspec:XF [(match_dup 9) (match_dup 5)]
16182                               UNSPEC_FSCALE_FRACT))
16183               (set (match_dup 11)
16184                    (unspec:XF [(match_dup 9) (match_dup 5)]
16185                               UNSPEC_FSCALE_EXP))])
16186    (set (match_operand:DF 0 "register_operand" "")
16187         (float_truncate:DF (match_dup 10)))]
16188   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16189    && flag_unsafe_math_optimizations"
16190 {
16191   rtx temp;
16192   int i;
16193
16194   for (i=2; i<12; i++)
16195     operands[i] = gen_reg_rtx (XFmode);
16196   temp = standard_80387_constant_rtx (6); /* fldl2t */
16197   emit_move_insn (operands[3], temp);
16198   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16199 })
16200
16201 (define_expand "exp10xf2"
16202   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16203                                (match_dup 2)))
16204    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16205    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16206    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16207    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16208    (parallel [(set (match_operand:XF 0 "register_operand" "")
16209                    (unspec:XF [(match_dup 8) (match_dup 4)]
16210                               UNSPEC_FSCALE_FRACT))
16211               (set (match_dup 9)
16212                    (unspec:XF [(match_dup 8) (match_dup 4)]
16213                               UNSPEC_FSCALE_EXP))])]
16214   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16215    && flag_unsafe_math_optimizations"
16216 {
16217   rtx temp;
16218   int i;
16219
16220   for (i=2; i<10; i++)
16221     operands[i] = gen_reg_rtx (XFmode);
16222   temp = standard_80387_constant_rtx (6); /* fldl2t */
16223   emit_move_insn (operands[2], temp);
16224   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16225 })
16226
16227 (define_expand "exp2sf2"
16228   [(set (match_dup 2)
16229         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16230    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16231    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16232    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16233    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16234    (parallel [(set (match_dup 8)
16235                    (unspec:XF [(match_dup 7) (match_dup 3)]
16236                               UNSPEC_FSCALE_FRACT))
16237               (set (match_dup 9)
16238                    (unspec:XF [(match_dup 7) (match_dup 3)]
16239                               UNSPEC_FSCALE_EXP))])
16240    (set (match_operand:SF 0 "register_operand" "")
16241         (float_truncate:SF (match_dup 8)))]
16242   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16243    && flag_unsafe_math_optimizations"
16244 {
16245   int i;
16246
16247   for (i=2; i<10; i++)
16248     operands[i] = gen_reg_rtx (XFmode);
16249   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16250 })
16251
16252 (define_expand "exp2df2"
16253   [(set (match_dup 2)
16254         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16255    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16256    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16257    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16258    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16259    (parallel [(set (match_dup 8)
16260                    (unspec:XF [(match_dup 7) (match_dup 3)]
16261                               UNSPEC_FSCALE_FRACT))
16262               (set (match_dup 9)
16263                    (unspec:XF [(match_dup 7) (match_dup 3)]
16264                               UNSPEC_FSCALE_EXP))])
16265    (set (match_operand:DF 0 "register_operand" "")
16266         (float_truncate:DF (match_dup 8)))]
16267   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16268    && flag_unsafe_math_optimizations"
16269 {
16270   int i;
16271
16272   for (i=2; i<10; i++)
16273     operands[i] = gen_reg_rtx (XFmode);
16274   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16275 })
16276
16277 (define_expand "exp2xf2"
16278   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16279    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16280    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16281    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16282    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16283    (parallel [(set (match_operand:XF 0 "register_operand" "")
16284                    (unspec:XF [(match_dup 7) (match_dup 3)]
16285                               UNSPEC_FSCALE_FRACT))
16286               (set (match_dup 8)
16287                    (unspec:XF [(match_dup 7) (match_dup 3)]
16288                               UNSPEC_FSCALE_EXP))])]
16289   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16290    && flag_unsafe_math_optimizations"
16291 {
16292   int i;
16293
16294   for (i=2; i<9; i++)
16295     operands[i] = gen_reg_rtx (XFmode);
16296   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16297 })
16298
16299 (define_expand "expm1df2"
16300   [(set (match_dup 2)
16301         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16302    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16303    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16304    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16305    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16306    (parallel [(set (match_dup 8)
16307                    (unspec:XF [(match_dup 7) (match_dup 5)]
16308                               UNSPEC_FSCALE_FRACT))
16309                    (set (match_dup 9)
16310                    (unspec:XF [(match_dup 7) (match_dup 5)]
16311                               UNSPEC_FSCALE_EXP))])
16312    (parallel [(set (match_dup 11)
16313                    (unspec:XF [(match_dup 10) (match_dup 9)]
16314                               UNSPEC_FSCALE_FRACT))
16315               (set (match_dup 12)
16316                    (unspec:XF [(match_dup 10) (match_dup 9)]
16317                               UNSPEC_FSCALE_EXP))])
16318    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16319    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16320    (set (match_operand:DF 0 "register_operand" "")
16321         (float_truncate:DF (match_dup 14)))]
16322   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16323    && flag_unsafe_math_optimizations"
16324 {
16325   rtx temp;
16326   int i;
16327
16328   for (i=2; i<15; i++)
16329     operands[i] = gen_reg_rtx (XFmode);
16330   temp = standard_80387_constant_rtx (5); /* fldl2e */
16331   emit_move_insn (operands[3], temp);
16332   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16333 })
16334
16335 (define_expand "expm1sf2"
16336   [(set (match_dup 2)
16337         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16338    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16339    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16340    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16341    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16342    (parallel [(set (match_dup 8)
16343                    (unspec:XF [(match_dup 7) (match_dup 5)]
16344                               UNSPEC_FSCALE_FRACT))
16345                    (set (match_dup 9)
16346                    (unspec:XF [(match_dup 7) (match_dup 5)]
16347                               UNSPEC_FSCALE_EXP))])
16348    (parallel [(set (match_dup 11)
16349                    (unspec:XF [(match_dup 10) (match_dup 9)]
16350                               UNSPEC_FSCALE_FRACT))
16351               (set (match_dup 12)
16352                    (unspec:XF [(match_dup 10) (match_dup 9)]
16353                               UNSPEC_FSCALE_EXP))])
16354    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16355    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16356    (set (match_operand:SF 0 "register_operand" "")
16357         (float_truncate:SF (match_dup 14)))]
16358   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16359    && flag_unsafe_math_optimizations"
16360 {
16361   rtx temp;
16362   int i;
16363
16364   for (i=2; i<15; i++)
16365     operands[i] = gen_reg_rtx (XFmode);
16366   temp = standard_80387_constant_rtx (5); /* fldl2e */
16367   emit_move_insn (operands[3], temp);
16368   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16369 })
16370
16371 (define_expand "expm1xf2"
16372   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16373                                (match_dup 2)))
16374    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16375    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16376    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16377    (parallel [(set (match_dup 7)
16378                    (unspec:XF [(match_dup 6) (match_dup 4)]
16379                               UNSPEC_FSCALE_FRACT))
16380                    (set (match_dup 8)
16381                    (unspec:XF [(match_dup 6) (match_dup 4)]
16382                               UNSPEC_FSCALE_EXP))])
16383    (parallel [(set (match_dup 10)
16384                    (unspec:XF [(match_dup 9) (match_dup 8)]
16385                               UNSPEC_FSCALE_FRACT))
16386               (set (match_dup 11)
16387                    (unspec:XF [(match_dup 9) (match_dup 8)]
16388                               UNSPEC_FSCALE_EXP))])
16389    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16390    (set (match_operand:XF 0 "register_operand" "")
16391         (plus:XF (match_dup 12) (match_dup 7)))]
16392   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16393    && flag_unsafe_math_optimizations"
16394 {
16395   rtx temp;
16396   int i;
16397
16398   for (i=2; i<13; i++)
16399     operands[i] = gen_reg_rtx (XFmode);
16400   temp = standard_80387_constant_rtx (5); /* fldl2e */
16401   emit_move_insn (operands[2], temp);
16402   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16403 })
16404 \f
16405 ;; Block operation instructions
16406
16407 (define_insn "cld"
16408  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16409  ""
16410  "cld"
16411   [(set_attr "type" "cld")])
16412
16413 (define_expand "movmemsi"
16414   [(use (match_operand:BLK 0 "memory_operand" ""))
16415    (use (match_operand:BLK 1 "memory_operand" ""))
16416    (use (match_operand:SI 2 "nonmemory_operand" ""))
16417    (use (match_operand:SI 3 "const_int_operand" ""))]
16418   "! optimize_size"
16419 {
16420  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16421    DONE;
16422  else
16423    FAIL;
16424 })
16425
16426 (define_expand "movmemdi"
16427   [(use (match_operand:BLK 0 "memory_operand" ""))
16428    (use (match_operand:BLK 1 "memory_operand" ""))
16429    (use (match_operand:DI 2 "nonmemory_operand" ""))
16430    (use (match_operand:DI 3 "const_int_operand" ""))]
16431   "TARGET_64BIT"
16432 {
16433  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16434    DONE;
16435  else
16436    FAIL;
16437 })
16438
16439 ;; Most CPUs don't like single string operations
16440 ;; Handle this case here to simplify previous expander.
16441
16442 (define_expand "strmov"
16443   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16444    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16445    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16446               (clobber (reg:CC FLAGS_REG))])
16447    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16448               (clobber (reg:CC FLAGS_REG))])]
16449   ""
16450 {
16451   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16452
16453   /* If .md ever supports :P for Pmode, these can be directly
16454      in the pattern above.  */
16455   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16456   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16457
16458   if (TARGET_SINGLE_STRINGOP || optimize_size)
16459     {
16460       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16461                                       operands[2], operands[3],
16462                                       operands[5], operands[6]));
16463       DONE;
16464     }
16465
16466   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16467 })
16468
16469 (define_expand "strmov_singleop"
16470   [(parallel [(set (match_operand 1 "memory_operand" "")
16471                    (match_operand 3 "memory_operand" ""))
16472               (set (match_operand 0 "register_operand" "")
16473                    (match_operand 4 "" ""))
16474               (set (match_operand 2 "register_operand" "")
16475                    (match_operand 5 "" ""))
16476               (use (reg:SI DIRFLAG_REG))])]
16477   "TARGET_SINGLE_STRINGOP || optimize_size"
16478   "")
16479
16480 (define_insn "*strmovdi_rex_1"
16481   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16482         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16483    (set (match_operand:DI 0 "register_operand" "=D")
16484         (plus:DI (match_dup 2)
16485                  (const_int 8)))
16486    (set (match_operand:DI 1 "register_operand" "=S")
16487         (plus:DI (match_dup 3)
16488                  (const_int 8)))
16489    (use (reg:SI DIRFLAG_REG))]
16490   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16491   "movsq"
16492   [(set_attr "type" "str")
16493    (set_attr "mode" "DI")
16494    (set_attr "memory" "both")])
16495
16496 (define_insn "*strmovsi_1"
16497   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16498         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16499    (set (match_operand:SI 0 "register_operand" "=D")
16500         (plus:SI (match_dup 2)
16501                  (const_int 4)))
16502    (set (match_operand:SI 1 "register_operand" "=S")
16503         (plus:SI (match_dup 3)
16504                  (const_int 4)))
16505    (use (reg:SI DIRFLAG_REG))]
16506   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16507   "{movsl|movsd}"
16508   [(set_attr "type" "str")
16509    (set_attr "mode" "SI")
16510    (set_attr "memory" "both")])
16511
16512 (define_insn "*strmovsi_rex_1"
16513   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16514         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16515    (set (match_operand:DI 0 "register_operand" "=D")
16516         (plus:DI (match_dup 2)
16517                  (const_int 4)))
16518    (set (match_operand:DI 1 "register_operand" "=S")
16519         (plus:DI (match_dup 3)
16520                  (const_int 4)))
16521    (use (reg:SI DIRFLAG_REG))]
16522   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16523   "{movsl|movsd}"
16524   [(set_attr "type" "str")
16525    (set_attr "mode" "SI")
16526    (set_attr "memory" "both")])
16527
16528 (define_insn "*strmovhi_1"
16529   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16530         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16531    (set (match_operand:SI 0 "register_operand" "=D")
16532         (plus:SI (match_dup 2)
16533                  (const_int 2)))
16534    (set (match_operand:SI 1 "register_operand" "=S")
16535         (plus:SI (match_dup 3)
16536                  (const_int 2)))
16537    (use (reg:SI DIRFLAG_REG))]
16538   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16539   "movsw"
16540   [(set_attr "type" "str")
16541    (set_attr "memory" "both")
16542    (set_attr "mode" "HI")])
16543
16544 (define_insn "*strmovhi_rex_1"
16545   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16546         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16547    (set (match_operand:DI 0 "register_operand" "=D")
16548         (plus:DI (match_dup 2)
16549                  (const_int 2)))
16550    (set (match_operand:DI 1 "register_operand" "=S")
16551         (plus:DI (match_dup 3)
16552                  (const_int 2)))
16553    (use (reg:SI DIRFLAG_REG))]
16554   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16555   "movsw"
16556   [(set_attr "type" "str")
16557    (set_attr "memory" "both")
16558    (set_attr "mode" "HI")])
16559
16560 (define_insn "*strmovqi_1"
16561   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16562         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16563    (set (match_operand:SI 0 "register_operand" "=D")
16564         (plus:SI (match_dup 2)
16565                  (const_int 1)))
16566    (set (match_operand:SI 1 "register_operand" "=S")
16567         (plus:SI (match_dup 3)
16568                  (const_int 1)))
16569    (use (reg:SI DIRFLAG_REG))]
16570   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16571   "movsb"
16572   [(set_attr "type" "str")
16573    (set_attr "memory" "both")
16574    (set_attr "mode" "QI")])
16575
16576 (define_insn "*strmovqi_rex_1"
16577   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16578         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16579    (set (match_operand:DI 0 "register_operand" "=D")
16580         (plus:DI (match_dup 2)
16581                  (const_int 1)))
16582    (set (match_operand:DI 1 "register_operand" "=S")
16583         (plus:DI (match_dup 3)
16584                  (const_int 1)))
16585    (use (reg:SI DIRFLAG_REG))]
16586   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16587   "movsb"
16588   [(set_attr "type" "str")
16589    (set_attr "memory" "both")
16590    (set_attr "mode" "QI")])
16591
16592 (define_expand "rep_mov"
16593   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16594               (set (match_operand 0 "register_operand" "")
16595                    (match_operand 5 "" ""))
16596               (set (match_operand 2 "register_operand" "")
16597                    (match_operand 6 "" ""))
16598               (set (match_operand 1 "memory_operand" "")
16599                    (match_operand 3 "memory_operand" ""))
16600               (use (match_dup 4))
16601               (use (reg:SI DIRFLAG_REG))])]
16602   ""
16603   "")
16604
16605 (define_insn "*rep_movdi_rex64"
16606   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16607    (set (match_operand:DI 0 "register_operand" "=D") 
16608         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16609                             (const_int 3))
16610                  (match_operand:DI 3 "register_operand" "0")))
16611    (set (match_operand:DI 1 "register_operand" "=S") 
16612         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16613                  (match_operand:DI 4 "register_operand" "1")))
16614    (set (mem:BLK (match_dup 3))
16615         (mem:BLK (match_dup 4)))
16616    (use (match_dup 5))
16617    (use (reg:SI DIRFLAG_REG))]
16618   "TARGET_64BIT"
16619   "{rep\;movsq|rep movsq}"
16620   [(set_attr "type" "str")
16621    (set_attr "prefix_rep" "1")
16622    (set_attr "memory" "both")
16623    (set_attr "mode" "DI")])
16624
16625 (define_insn "*rep_movsi"
16626   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16627    (set (match_operand:SI 0 "register_operand" "=D") 
16628         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16629                             (const_int 2))
16630                  (match_operand:SI 3 "register_operand" "0")))
16631    (set (match_operand:SI 1 "register_operand" "=S") 
16632         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16633                  (match_operand:SI 4 "register_operand" "1")))
16634    (set (mem:BLK (match_dup 3))
16635         (mem:BLK (match_dup 4)))
16636    (use (match_dup 5))
16637    (use (reg:SI DIRFLAG_REG))]
16638   "!TARGET_64BIT"
16639   "{rep\;movsl|rep movsd}"
16640   [(set_attr "type" "str")
16641    (set_attr "prefix_rep" "1")
16642    (set_attr "memory" "both")
16643    (set_attr "mode" "SI")])
16644
16645 (define_insn "*rep_movsi_rex64"
16646   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16647    (set (match_operand:DI 0 "register_operand" "=D") 
16648         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16649                             (const_int 2))
16650                  (match_operand:DI 3 "register_operand" "0")))
16651    (set (match_operand:DI 1 "register_operand" "=S") 
16652         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16653                  (match_operand:DI 4 "register_operand" "1")))
16654    (set (mem:BLK (match_dup 3))
16655         (mem:BLK (match_dup 4)))
16656    (use (match_dup 5))
16657    (use (reg:SI DIRFLAG_REG))]
16658   "TARGET_64BIT"
16659   "{rep\;movsl|rep movsd}"
16660   [(set_attr "type" "str")
16661    (set_attr "prefix_rep" "1")
16662    (set_attr "memory" "both")
16663    (set_attr "mode" "SI")])
16664
16665 (define_insn "*rep_movqi"
16666   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16667    (set (match_operand:SI 0 "register_operand" "=D") 
16668         (plus:SI (match_operand:SI 3 "register_operand" "0")
16669                  (match_operand:SI 5 "register_operand" "2")))
16670    (set (match_operand:SI 1 "register_operand" "=S") 
16671         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16672    (set (mem:BLK (match_dup 3))
16673         (mem:BLK (match_dup 4)))
16674    (use (match_dup 5))
16675    (use (reg:SI DIRFLAG_REG))]
16676   "!TARGET_64BIT"
16677   "{rep\;movsb|rep movsb}"
16678   [(set_attr "type" "str")
16679    (set_attr "prefix_rep" "1")
16680    (set_attr "memory" "both")
16681    (set_attr "mode" "SI")])
16682
16683 (define_insn "*rep_movqi_rex64"
16684   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16685    (set (match_operand:DI 0 "register_operand" "=D") 
16686         (plus:DI (match_operand:DI 3 "register_operand" "0")
16687                  (match_operand:DI 5 "register_operand" "2")))
16688    (set (match_operand:DI 1 "register_operand" "=S") 
16689         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16690    (set (mem:BLK (match_dup 3))
16691         (mem:BLK (match_dup 4)))
16692    (use (match_dup 5))
16693    (use (reg:SI DIRFLAG_REG))]
16694   "TARGET_64BIT"
16695   "{rep\;movsb|rep movsb}"
16696   [(set_attr "type" "str")
16697    (set_attr "prefix_rep" "1")
16698    (set_attr "memory" "both")
16699    (set_attr "mode" "SI")])
16700
16701 (define_expand "clrmemsi"
16702    [(use (match_operand:BLK 0 "memory_operand" ""))
16703     (use (match_operand:SI 1 "nonmemory_operand" ""))
16704     (use (match_operand 2 "const_int_operand" ""))]
16705   ""
16706 {
16707  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16708    DONE;
16709  else
16710    FAIL;
16711 })
16712
16713 (define_expand "clrmemdi"
16714    [(use (match_operand:BLK 0 "memory_operand" ""))
16715     (use (match_operand:DI 1 "nonmemory_operand" ""))
16716     (use (match_operand 2 "const_int_operand" ""))]
16717   "TARGET_64BIT"
16718 {
16719  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16720    DONE;
16721  else
16722    FAIL;
16723 })
16724
16725 ;; Most CPUs don't like single string operations
16726 ;; Handle this case here to simplify previous expander.
16727
16728 (define_expand "strset"
16729   [(set (match_operand 1 "memory_operand" "")
16730         (match_operand 2 "register_operand" ""))
16731    (parallel [(set (match_operand 0 "register_operand" "")
16732                    (match_dup 3))
16733               (clobber (reg:CC FLAGS_REG))])]
16734   ""
16735 {
16736   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16737     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16738
16739   /* If .md ever supports :P for Pmode, this can be directly
16740      in the pattern above.  */
16741   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16742                               GEN_INT (GET_MODE_SIZE (GET_MODE
16743                                                       (operands[2]))));
16744   if (TARGET_SINGLE_STRINGOP || optimize_size)
16745     {
16746       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16747                                       operands[3]));
16748       DONE;
16749     }
16750 })
16751
16752 (define_expand "strset_singleop"
16753   [(parallel [(set (match_operand 1 "memory_operand" "")
16754                    (match_operand 2 "register_operand" ""))
16755               (set (match_operand 0 "register_operand" "")
16756                    (match_operand 3 "" ""))
16757               (use (reg:SI DIRFLAG_REG))])]
16758   "TARGET_SINGLE_STRINGOP || optimize_size"
16759   "")
16760
16761 (define_insn "*strsetdi_rex_1"
16762   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16763         (match_operand:SI 2 "register_operand" "a"))
16764    (set (match_operand:DI 0 "register_operand" "=D")
16765         (plus:DI (match_dup 1)
16766                  (const_int 8)))
16767    (use (reg:SI DIRFLAG_REG))]
16768   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16769   "stosq"
16770   [(set_attr "type" "str")
16771    (set_attr "memory" "store")
16772    (set_attr "mode" "DI")])
16773
16774 (define_insn "*strsetsi_1"
16775   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16776         (match_operand:SI 2 "register_operand" "a"))
16777    (set (match_operand:SI 0 "register_operand" "=D")
16778         (plus:SI (match_dup 1)
16779                  (const_int 4)))
16780    (use (reg:SI DIRFLAG_REG))]
16781   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16782   "{stosl|stosd}"
16783   [(set_attr "type" "str")
16784    (set_attr "memory" "store")
16785    (set_attr "mode" "SI")])
16786
16787 (define_insn "*strsetsi_rex_1"
16788   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16789         (match_operand:SI 2 "register_operand" "a"))
16790    (set (match_operand:DI 0 "register_operand" "=D")
16791         (plus:DI (match_dup 1)
16792                  (const_int 4)))
16793    (use (reg:SI DIRFLAG_REG))]
16794   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16795   "{stosl|stosd}"
16796   [(set_attr "type" "str")
16797    (set_attr "memory" "store")
16798    (set_attr "mode" "SI")])
16799
16800 (define_insn "*strsethi_1"
16801   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16802         (match_operand:HI 2 "register_operand" "a"))
16803    (set (match_operand:SI 0 "register_operand" "=D")
16804         (plus:SI (match_dup 1)
16805                  (const_int 2)))
16806    (use (reg:SI DIRFLAG_REG))]
16807   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16808   "stosw"
16809   [(set_attr "type" "str")
16810    (set_attr "memory" "store")
16811    (set_attr "mode" "HI")])
16812
16813 (define_insn "*strsethi_rex_1"
16814   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16815         (match_operand:HI 2 "register_operand" "a"))
16816    (set (match_operand:DI 0 "register_operand" "=D")
16817         (plus:DI (match_dup 1)
16818                  (const_int 2)))
16819    (use (reg:SI DIRFLAG_REG))]
16820   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16821   "stosw"
16822   [(set_attr "type" "str")
16823    (set_attr "memory" "store")
16824    (set_attr "mode" "HI")])
16825
16826 (define_insn "*strsetqi_1"
16827   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16828         (match_operand:QI 2 "register_operand" "a"))
16829    (set (match_operand:SI 0 "register_operand" "=D")
16830         (plus:SI (match_dup 1)
16831                  (const_int 1)))
16832    (use (reg:SI DIRFLAG_REG))]
16833   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16834   "stosb"
16835   [(set_attr "type" "str")
16836    (set_attr "memory" "store")
16837    (set_attr "mode" "QI")])
16838
16839 (define_insn "*strsetqi_rex_1"
16840   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16841         (match_operand:QI 2 "register_operand" "a"))
16842    (set (match_operand:DI 0 "register_operand" "=D")
16843         (plus:DI (match_dup 1)
16844                  (const_int 1)))
16845    (use (reg:SI DIRFLAG_REG))]
16846   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16847   "stosb"
16848   [(set_attr "type" "str")
16849    (set_attr "memory" "store")
16850    (set_attr "mode" "QI")])
16851
16852 (define_expand "rep_stos"
16853   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16854               (set (match_operand 0 "register_operand" "")
16855                    (match_operand 4 "" ""))
16856               (set (match_operand 2 "memory_operand" "") (const_int 0))
16857               (use (match_operand 3 "register_operand" ""))
16858               (use (match_dup 1))
16859               (use (reg:SI DIRFLAG_REG))])]
16860   ""
16861   "")
16862
16863 (define_insn "*rep_stosdi_rex64"
16864   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16865    (set (match_operand:DI 0 "register_operand" "=D") 
16866         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16867                             (const_int 3))
16868                  (match_operand:DI 3 "register_operand" "0")))
16869    (set (mem:BLK (match_dup 3))
16870         (const_int 0))
16871    (use (match_operand:DI 2 "register_operand" "a"))
16872    (use (match_dup 4))
16873    (use (reg:SI DIRFLAG_REG))]
16874   "TARGET_64BIT"
16875   "{rep\;stosq|rep stosq}"
16876   [(set_attr "type" "str")
16877    (set_attr "prefix_rep" "1")
16878    (set_attr "memory" "store")
16879    (set_attr "mode" "DI")])
16880
16881 (define_insn "*rep_stossi"
16882   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16883    (set (match_operand:SI 0 "register_operand" "=D") 
16884         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16885                             (const_int 2))
16886                  (match_operand:SI 3 "register_operand" "0")))
16887    (set (mem:BLK (match_dup 3))
16888         (const_int 0))
16889    (use (match_operand:SI 2 "register_operand" "a"))
16890    (use (match_dup 4))
16891    (use (reg:SI DIRFLAG_REG))]
16892   "!TARGET_64BIT"
16893   "{rep\;stosl|rep stosd}"
16894   [(set_attr "type" "str")
16895    (set_attr "prefix_rep" "1")
16896    (set_attr "memory" "store")
16897    (set_attr "mode" "SI")])
16898
16899 (define_insn "*rep_stossi_rex64"
16900   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16901    (set (match_operand:DI 0 "register_operand" "=D") 
16902         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16903                             (const_int 2))
16904                  (match_operand:DI 3 "register_operand" "0")))
16905    (set (mem:BLK (match_dup 3))
16906         (const_int 0))
16907    (use (match_operand:SI 2 "register_operand" "a"))
16908    (use (match_dup 4))
16909    (use (reg:SI DIRFLAG_REG))]
16910   "TARGET_64BIT"
16911   "{rep\;stosl|rep stosd}"
16912   [(set_attr "type" "str")
16913    (set_attr "prefix_rep" "1")
16914    (set_attr "memory" "store")
16915    (set_attr "mode" "SI")])
16916
16917 (define_insn "*rep_stosqi"
16918   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16919    (set (match_operand:SI 0 "register_operand" "=D") 
16920         (plus:SI (match_operand:SI 3 "register_operand" "0")
16921                  (match_operand:SI 4 "register_operand" "1")))
16922    (set (mem:BLK (match_dup 3))
16923         (const_int 0))
16924    (use (match_operand:QI 2 "register_operand" "a"))
16925    (use (match_dup 4))
16926    (use (reg:SI DIRFLAG_REG))]
16927   "!TARGET_64BIT"
16928   "{rep\;stosb|rep stosb}"
16929   [(set_attr "type" "str")
16930    (set_attr "prefix_rep" "1")
16931    (set_attr "memory" "store")
16932    (set_attr "mode" "QI")])
16933
16934 (define_insn "*rep_stosqi_rex64"
16935   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16936    (set (match_operand:DI 0 "register_operand" "=D") 
16937         (plus:DI (match_operand:DI 3 "register_operand" "0")
16938                  (match_operand:DI 4 "register_operand" "1")))
16939    (set (mem:BLK (match_dup 3))
16940         (const_int 0))
16941    (use (match_operand:QI 2 "register_operand" "a"))
16942    (use (match_dup 4))
16943    (use (reg:SI DIRFLAG_REG))]
16944   "TARGET_64BIT"
16945   "{rep\;stosb|rep stosb}"
16946   [(set_attr "type" "str")
16947    (set_attr "prefix_rep" "1")
16948    (set_attr "memory" "store")
16949    (set_attr "mode" "QI")])
16950
16951 (define_expand "cmpstrsi"
16952   [(set (match_operand:SI 0 "register_operand" "")
16953         (compare:SI (match_operand:BLK 1 "general_operand" "")
16954                     (match_operand:BLK 2 "general_operand" "")))
16955    (use (match_operand 3 "general_operand" ""))
16956    (use (match_operand 4 "immediate_operand" ""))]
16957   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16958 {
16959   rtx addr1, addr2, out, outlow, count, countreg, align;
16960
16961   /* Can't use this if the user has appropriated esi or edi.  */
16962   if (global_regs[4] || global_regs[5])
16963     FAIL;
16964
16965   out = operands[0];
16966   if (GET_CODE (out) != REG)
16967     out = gen_reg_rtx (SImode);
16968
16969   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16970   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16971   if (addr1 != XEXP (operands[1], 0))
16972     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16973   if (addr2 != XEXP (operands[2], 0))
16974     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16975
16976   count = operands[3];
16977   countreg = ix86_zero_extend_to_Pmode (count);
16978
16979   /* %%% Iff we are testing strict equality, we can use known alignment
16980      to good advantage.  This may be possible with combine, particularly
16981      once cc0 is dead.  */
16982   align = operands[4];
16983
16984   emit_insn (gen_cld ());
16985   if (GET_CODE (count) == CONST_INT)
16986     {
16987       if (INTVAL (count) == 0)
16988         {
16989           emit_move_insn (operands[0], const0_rtx);
16990           DONE;
16991         }
16992       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16993                                     operands[1], operands[2]));
16994     }
16995   else
16996     {
16997       if (TARGET_64BIT)
16998         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16999       else
17000         emit_insn (gen_cmpsi_1 (countreg, countreg));
17001       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17002                                  operands[1], operands[2]));
17003     }
17004
17005   outlow = gen_lowpart (QImode, out);
17006   emit_insn (gen_cmpintqi (outlow));
17007   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17008
17009   if (operands[0] != out)
17010     emit_move_insn (operands[0], out);
17011
17012   DONE;
17013 })
17014
17015 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17016
17017 (define_expand "cmpintqi"
17018   [(set (match_dup 1)
17019         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17020    (set (match_dup 2)
17021         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17022    (parallel [(set (match_operand:QI 0 "register_operand" "")
17023                    (minus:QI (match_dup 1)
17024                              (match_dup 2)))
17025               (clobber (reg:CC FLAGS_REG))])]
17026   ""
17027   "operands[1] = gen_reg_rtx (QImode);
17028    operands[2] = gen_reg_rtx (QImode);")
17029
17030 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17031 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17032
17033 (define_expand "cmpstrqi_nz_1"
17034   [(parallel [(set (reg:CC FLAGS_REG)
17035                    (compare:CC (match_operand 4 "memory_operand" "")
17036                                (match_operand 5 "memory_operand" "")))
17037               (use (match_operand 2 "register_operand" ""))
17038               (use (match_operand:SI 3 "immediate_operand" ""))
17039               (use (reg:SI DIRFLAG_REG))
17040               (clobber (match_operand 0 "register_operand" ""))
17041               (clobber (match_operand 1 "register_operand" ""))
17042               (clobber (match_dup 2))])]
17043   ""
17044   "")
17045
17046 (define_insn "*cmpstrqi_nz_1"
17047   [(set (reg:CC FLAGS_REG)
17048         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17049                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17050    (use (match_operand:SI 6 "register_operand" "2"))
17051    (use (match_operand:SI 3 "immediate_operand" "i"))
17052    (use (reg:SI DIRFLAG_REG))
17053    (clobber (match_operand:SI 0 "register_operand" "=S"))
17054    (clobber (match_operand:SI 1 "register_operand" "=D"))
17055    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17056   "!TARGET_64BIT"
17057   "repz{\;| }cmpsb"
17058   [(set_attr "type" "str")
17059    (set_attr "mode" "QI")
17060    (set_attr "prefix_rep" "1")])
17061
17062 (define_insn "*cmpstrqi_nz_rex_1"
17063   [(set (reg:CC FLAGS_REG)
17064         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17065                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17066    (use (match_operand:DI 6 "register_operand" "2"))
17067    (use (match_operand:SI 3 "immediate_operand" "i"))
17068    (use (reg:SI DIRFLAG_REG))
17069    (clobber (match_operand:DI 0 "register_operand" "=S"))
17070    (clobber (match_operand:DI 1 "register_operand" "=D"))
17071    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17072   "TARGET_64BIT"
17073   "repz{\;| }cmpsb"
17074   [(set_attr "type" "str")
17075    (set_attr "mode" "QI")
17076    (set_attr "prefix_rep" "1")])
17077
17078 ;; The same, but the count is not known to not be zero.
17079
17080 (define_expand "cmpstrqi_1"
17081   [(parallel [(set (reg:CC FLAGS_REG)
17082                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17083                                      (const_int 0))
17084                   (compare:CC (match_operand 4 "memory_operand" "")
17085                               (match_operand 5 "memory_operand" ""))
17086                   (const_int 0)))
17087               (use (match_operand:SI 3 "immediate_operand" ""))
17088               (use (reg:CC FLAGS_REG))
17089               (use (reg:SI DIRFLAG_REG))
17090               (clobber (match_operand 0 "register_operand" ""))
17091               (clobber (match_operand 1 "register_operand" ""))
17092               (clobber (match_dup 2))])]
17093   ""
17094   "")
17095
17096 (define_insn "*cmpstrqi_1"
17097   [(set (reg:CC FLAGS_REG)
17098         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17099                              (const_int 0))
17100           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17101                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17102           (const_int 0)))
17103    (use (match_operand:SI 3 "immediate_operand" "i"))
17104    (use (reg:CC FLAGS_REG))
17105    (use (reg:SI DIRFLAG_REG))
17106    (clobber (match_operand:SI 0 "register_operand" "=S"))
17107    (clobber (match_operand:SI 1 "register_operand" "=D"))
17108    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17109   "!TARGET_64BIT"
17110   "repz{\;| }cmpsb"
17111   [(set_attr "type" "str")
17112    (set_attr "mode" "QI")
17113    (set_attr "prefix_rep" "1")])
17114
17115 (define_insn "*cmpstrqi_rex_1"
17116   [(set (reg:CC FLAGS_REG)
17117         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17118                              (const_int 0))
17119           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17120                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17121           (const_int 0)))
17122    (use (match_operand:SI 3 "immediate_operand" "i"))
17123    (use (reg:CC FLAGS_REG))
17124    (use (reg:SI DIRFLAG_REG))
17125    (clobber (match_operand:DI 0 "register_operand" "=S"))
17126    (clobber (match_operand:DI 1 "register_operand" "=D"))
17127    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17128   "TARGET_64BIT"
17129   "repz{\;| }cmpsb"
17130   [(set_attr "type" "str")
17131    (set_attr "mode" "QI")
17132    (set_attr "prefix_rep" "1")])
17133
17134 (define_expand "strlensi"
17135   [(set (match_operand:SI 0 "register_operand" "")
17136         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17137                     (match_operand:QI 2 "immediate_operand" "")
17138                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17139   ""
17140 {
17141  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17142    DONE;
17143  else
17144    FAIL;
17145 })
17146
17147 (define_expand "strlendi"
17148   [(set (match_operand:DI 0 "register_operand" "")
17149         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17150                     (match_operand:QI 2 "immediate_operand" "")
17151                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17152   ""
17153 {
17154  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17155    DONE;
17156  else
17157    FAIL;
17158 })
17159
17160 (define_expand "strlenqi_1"
17161   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17162               (use (reg:SI DIRFLAG_REG))
17163               (clobber (match_operand 1 "register_operand" ""))
17164               (clobber (reg:CC FLAGS_REG))])]
17165   ""
17166   "")
17167
17168 (define_insn "*strlenqi_1"
17169   [(set (match_operand:SI 0 "register_operand" "=&c")
17170         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17171                     (match_operand:QI 2 "register_operand" "a")
17172                     (match_operand:SI 3 "immediate_operand" "i")
17173                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17174    (use (reg:SI DIRFLAG_REG))
17175    (clobber (match_operand:SI 1 "register_operand" "=D"))
17176    (clobber (reg:CC FLAGS_REG))]
17177   "!TARGET_64BIT"
17178   "repnz{\;| }scasb"
17179   [(set_attr "type" "str")
17180    (set_attr "mode" "QI")
17181    (set_attr "prefix_rep" "1")])
17182
17183 (define_insn "*strlenqi_rex_1"
17184   [(set (match_operand:DI 0 "register_operand" "=&c")
17185         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17186                     (match_operand:QI 2 "register_operand" "a")
17187                     (match_operand:DI 3 "immediate_operand" "i")
17188                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17189    (use (reg:SI DIRFLAG_REG))
17190    (clobber (match_operand:DI 1 "register_operand" "=D"))
17191    (clobber (reg:CC FLAGS_REG))]
17192   "TARGET_64BIT"
17193   "repnz{\;| }scasb"
17194   [(set_attr "type" "str")
17195    (set_attr "mode" "QI")
17196    (set_attr "prefix_rep" "1")])
17197
17198 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17199 ;; handled in combine, but it is not currently up to the task.
17200 ;; When used for their truth value, the cmpstr* expanders generate
17201 ;; code like this:
17202 ;;
17203 ;;   repz cmpsb
17204 ;;   seta       %al
17205 ;;   setb       %dl
17206 ;;   cmpb       %al, %dl
17207 ;;   jcc        label
17208 ;;
17209 ;; The intermediate three instructions are unnecessary.
17210
17211 ;; This one handles cmpstr*_nz_1...
17212 (define_peephole2
17213   [(parallel[
17214      (set (reg:CC FLAGS_REG)
17215           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17216                       (mem:BLK (match_operand 5 "register_operand" ""))))
17217      (use (match_operand 6 "register_operand" ""))
17218      (use (match_operand:SI 3 "immediate_operand" ""))
17219      (use (reg:SI DIRFLAG_REG))
17220      (clobber (match_operand 0 "register_operand" ""))
17221      (clobber (match_operand 1 "register_operand" ""))
17222      (clobber (match_operand 2 "register_operand" ""))])
17223    (set (match_operand:QI 7 "register_operand" "")
17224         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17225    (set (match_operand:QI 8 "register_operand" "")
17226         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17227    (set (reg 17)
17228         (compare (match_dup 7) (match_dup 8)))
17229   ]
17230   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17231   [(parallel[
17232      (set (reg:CC FLAGS_REG)
17233           (compare:CC (mem:BLK (match_dup 4))
17234                       (mem:BLK (match_dup 5))))
17235      (use (match_dup 6))
17236      (use (match_dup 3))
17237      (use (reg:SI DIRFLAG_REG))
17238      (clobber (match_dup 0))
17239      (clobber (match_dup 1))
17240      (clobber (match_dup 2))])]
17241   "")
17242
17243 ;; ...and this one handles cmpstr*_1.
17244 (define_peephole2
17245   [(parallel[
17246      (set (reg:CC FLAGS_REG)
17247           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17248                                (const_int 0))
17249             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17250                         (mem:BLK (match_operand 5 "register_operand" "")))
17251             (const_int 0)))
17252      (use (match_operand:SI 3 "immediate_operand" ""))
17253      (use (reg:CC FLAGS_REG))
17254      (use (reg:SI DIRFLAG_REG))
17255      (clobber (match_operand 0 "register_operand" ""))
17256      (clobber (match_operand 1 "register_operand" ""))
17257      (clobber (match_operand 2 "register_operand" ""))])
17258    (set (match_operand:QI 7 "register_operand" "")
17259         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17260    (set (match_operand:QI 8 "register_operand" "")
17261         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17262    (set (reg 17)
17263         (compare (match_dup 7) (match_dup 8)))
17264   ]
17265   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17266   [(parallel[
17267      (set (reg:CC FLAGS_REG)
17268           (if_then_else:CC (ne (match_dup 6)
17269                                (const_int 0))
17270             (compare:CC (mem:BLK (match_dup 4))
17271                         (mem:BLK (match_dup 5)))
17272             (const_int 0)))
17273      (use (match_dup 3))
17274      (use (reg:CC FLAGS_REG))
17275      (use (reg:SI DIRFLAG_REG))
17276      (clobber (match_dup 0))
17277      (clobber (match_dup 1))
17278      (clobber (match_dup 2))])]
17279   "")
17280
17281
17282 \f
17283 ;; Conditional move instructions.
17284
17285 (define_expand "movdicc"
17286   [(set (match_operand:DI 0 "register_operand" "")
17287         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17288                          (match_operand:DI 2 "general_operand" "")
17289                          (match_operand:DI 3 "general_operand" "")))]
17290   "TARGET_64BIT"
17291   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17292
17293 (define_insn "x86_movdicc_0_m1_rex64"
17294   [(set (match_operand:DI 0 "register_operand" "=r")
17295         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17296           (const_int -1)
17297           (const_int 0)))
17298    (clobber (reg:CC FLAGS_REG))]
17299   "TARGET_64BIT"
17300   "sbb{q}\t%0, %0"
17301   ; Since we don't have the proper number of operands for an alu insn,
17302   ; fill in all the blanks.
17303   [(set_attr "type" "alu")
17304    (set_attr "pent_pair" "pu")
17305    (set_attr "memory" "none")
17306    (set_attr "imm_disp" "false")
17307    (set_attr "mode" "DI")
17308    (set_attr "length_immediate" "0")])
17309
17310 (define_insn "movdicc_c_rex64"
17311   [(set (match_operand:DI 0 "register_operand" "=r,r")
17312         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17313                                 [(reg 17) (const_int 0)])
17314                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17315                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17316   "TARGET_64BIT && TARGET_CMOVE
17317    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17318   "@
17319    cmov%O2%C1\t{%2, %0|%0, %2}
17320    cmov%O2%c1\t{%3, %0|%0, %3}"
17321   [(set_attr "type" "icmov")
17322    (set_attr "mode" "DI")])
17323
17324 (define_expand "movsicc"
17325   [(set (match_operand:SI 0 "register_operand" "")
17326         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17327                          (match_operand:SI 2 "general_operand" "")
17328                          (match_operand:SI 3 "general_operand" "")))]
17329   ""
17330   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17331
17332 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17333 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17334 ;; So just document what we're doing explicitly.
17335
17336 (define_insn "x86_movsicc_0_m1"
17337   [(set (match_operand:SI 0 "register_operand" "=r")
17338         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17339           (const_int -1)
17340           (const_int 0)))
17341    (clobber (reg:CC FLAGS_REG))]
17342   ""
17343   "sbb{l}\t%0, %0"
17344   ; Since we don't have the proper number of operands for an alu insn,
17345   ; fill in all the blanks.
17346   [(set_attr "type" "alu")
17347    (set_attr "pent_pair" "pu")
17348    (set_attr "memory" "none")
17349    (set_attr "imm_disp" "false")
17350    (set_attr "mode" "SI")
17351    (set_attr "length_immediate" "0")])
17352
17353 (define_insn "*movsicc_noc"
17354   [(set (match_operand:SI 0 "register_operand" "=r,r")
17355         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17356                                 [(reg 17) (const_int 0)])
17357                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17358                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17359   "TARGET_CMOVE
17360    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17361   "@
17362    cmov%O2%C1\t{%2, %0|%0, %2}
17363    cmov%O2%c1\t{%3, %0|%0, %3}"
17364   [(set_attr "type" "icmov")
17365    (set_attr "mode" "SI")])
17366
17367 (define_expand "movhicc"
17368   [(set (match_operand:HI 0 "register_operand" "")
17369         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17370                          (match_operand:HI 2 "general_operand" "")
17371                          (match_operand:HI 3 "general_operand" "")))]
17372   "TARGET_HIMODE_MATH"
17373   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17374
17375 (define_insn "*movhicc_noc"
17376   [(set (match_operand:HI 0 "register_operand" "=r,r")
17377         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17378                                 [(reg 17) (const_int 0)])
17379                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17380                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17381   "TARGET_CMOVE
17382    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17383   "@
17384    cmov%O2%C1\t{%2, %0|%0, %2}
17385    cmov%O2%c1\t{%3, %0|%0, %3}"
17386   [(set_attr "type" "icmov")
17387    (set_attr "mode" "HI")])
17388
17389 (define_expand "movqicc"
17390   [(set (match_operand:QI 0 "register_operand" "")
17391         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17392                          (match_operand:QI 2 "general_operand" "")
17393                          (match_operand:QI 3 "general_operand" "")))]
17394   "TARGET_QIMODE_MATH"
17395   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17396
17397 (define_insn_and_split "*movqicc_noc"
17398   [(set (match_operand:QI 0 "register_operand" "=r,r")
17399         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17400                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17401                       (match_operand:QI 2 "register_operand" "r,0")
17402                       (match_operand:QI 3 "register_operand" "0,r")))]
17403   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17404   "#"
17405   "&& reload_completed"
17406   [(set (match_dup 0)
17407         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17408                       (match_dup 2)
17409                       (match_dup 3)))]
17410   "operands[0] = gen_lowpart (SImode, operands[0]);
17411    operands[2] = gen_lowpart (SImode, operands[2]);
17412    operands[3] = gen_lowpart (SImode, operands[3]);"
17413   [(set_attr "type" "icmov")
17414    (set_attr "mode" "SI")])
17415
17416 (define_expand "movsfcc"
17417   [(set (match_operand:SF 0 "register_operand" "")
17418         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17419                          (match_operand:SF 2 "register_operand" "")
17420                          (match_operand:SF 3 "register_operand" "")))]
17421   "TARGET_CMOVE"
17422   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17423
17424 (define_insn "*movsfcc_1"
17425   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17426         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17427                                 [(reg 17) (const_int 0)])
17428                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17429                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17430   "TARGET_CMOVE
17431    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17432   "@
17433    fcmov%F1\t{%2, %0|%0, %2}
17434    fcmov%f1\t{%3, %0|%0, %3}
17435    cmov%O2%C1\t{%2, %0|%0, %2}
17436    cmov%O2%c1\t{%3, %0|%0, %3}"
17437   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17438    (set_attr "mode" "SF,SF,SI,SI")])
17439
17440 (define_expand "movdfcc"
17441   [(set (match_operand:DF 0 "register_operand" "")
17442         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17443                          (match_operand:DF 2 "register_operand" "")
17444                          (match_operand:DF 3 "register_operand" "")))]
17445   "TARGET_CMOVE"
17446   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17447
17448 (define_insn "*movdfcc_1"
17449   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17450         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17451                                 [(reg 17) (const_int 0)])
17452                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17453                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17454   "!TARGET_64BIT && TARGET_CMOVE
17455    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17456   "@
17457    fcmov%F1\t{%2, %0|%0, %2}
17458    fcmov%f1\t{%3, %0|%0, %3}
17459    #
17460    #"
17461   [(set_attr "type" "fcmov,fcmov,multi,multi")
17462    (set_attr "mode" "DF")])
17463
17464 (define_insn "*movdfcc_1_rex64"
17465   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17466         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17467                                 [(reg 17) (const_int 0)])
17468                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17469                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17470   "TARGET_64BIT && TARGET_CMOVE
17471    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17472   "@
17473    fcmov%F1\t{%2, %0|%0, %2}
17474    fcmov%f1\t{%3, %0|%0, %3}
17475    cmov%O2%C1\t{%2, %0|%0, %2}
17476    cmov%O2%c1\t{%3, %0|%0, %3}"
17477   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17478    (set_attr "mode" "DF")])
17479
17480 (define_split
17481   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17482         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17483                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17484                       (match_operand:DF 2 "nonimmediate_operand" "")
17485                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17486   "!TARGET_64BIT && reload_completed"
17487   [(set (match_dup 2)
17488         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17489                       (match_dup 5)
17490                       (match_dup 7)))
17491    (set (match_dup 3)
17492         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17493                       (match_dup 6)
17494                       (match_dup 8)))]
17495   "split_di (operands+2, 1, operands+5, operands+6);
17496    split_di (operands+3, 1, operands+7, operands+8);
17497    split_di (operands, 1, operands+2, operands+3);")
17498
17499 (define_expand "movxfcc"
17500   [(set (match_operand:XF 0 "register_operand" "")
17501         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17502                          (match_operand:XF 2 "register_operand" "")
17503                          (match_operand:XF 3 "register_operand" "")))]
17504   "TARGET_CMOVE"
17505   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17506
17507 (define_insn "*movxfcc_1"
17508   [(set (match_operand:XF 0 "register_operand" "=f,f")
17509         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17510                                 [(reg 17) (const_int 0)])
17511                       (match_operand:XF 2 "register_operand" "f,0")
17512                       (match_operand:XF 3 "register_operand" "0,f")))]
17513   "TARGET_CMOVE"
17514   "@
17515    fcmov%F1\t{%2, %0|%0, %2}
17516    fcmov%f1\t{%3, %0|%0, %3}"
17517   [(set_attr "type" "fcmov")
17518    (set_attr "mode" "XF")])
17519
17520 (define_expand "minsf3"
17521   [(parallel [
17522      (set (match_operand:SF 0 "register_operand" "")
17523           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17524                                (match_operand:SF 2 "nonimmediate_operand" ""))
17525                            (match_dup 1)
17526                            (match_dup 2)))
17527      (clobber (reg:CC FLAGS_REG))])]
17528   "TARGET_SSE"
17529   "")
17530
17531 (define_insn "*minsf"
17532   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17533         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17534                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17535                          (match_dup 1)
17536                          (match_dup 2)))
17537    (clobber (reg:CC FLAGS_REG))]
17538   "TARGET_SSE && TARGET_IEEE_FP"
17539   "#")
17540
17541 (define_insn "*minsf_nonieee"
17542   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17543         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17544                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17545                          (match_dup 1)
17546                          (match_dup 2)))
17547    (clobber (reg:CC FLAGS_REG))]
17548   "TARGET_SSE && !TARGET_IEEE_FP
17549    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17550   "#")
17551
17552 (define_split
17553   [(set (match_operand:SF 0 "register_operand" "")
17554         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17555                              (match_operand:SF 2 "nonimmediate_operand" ""))
17556                          (match_operand:SF 3 "register_operand" "")
17557                          (match_operand:SF 4 "nonimmediate_operand" "")))
17558    (clobber (reg:CC FLAGS_REG))]
17559   "SSE_REG_P (operands[0]) && reload_completed
17560    && ((operands_match_p (operands[1], operands[3])
17561         && operands_match_p (operands[2], operands[4]))
17562        || (operands_match_p (operands[1], operands[4])
17563            && operands_match_p (operands[2], operands[3])))"
17564   [(set (match_dup 0)
17565         (if_then_else:SF (lt (match_dup 1)
17566                              (match_dup 2))
17567                          (match_dup 1)
17568                          (match_dup 2)))])
17569
17570 ;; Conditional addition patterns
17571 (define_expand "addqicc"
17572   [(match_operand:QI 0 "register_operand" "")
17573    (match_operand 1 "comparison_operator" "")
17574    (match_operand:QI 2 "register_operand" "")
17575    (match_operand:QI 3 "const_int_operand" "")]
17576   ""
17577   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17578
17579 (define_expand "addhicc"
17580   [(match_operand:HI 0 "register_operand" "")
17581    (match_operand 1 "comparison_operator" "")
17582    (match_operand:HI 2 "register_operand" "")
17583    (match_operand:HI 3 "const_int_operand" "")]
17584   ""
17585   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17586
17587 (define_expand "addsicc"
17588   [(match_operand:SI 0 "register_operand" "")
17589    (match_operand 1 "comparison_operator" "")
17590    (match_operand:SI 2 "register_operand" "")
17591    (match_operand:SI 3 "const_int_operand" "")]
17592   ""
17593   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17594
17595 (define_expand "adddicc"
17596   [(match_operand:DI 0 "register_operand" "")
17597    (match_operand 1 "comparison_operator" "")
17598    (match_operand:DI 2 "register_operand" "")
17599    (match_operand:DI 3 "const_int_operand" "")]
17600   "TARGET_64BIT"
17601   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17602
17603 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17604
17605 (define_split
17606   [(set (match_operand:SF 0 "fp_register_operand" "")
17607         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17608                              (match_operand:SF 2 "register_operand" ""))
17609                          (match_operand:SF 3 "register_operand" "")
17610                          (match_operand:SF 4 "register_operand" "")))
17611    (clobber (reg:CC FLAGS_REG))]
17612   "reload_completed
17613    && ((operands_match_p (operands[1], operands[3])
17614         && operands_match_p (operands[2], operands[4]))
17615        || (operands_match_p (operands[1], operands[4])
17616            && operands_match_p (operands[2], operands[3])))"
17617   [(set (reg:CCFP FLAGS_REG)
17618         (compare:CCFP (match_dup 2)
17619                       (match_dup 1)))
17620    (set (match_dup 0)
17621         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17622                          (match_dup 1)
17623                          (match_dup 2)))])
17624
17625 (define_insn "*minsf_sse"
17626   [(set (match_operand:SF 0 "register_operand" "=x")
17627         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17628                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17629                          (match_dup 1)
17630                          (match_dup 2)))]
17631   "TARGET_SSE && reload_completed"
17632   "minss\t{%2, %0|%0, %2}"
17633   [(set_attr "type" "sse")
17634    (set_attr "mode" "SF")])
17635
17636 (define_expand "mindf3"
17637   [(parallel [
17638      (set (match_operand:DF 0 "register_operand" "")
17639           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17640                                (match_operand:DF 2 "nonimmediate_operand" ""))
17641                            (match_dup 1)
17642                            (match_dup 2)))
17643      (clobber (reg:CC FLAGS_REG))])]
17644   "TARGET_SSE2 && TARGET_SSE_MATH"
17645   "#")
17646
17647 (define_insn "*mindf"
17648   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17649         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17650                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17651                          (match_dup 1)
17652                          (match_dup 2)))
17653    (clobber (reg:CC FLAGS_REG))]
17654   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17655   "#")
17656
17657 (define_insn "*mindf_nonieee"
17658   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17659         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17660                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17661                          (match_dup 1)
17662                          (match_dup 2)))
17663    (clobber (reg:CC FLAGS_REG))]
17664   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17665    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17666   "#")
17667
17668 (define_split
17669   [(set (match_operand:DF 0 "register_operand" "")
17670         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17671                              (match_operand:DF 2 "nonimmediate_operand" ""))
17672                          (match_operand:DF 3 "register_operand" "")
17673                          (match_operand:DF 4 "nonimmediate_operand" "")))
17674    (clobber (reg:CC FLAGS_REG))]
17675   "SSE_REG_P (operands[0]) && reload_completed
17676    && ((operands_match_p (operands[1], operands[3])
17677         && operands_match_p (operands[2], operands[4]))
17678        || (operands_match_p (operands[1], operands[4])
17679            && operands_match_p (operands[2], operands[3])))"
17680   [(set (match_dup 0)
17681         (if_then_else:DF (lt (match_dup 1)
17682                              (match_dup 2))
17683                          (match_dup 1)
17684                          (match_dup 2)))])
17685
17686 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17687 (define_split
17688   [(set (match_operand:DF 0 "fp_register_operand" "")
17689         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17690                              (match_operand:DF 2 "register_operand" ""))
17691                          (match_operand:DF 3 "register_operand" "")
17692                          (match_operand:DF 4 "register_operand" "")))
17693    (clobber (reg:CC FLAGS_REG))]
17694   "reload_completed
17695    && ((operands_match_p (operands[1], operands[3])
17696         && operands_match_p (operands[2], operands[4]))
17697        || (operands_match_p (operands[1], operands[4])
17698            && operands_match_p (operands[2], operands[3])))"
17699   [(set (reg:CCFP FLAGS_REG)
17700         (compare:CCFP (match_dup 2)
17701                       (match_dup 1)))
17702    (set (match_dup 0)
17703         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17704                          (match_dup 1)
17705                          (match_dup 2)))])
17706
17707 (define_insn "*mindf_sse"
17708   [(set (match_operand:DF 0 "register_operand" "=Y")
17709         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17710                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17711                          (match_dup 1)
17712                          (match_dup 2)))]
17713   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17714   "minsd\t{%2, %0|%0, %2}"
17715   [(set_attr "type" "sse")
17716    (set_attr "mode" "DF")])
17717
17718 (define_expand "maxsf3"
17719   [(parallel [
17720      (set (match_operand:SF 0 "register_operand" "")
17721           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17722                                (match_operand:SF 2 "nonimmediate_operand" ""))
17723                            (match_dup 1)
17724                            (match_dup 2)))
17725      (clobber (reg:CC FLAGS_REG))])]
17726   "TARGET_SSE"
17727   "#")
17728
17729 (define_insn "*maxsf"
17730   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17731         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17732                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17733                          (match_dup 1)
17734                          (match_dup 2)))
17735    (clobber (reg:CC FLAGS_REG))]
17736   "TARGET_SSE && TARGET_IEEE_FP"
17737   "#")
17738
17739 (define_insn "*maxsf_nonieee"
17740   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17741         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17742                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17743                          (match_dup 1)
17744                          (match_dup 2)))
17745    (clobber (reg:CC FLAGS_REG))]
17746   "TARGET_SSE && !TARGET_IEEE_FP
17747    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17748   "#")
17749
17750 (define_split
17751   [(set (match_operand:SF 0 "register_operand" "")
17752         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17753                              (match_operand:SF 2 "nonimmediate_operand" ""))
17754                          (match_operand:SF 3 "register_operand" "")
17755                          (match_operand:SF 4 "nonimmediate_operand" "")))
17756    (clobber (reg:CC FLAGS_REG))]
17757   "SSE_REG_P (operands[0]) && reload_completed
17758    && ((operands_match_p (operands[1], operands[3])
17759         && operands_match_p (operands[2], operands[4]))
17760        || (operands_match_p (operands[1], operands[4])
17761            && operands_match_p (operands[2], operands[3])))"
17762   [(set (match_dup 0)
17763         (if_then_else:SF (gt (match_dup 1)
17764                              (match_dup 2))
17765                          (match_dup 1)
17766                          (match_dup 2)))])
17767
17768 (define_split
17769   [(set (match_operand:SF 0 "fp_register_operand" "")
17770         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17771                              (match_operand:SF 2 "register_operand" ""))
17772                          (match_operand:SF 3 "register_operand" "")
17773                          (match_operand:SF 4 "register_operand" "")))
17774    (clobber (reg:CC FLAGS_REG))]
17775   "reload_completed
17776    && ((operands_match_p (operands[1], operands[3])
17777         && operands_match_p (operands[2], operands[4]))
17778        || (operands_match_p (operands[1], operands[4])
17779            && operands_match_p (operands[2], operands[3])))"
17780   [(set (reg:CCFP FLAGS_REG)
17781         (compare:CCFP (match_dup 1)
17782                       (match_dup 2)))
17783    (set (match_dup 0)
17784         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17785                          (match_dup 1)
17786                          (match_dup 2)))])
17787
17788 (define_insn "*maxsf_sse"
17789   [(set (match_operand:SF 0 "register_operand" "=x")
17790         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17791                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17792                          (match_dup 1)
17793                          (match_dup 2)))]
17794   "TARGET_SSE && reload_completed"
17795   "maxss\t{%2, %0|%0, %2}"
17796   [(set_attr "type" "sse")
17797    (set_attr "mode" "SF")])
17798
17799 (define_expand "maxdf3"
17800   [(parallel [
17801      (set (match_operand:DF 0 "register_operand" "")
17802           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17803                                (match_operand:DF 2 "nonimmediate_operand" ""))
17804                            (match_dup 1)
17805                            (match_dup 2)))
17806      (clobber (reg:CC FLAGS_REG))])]
17807   "TARGET_SSE2 && TARGET_SSE_MATH"
17808   "#")
17809
17810 (define_insn "*maxdf"
17811   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17812         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17813                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17814                          (match_dup 1)
17815                          (match_dup 2)))
17816    (clobber (reg:CC FLAGS_REG))]
17817   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17818   "#")
17819
17820 (define_insn "*maxdf_nonieee"
17821   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17822         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17823                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17824                          (match_dup 1)
17825                          (match_dup 2)))
17826    (clobber (reg:CC FLAGS_REG))]
17827   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17828    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17829   "#")
17830
17831 (define_split
17832   [(set (match_operand:DF 0 "register_operand" "")
17833         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17834                              (match_operand:DF 2 "nonimmediate_operand" ""))
17835                          (match_operand:DF 3 "register_operand" "")
17836                          (match_operand:DF 4 "nonimmediate_operand" "")))
17837    (clobber (reg:CC FLAGS_REG))]
17838   "SSE_REG_P (operands[0]) && reload_completed
17839    && ((operands_match_p (operands[1], operands[3])
17840         && operands_match_p (operands[2], operands[4]))
17841        || (operands_match_p (operands[1], operands[4])
17842            && operands_match_p (operands[2], operands[3])))"
17843   [(set (match_dup 0)
17844         (if_then_else:DF (gt (match_dup 1)
17845                              (match_dup 2))
17846                          (match_dup 1)
17847                          (match_dup 2)))])
17848
17849 (define_split
17850   [(set (match_operand:DF 0 "fp_register_operand" "")
17851         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17852                              (match_operand:DF 2 "register_operand" ""))
17853                          (match_operand:DF 3 "register_operand" "")
17854                          (match_operand:DF 4 "register_operand" "")))
17855    (clobber (reg:CC FLAGS_REG))]
17856   "reload_completed
17857    && ((operands_match_p (operands[1], operands[3])
17858         && operands_match_p (operands[2], operands[4]))
17859        || (operands_match_p (operands[1], operands[4])
17860            && operands_match_p (operands[2], operands[3])))"
17861   [(set (reg:CCFP FLAGS_REG)
17862         (compare:CCFP (match_dup 1)
17863                       (match_dup 2)))
17864    (set (match_dup 0)
17865         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17866                          (match_dup 1)
17867                          (match_dup 2)))])
17868
17869 (define_insn "*maxdf_sse"
17870   [(set (match_operand:DF 0 "register_operand" "=Y")
17871         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17872                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17873                          (match_dup 1)
17874                          (match_dup 2)))]
17875   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17876   "maxsd\t{%2, %0|%0, %2}"
17877   [(set_attr "type" "sse")
17878    (set_attr "mode" "DF")])
17879 \f
17880 ;; Misc patterns (?)
17881
17882 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17883 ;; Otherwise there will be nothing to keep
17884 ;; 
17885 ;; [(set (reg ebp) (reg esp))]
17886 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17887 ;;  (clobber (eflags)]
17888 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17889 ;;
17890 ;; in proper program order.
17891 (define_insn "pro_epilogue_adjust_stack_1"
17892   [(set (match_operand:SI 0 "register_operand" "=r,r")
17893         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17894                  (match_operand:SI 2 "immediate_operand" "i,i")))
17895    (clobber (reg:CC FLAGS_REG))
17896    (clobber (mem:BLK (scratch)))]
17897   "!TARGET_64BIT"
17898 {
17899   switch (get_attr_type (insn))
17900     {
17901     case TYPE_IMOV:
17902       return "mov{l}\t{%1, %0|%0, %1}";
17903
17904     case TYPE_ALU:
17905       if (GET_CODE (operands[2]) == CONST_INT
17906           && (INTVAL (operands[2]) == 128
17907               || (INTVAL (operands[2]) < 0
17908                   && INTVAL (operands[2]) != -128)))
17909         {
17910           operands[2] = GEN_INT (-INTVAL (operands[2]));
17911           return "sub{l}\t{%2, %0|%0, %2}";
17912         }
17913       return "add{l}\t{%2, %0|%0, %2}";
17914
17915     case TYPE_LEA:
17916       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17917       return "lea{l}\t{%a2, %0|%0, %a2}";
17918
17919     default:
17920       abort ();
17921     }
17922 }
17923   [(set (attr "type")
17924         (cond [(eq_attr "alternative" "0")
17925                  (const_string "alu")
17926                (match_operand:SI 2 "const0_operand" "")
17927                  (const_string "imov")
17928               ]
17929               (const_string "lea")))
17930    (set_attr "mode" "SI")])
17931
17932 (define_insn "pro_epilogue_adjust_stack_rex64"
17933   [(set (match_operand:DI 0 "register_operand" "=r,r")
17934         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17935                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17936    (clobber (reg:CC FLAGS_REG))
17937    (clobber (mem:BLK (scratch)))]
17938   "TARGET_64BIT"
17939 {
17940   switch (get_attr_type (insn))
17941     {
17942     case TYPE_IMOV:
17943       return "mov{q}\t{%1, %0|%0, %1}";
17944
17945     case TYPE_ALU:
17946       if (GET_CODE (operands[2]) == CONST_INT
17947           /* Avoid overflows.  */
17948           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17949           && (INTVAL (operands[2]) == 128
17950               || (INTVAL (operands[2]) < 0
17951                   && INTVAL (operands[2]) != -128)))
17952         {
17953           operands[2] = GEN_INT (-INTVAL (operands[2]));
17954           return "sub{q}\t{%2, %0|%0, %2}";
17955         }
17956       return "add{q}\t{%2, %0|%0, %2}";
17957
17958     case TYPE_LEA:
17959       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17960       return "lea{q}\t{%a2, %0|%0, %a2}";
17961
17962     default:
17963       abort ();
17964     }
17965 }
17966   [(set (attr "type")
17967         (cond [(eq_attr "alternative" "0")
17968                  (const_string "alu")
17969                (match_operand:DI 2 "const0_operand" "")
17970                  (const_string "imov")
17971               ]
17972               (const_string "lea")))
17973    (set_attr "mode" "DI")])
17974
17975 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17976   [(set (match_operand:DI 0 "register_operand" "=r,r")
17977         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17978                  (match_operand:DI 3 "immediate_operand" "i,i")))
17979    (use (match_operand:DI 2 "register_operand" "r,r"))
17980    (clobber (reg:CC FLAGS_REG))
17981    (clobber (mem:BLK (scratch)))]
17982   "TARGET_64BIT"
17983 {
17984   switch (get_attr_type (insn))
17985     {
17986     case TYPE_ALU:
17987       return "add{q}\t{%2, %0|%0, %2}";
17988
17989     case TYPE_LEA:
17990       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17991       return "lea{q}\t{%a2, %0|%0, %a2}";
17992
17993     default:
17994       abort ();
17995     }
17996 }
17997   [(set_attr "type" "alu,lea")
17998    (set_attr "mode" "DI")])
17999
18000 ;; Placeholder for the conditional moves.  This one is split either to SSE
18001 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18002 ;; fact is that compares supported by the cmp??ss instructions are exactly
18003 ;; swapped of those supported by cmove sequence.
18004 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18005 ;; supported by i387 comparisons and we do need to emit two conditional moves
18006 ;; in tandem.
18007
18008 (define_insn "sse_movsfcc"
18009   [(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")
18010         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18011                         [(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")
18012                          (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")])
18013                       (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")
18014                       (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")))
18015    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18016    (clobber (reg:CC FLAGS_REG))]
18017   "TARGET_SSE
18018    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18019    /* Avoid combine from being smart and converting min/max
18020       instruction patterns into conditional moves.  */
18021    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18022         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18023        || !rtx_equal_p (operands[4], operands[2])
18024        || !rtx_equal_p (operands[5], operands[3]))
18025    && (!TARGET_IEEE_FP
18026        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18027   "#")
18028
18029 (define_insn "sse_movsfcc_eq"
18030   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18031         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18032                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18033                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18034                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18035    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18036    (clobber (reg:CC FLAGS_REG))]
18037   "TARGET_SSE
18038    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18039   "#")
18040
18041 (define_insn "sse_movdfcc"
18042   [(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")
18043         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18044                         [(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")
18045                          (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")])
18046                       (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")
18047                       (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")))
18048    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18049    (clobber (reg:CC FLAGS_REG))]
18050   "TARGET_SSE2
18051    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18052    /* Avoid combine from being smart and converting min/max
18053       instruction patterns into conditional moves.  */
18054    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18055         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18056        || !rtx_equal_p (operands[4], operands[2])
18057        || !rtx_equal_p (operands[5], operands[3]))
18058    && (!TARGET_IEEE_FP
18059        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18060   "#")
18061
18062 (define_insn "sse_movdfcc_eq"
18063   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18064         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18065                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18066                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18067                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18068    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18069    (clobber (reg:CC FLAGS_REG))]
18070   "TARGET_SSE
18071    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18072   "#")
18073
18074 ;; For non-sse moves just expand the usual cmove sequence.
18075 (define_split
18076   [(set (match_operand 0 "register_operand" "")
18077         (if_then_else (match_operator 1 "comparison_operator"
18078                         [(match_operand 4 "nonimmediate_operand" "")
18079                          (match_operand 5 "register_operand" "")])
18080                       (match_operand 2 "nonimmediate_operand" "")
18081                       (match_operand 3 "nonimmediate_operand" "")))
18082    (clobber (match_operand 6 "" ""))
18083    (clobber (reg:CC FLAGS_REG))]
18084   "!SSE_REG_P (operands[0]) && reload_completed
18085    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18086   [(const_int 0)]
18087 {
18088    ix86_compare_op0 = operands[5];
18089    ix86_compare_op1 = operands[4];
18090    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18091                                  VOIDmode, operands[5], operands[4]);
18092    ix86_expand_fp_movcc (operands);
18093    DONE;
18094 })
18095
18096 ;; Split SSE based conditional move into sequence:
18097 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18098 ;; and   op2, op0   -  zero op2 if comparison was false
18099 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18100 ;; or    op2, op0   -  get the nonzero one into the result.
18101 (define_split
18102   [(set (match_operand:SF 0 "register_operand" "")
18103         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18104                         [(match_operand:SF 4 "register_operand" "")
18105                          (match_operand:SF 5 "nonimmediate_operand" "")])
18106                       (match_operand:SF 2 "register_operand" "")
18107                       (match_operand:SF 3 "register_operand" "")))
18108    (clobber (match_operand 6 "" ""))
18109    (clobber (reg:CC FLAGS_REG))]
18110   "SSE_REG_P (operands[0]) && reload_completed"
18111   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18112    (set (match_dup 2) (and:V4SF (match_dup 2)
18113                                 (match_dup 8)))
18114    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18115                                           (match_dup 3)))
18116    (set (match_dup 0) (ior:V4SF (match_dup 6)
18117                                 (match_dup 7)))]
18118 {
18119   /* If op2 == op3, op3 would be clobbered before it is used.  */
18120   if (operands_match_p (operands[2], operands[3]))
18121     {
18122       emit_move_insn (operands[0], operands[2]);
18123       DONE;
18124     }
18125
18126   PUT_MODE (operands[1], GET_MODE (operands[0]));
18127   if (operands_match_p (operands[0], operands[4]))
18128     operands[6] = operands[4], operands[7] = operands[2];
18129   else
18130     operands[6] = operands[2], operands[7] = operands[4];
18131   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18132   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18133   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18134   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18135   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18136   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18137 })
18138
18139 (define_split
18140   [(set (match_operand:DF 0 "register_operand" "")
18141         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18142                         [(match_operand:DF 4 "register_operand" "")
18143                          (match_operand:DF 5 "nonimmediate_operand" "")])
18144                       (match_operand:DF 2 "register_operand" "")
18145                       (match_operand:DF 3 "register_operand" "")))
18146    (clobber (match_operand 6 "" ""))
18147    (clobber (reg:CC FLAGS_REG))]
18148   "SSE_REG_P (operands[0]) && reload_completed"
18149   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18150    (set (match_dup 2) (and:V2DF (match_dup 2)
18151                                 (match_dup 8)))
18152    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18153                                           (match_dup 3)))
18154    (set (match_dup 0) (ior:V2DF (match_dup 6)
18155                                 (match_dup 7)))]
18156 {
18157   if (GET_MODE (operands[2]) == DFmode
18158       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18159     {
18160       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18161       emit_insn (gen_sse2_unpcklpd (op, op, op));
18162       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18163       emit_insn (gen_sse2_unpcklpd (op, op, op));
18164     }
18165
18166   /* If op2 == op3, op3 would be clobbered before it is used.  */
18167   if (operands_match_p (operands[2], operands[3]))
18168     {
18169       emit_move_insn (operands[0], operands[2]);
18170       DONE;
18171     }
18172
18173   PUT_MODE (operands[1], GET_MODE (operands[0]));
18174   if (operands_match_p (operands[0], operands[4]))
18175     operands[6] = operands[4], operands[7] = operands[2];
18176   else
18177     operands[6] = operands[2], operands[7] = operands[4];
18178   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18179   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18180   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18181   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18182   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18183   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18184 })
18185
18186 ;; Special case of conditional move we can handle effectively.
18187 ;; Do not brother with the integer/floating point case, since these are
18188 ;; bot considerably slower, unlike in the generic case.
18189 (define_insn "*sse_movsfcc_const0_1"
18190   [(set (match_operand:SF 0 "register_operand" "=&x")
18191         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18192                         [(match_operand:SF 4 "register_operand" "0")
18193                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18194                       (match_operand:SF 2 "register_operand" "x")
18195                       (match_operand:SF 3 "const0_operand" "X")))]
18196   "TARGET_SSE"
18197   "#")
18198
18199 (define_insn "*sse_movsfcc_const0_2"
18200   [(set (match_operand:SF 0 "register_operand" "=&x")
18201         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18202                         [(match_operand:SF 4 "register_operand" "0")
18203                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18204                       (match_operand:SF 2 "const0_operand" "X")
18205                       (match_operand:SF 3 "register_operand" "x")))]
18206   "TARGET_SSE"
18207   "#")
18208
18209 (define_insn "*sse_movsfcc_const0_3"
18210   [(set (match_operand:SF 0 "register_operand" "=&x")
18211         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18212                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18213                          (match_operand:SF 5 "register_operand" "0")])
18214                       (match_operand:SF 2 "register_operand" "x")
18215                       (match_operand:SF 3 "const0_operand" "X")))]
18216   "TARGET_SSE"
18217   "#")
18218
18219 (define_insn "*sse_movsfcc_const0_4"
18220   [(set (match_operand:SF 0 "register_operand" "=&x")
18221         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18222                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18223                          (match_operand:SF 5 "register_operand" "0")])
18224                       (match_operand:SF 2 "const0_operand" "X")
18225                       (match_operand:SF 3 "register_operand" "x")))]
18226   "TARGET_SSE"
18227   "#")
18228
18229 (define_insn "*sse_movdfcc_const0_1"
18230   [(set (match_operand:DF 0 "register_operand" "=&Y")
18231         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18232                         [(match_operand:DF 4 "register_operand" "0")
18233                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18234                       (match_operand:DF 2 "register_operand" "Y")
18235                       (match_operand:DF 3 "const0_operand" "X")))]
18236   "TARGET_SSE2"
18237   "#")
18238
18239 (define_insn "*sse_movdfcc_const0_2"
18240   [(set (match_operand:DF 0 "register_operand" "=&Y")
18241         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18242                         [(match_operand:DF 4 "register_operand" "0")
18243                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18244                       (match_operand:DF 2 "const0_operand" "X")
18245                       (match_operand:DF 3 "register_operand" "Y")))]
18246   "TARGET_SSE2"
18247   "#")
18248
18249 (define_insn "*sse_movdfcc_const0_3"
18250   [(set (match_operand:DF 0 "register_operand" "=&Y")
18251         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18252                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18253                          (match_operand:DF 5 "register_operand" "0")])
18254                       (match_operand:DF 2 "register_operand" "Y")
18255                       (match_operand:DF 3 "const0_operand" "X")))]
18256   "TARGET_SSE2"
18257   "#")
18258
18259 (define_insn "*sse_movdfcc_const0_4"
18260   [(set (match_operand:DF 0 "register_operand" "=&Y")
18261         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18262                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18263                          (match_operand:DF 5 "register_operand" "0")])
18264                       (match_operand:DF 2 "const0_operand" "X")
18265                       (match_operand:DF 3 "register_operand" "Y")))]
18266   "TARGET_SSE2"
18267   "#")
18268
18269 (define_split
18270   [(set (match_operand:SF 0 "register_operand" "")
18271         (if_then_else (match_operator 1 "comparison_operator"
18272                         [(match_operand:SF 4 "nonimmediate_operand" "")
18273                          (match_operand:SF 5 "nonimmediate_operand" "")])
18274                       (match_operand:SF 2 "nonmemory_operand" "")
18275                       (match_operand:SF 3 "nonmemory_operand" "")))]
18276   "SSE_REG_P (operands[0]) && reload_completed
18277    && (const0_operand (operands[2], GET_MODE (operands[0]))
18278        || const0_operand (operands[3], GET_MODE (operands[0])))"
18279   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18280    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18281 {
18282   PUT_MODE (operands[1], GET_MODE (operands[0]));
18283   if (!sse_comparison_operator (operands[1], VOIDmode)
18284       || !rtx_equal_p (operands[0], operands[4]))
18285     {
18286       rtx tmp = operands[5];
18287       operands[5] = operands[4];
18288       operands[4] = tmp;
18289       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18290     }
18291   if (!rtx_equal_p (operands[0], operands[4]))
18292     abort ();
18293   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18294   if (const0_operand (operands[2], GET_MODE (operands[2])))
18295     {
18296       operands[7] = operands[3];
18297       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18298     }
18299   else
18300     {
18301       operands[7] = operands[2];
18302       operands[6] = operands[8];
18303     }
18304   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18305 })
18306
18307 (define_split
18308   [(set (match_operand:DF 0 "register_operand" "")
18309         (if_then_else (match_operator 1 "comparison_operator"
18310                         [(match_operand:DF 4 "nonimmediate_operand" "")
18311                          (match_operand:DF 5 "nonimmediate_operand" "")])
18312                       (match_operand:DF 2 "nonmemory_operand" "")
18313                       (match_operand:DF 3 "nonmemory_operand" "")))]
18314   "SSE_REG_P (operands[0]) && reload_completed
18315    && (const0_operand (operands[2], GET_MODE (operands[0]))
18316        || const0_operand (operands[3], GET_MODE (operands[0])))"
18317   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18318    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18319 {
18320   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18321       && GET_MODE (operands[2]) == DFmode)
18322     {
18323       if (REG_P (operands[2]))
18324         {
18325           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18326           emit_insn (gen_sse2_unpcklpd (op, op, op));
18327         }
18328       if (REG_P (operands[3]))
18329         {
18330           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18331           emit_insn (gen_sse2_unpcklpd (op, op, op));
18332         }
18333     }
18334   PUT_MODE (operands[1], GET_MODE (operands[0]));
18335   if (!sse_comparison_operator (operands[1], VOIDmode)
18336       || !rtx_equal_p (operands[0], operands[4]))
18337     {
18338       rtx tmp = operands[5];
18339       operands[5] = operands[4];
18340       operands[4] = tmp;
18341       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18342     }
18343   if (!rtx_equal_p (operands[0], operands[4]))
18344     abort ();
18345   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18346   if (const0_operand (operands[2], GET_MODE (operands[2])))
18347     {
18348       operands[7] = operands[3];
18349       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18350     }
18351   else
18352     {
18353       operands[7] = operands[2];
18354       operands[6] = operands[8];
18355     }
18356   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18357 })
18358
18359 (define_expand "allocate_stack_worker"
18360   [(match_operand:SI 0 "register_operand" "")]
18361   "TARGET_STACK_PROBE"
18362 {
18363   if (reload_completed)
18364     {
18365       if (TARGET_64BIT)
18366         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18367       else
18368         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18369     }
18370   else
18371     {
18372       if (TARGET_64BIT)
18373         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18374       else
18375         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18376     }
18377   DONE;
18378 })
18379
18380 (define_insn "allocate_stack_worker_1"
18381   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18382     UNSPECV_STACK_PROBE)
18383    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18384    (clobber (match_scratch:SI 1 "=0"))
18385    (clobber (reg:CC FLAGS_REG))]
18386   "!TARGET_64BIT && TARGET_STACK_PROBE"
18387   "call\t__alloca"
18388   [(set_attr "type" "multi")
18389    (set_attr "length" "5")])
18390
18391 (define_expand "allocate_stack_worker_postreload"
18392   [(parallel [(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_dup 0))
18396               (clobber (reg:CC FLAGS_REG))])]
18397   ""
18398   "")
18399
18400 (define_insn "allocate_stack_worker_rex64"
18401   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18402     UNSPECV_STACK_PROBE)
18403    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18404    (clobber (match_scratch:DI 1 "=0"))
18405    (clobber (reg:CC FLAGS_REG))]
18406   "TARGET_64BIT && TARGET_STACK_PROBE"
18407   "call\t__alloca"
18408   [(set_attr "type" "multi")
18409    (set_attr "length" "5")])
18410
18411 (define_expand "allocate_stack_worker_rex64_postreload"
18412   [(parallel [(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_dup 0))
18416               (clobber (reg:CC FLAGS_REG))])]
18417   ""
18418   "")
18419
18420 (define_expand "allocate_stack"
18421   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18422                    (minus:SI (reg:SI SP_REG)
18423                              (match_operand:SI 1 "general_operand" "")))
18424               (clobber (reg:CC FLAGS_REG))])
18425    (parallel [(set (reg:SI SP_REG)
18426                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18427               (clobber (reg:CC FLAGS_REG))])]
18428   "TARGET_STACK_PROBE"
18429 {
18430 #ifdef CHECK_STACK_LIMIT
18431   if (GET_CODE (operands[1]) == CONST_INT
18432       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18433     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18434                            operands[1]));
18435   else 
18436 #endif
18437     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18438                                                             operands[1])));
18439
18440   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18441   DONE;
18442 })
18443
18444 (define_expand "builtin_setjmp_receiver"
18445   [(label_ref (match_operand 0 "" ""))]
18446   "!TARGET_64BIT && flag_pic"
18447 {
18448   emit_insn (gen_set_got (pic_offset_table_rtx));
18449   DONE;
18450 })
18451 \f
18452 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18453
18454 (define_split
18455   [(set (match_operand 0 "register_operand" "")
18456         (match_operator 3 "promotable_binary_operator"
18457            [(match_operand 1 "register_operand" "")
18458             (match_operand 2 "aligned_operand" "")]))
18459    (clobber (reg:CC FLAGS_REG))]
18460   "! TARGET_PARTIAL_REG_STALL && reload_completed
18461    && ((GET_MODE (operands[0]) == HImode 
18462         && ((!optimize_size && !TARGET_FAST_PREFIX)
18463             || GET_CODE (operands[2]) != CONST_INT
18464             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18465        || (GET_MODE (operands[0]) == QImode 
18466            && (TARGET_PROMOTE_QImode || optimize_size)))"
18467   [(parallel [(set (match_dup 0)
18468                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18469               (clobber (reg:CC FLAGS_REG))])]
18470   "operands[0] = gen_lowpart (SImode, operands[0]);
18471    operands[1] = gen_lowpart (SImode, operands[1]);
18472    if (GET_CODE (operands[3]) != ASHIFT)
18473      operands[2] = gen_lowpart (SImode, operands[2]);
18474    PUT_MODE (operands[3], SImode);")
18475
18476 ; Promote the QImode tests, as i386 has encoding of the AND
18477 ; instruction with 32-bit sign-extended immediate and thus the
18478 ; instruction size is unchanged, except in the %eax case for
18479 ; which it is increased by one byte, hence the ! optimize_size.
18480 (define_split
18481   [(set (reg 17)
18482         (compare (and (match_operand 1 "aligned_operand" "")
18483                       (match_operand 2 "const_int_operand" ""))
18484                  (const_int 0)))
18485    (set (match_operand 0 "register_operand" "")
18486         (and (match_dup 1) (match_dup 2)))]
18487   "! TARGET_PARTIAL_REG_STALL && reload_completed
18488    /* Ensure that the operand will remain sign-extended immediate.  */
18489    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18490    && ! optimize_size
18491    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18492        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18493   [(parallel [(set (reg:CCNO FLAGS_REG)
18494                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18495                                  (const_int 0)))
18496               (set (match_dup 0)
18497                    (and:SI (match_dup 1) (match_dup 2)))])]
18498   "operands[2]
18499      = gen_int_mode (INTVAL (operands[2])
18500                      & GET_MODE_MASK (GET_MODE (operands[0])),
18501                      SImode);
18502    operands[0] = gen_lowpart (SImode, operands[0]);
18503    operands[1] = gen_lowpart (SImode, operands[1]);")
18504
18505 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18506 ; the TEST instruction with 32-bit sign-extended immediate and thus
18507 ; the instruction size would at least double, which is not what we
18508 ; want even with ! optimize_size.
18509 (define_split
18510   [(set (reg 17)
18511         (compare (and (match_operand:HI 0 "aligned_operand" "")
18512                       (match_operand:HI 1 "const_int_operand" ""))
18513                  (const_int 0)))]
18514   "! TARGET_PARTIAL_REG_STALL && reload_completed
18515    /* Ensure that the operand will remain sign-extended immediate.  */
18516    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18517    && ! TARGET_FAST_PREFIX
18518    && ! optimize_size"
18519   [(set (reg:CCNO FLAGS_REG)
18520         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18521                       (const_int 0)))]
18522   "operands[1]
18523      = gen_int_mode (INTVAL (operands[1])
18524                      & GET_MODE_MASK (GET_MODE (operands[0])),
18525                      SImode);
18526    operands[0] = gen_lowpart (SImode, operands[0]);")
18527
18528 (define_split
18529   [(set (match_operand 0 "register_operand" "")
18530         (neg (match_operand 1 "register_operand" "")))
18531    (clobber (reg:CC FLAGS_REG))]
18532   "! TARGET_PARTIAL_REG_STALL && reload_completed
18533    && (GET_MODE (operands[0]) == HImode
18534        || (GET_MODE (operands[0]) == QImode 
18535            && (TARGET_PROMOTE_QImode || optimize_size)))"
18536   [(parallel [(set (match_dup 0)
18537                    (neg:SI (match_dup 1)))
18538               (clobber (reg:CC FLAGS_REG))])]
18539   "operands[0] = gen_lowpart (SImode, operands[0]);
18540    operands[1] = gen_lowpart (SImode, operands[1]);")
18541
18542 (define_split
18543   [(set (match_operand 0 "register_operand" "")
18544         (not (match_operand 1 "register_operand" "")))]
18545   "! TARGET_PARTIAL_REG_STALL && reload_completed
18546    && (GET_MODE (operands[0]) == HImode
18547        || (GET_MODE (operands[0]) == QImode 
18548            && (TARGET_PROMOTE_QImode || optimize_size)))"
18549   [(set (match_dup 0)
18550         (not:SI (match_dup 1)))]
18551   "operands[0] = gen_lowpart (SImode, operands[0]);
18552    operands[1] = gen_lowpart (SImode, operands[1]);")
18553
18554 (define_split 
18555   [(set (match_operand 0 "register_operand" "")
18556         (if_then_else (match_operator 1 "comparison_operator" 
18557                                 [(reg 17) (const_int 0)])
18558                       (match_operand 2 "register_operand" "")
18559                       (match_operand 3 "register_operand" "")))]
18560   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18561    && (GET_MODE (operands[0]) == HImode
18562        || (GET_MODE (operands[0]) == QImode 
18563            && (TARGET_PROMOTE_QImode || optimize_size)))"
18564   [(set (match_dup 0)
18565         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18566   "operands[0] = gen_lowpart (SImode, operands[0]);
18567    operands[2] = gen_lowpart (SImode, operands[2]);
18568    operands[3] = gen_lowpart (SImode, operands[3]);")
18569                         
18570 \f
18571 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18572 ;; transform a complex memory operation into two memory to register operations.
18573
18574 ;; Don't push memory operands
18575 (define_peephole2
18576   [(set (match_operand:SI 0 "push_operand" "")
18577         (match_operand:SI 1 "memory_operand" ""))
18578    (match_scratch:SI 2 "r")]
18579   "! optimize_size && ! TARGET_PUSH_MEMORY"
18580   [(set (match_dup 2) (match_dup 1))
18581    (set (match_dup 0) (match_dup 2))]
18582   "")
18583
18584 (define_peephole2
18585   [(set (match_operand:DI 0 "push_operand" "")
18586         (match_operand:DI 1 "memory_operand" ""))
18587    (match_scratch:DI 2 "r")]
18588   "! optimize_size && ! TARGET_PUSH_MEMORY"
18589   [(set (match_dup 2) (match_dup 1))
18590    (set (match_dup 0) (match_dup 2))]
18591   "")
18592
18593 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18594 ;; SImode pushes.
18595 (define_peephole2
18596   [(set (match_operand:SF 0 "push_operand" "")
18597         (match_operand:SF 1 "memory_operand" ""))
18598    (match_scratch:SF 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 (define_peephole2
18605   [(set (match_operand:HI 0 "push_operand" "")
18606         (match_operand:HI 1 "memory_operand" ""))
18607    (match_scratch:HI 2 "r")]
18608   "! optimize_size && ! TARGET_PUSH_MEMORY"
18609   [(set (match_dup 2) (match_dup 1))
18610    (set (match_dup 0) (match_dup 2))]
18611   "")
18612
18613 (define_peephole2
18614   [(set (match_operand:QI 0 "push_operand" "")
18615         (match_operand:QI 1 "memory_operand" ""))
18616    (match_scratch:QI 2 "q")]
18617   "! optimize_size && ! TARGET_PUSH_MEMORY"
18618   [(set (match_dup 2) (match_dup 1))
18619    (set (match_dup 0) (match_dup 2))]
18620   "")
18621
18622 ;; Don't move an immediate directly to memory when the instruction
18623 ;; gets too big.
18624 (define_peephole2
18625   [(match_scratch:SI 1 "r")
18626    (set (match_operand:SI 0 "memory_operand" "")
18627         (const_int 0))]
18628   "! optimize_size
18629    && ! TARGET_USE_MOV0
18630    && TARGET_SPLIT_LONG_MOVES
18631    && get_attr_length (insn) >= ix86_cost->large_insn
18632    && peep2_regno_dead_p (0, FLAGS_REG)"
18633   [(parallel [(set (match_dup 1) (const_int 0))
18634               (clobber (reg:CC FLAGS_REG))])
18635    (set (match_dup 0) (match_dup 1))]
18636   "")
18637
18638 (define_peephole2
18639   [(match_scratch:HI 1 "r")
18640    (set (match_operand:HI 0 "memory_operand" "")
18641         (const_int 0))]
18642   "! optimize_size
18643    && ! TARGET_USE_MOV0
18644    && TARGET_SPLIT_LONG_MOVES
18645    && get_attr_length (insn) >= ix86_cost->large_insn
18646    && peep2_regno_dead_p (0, FLAGS_REG)"
18647   [(parallel [(set (match_dup 2) (const_int 0))
18648               (clobber (reg:CC FLAGS_REG))])
18649    (set (match_dup 0) (match_dup 1))]
18650   "operands[2] = gen_lowpart (SImode, operands[1]);")
18651
18652 (define_peephole2
18653   [(match_scratch:QI 1 "q")
18654    (set (match_operand:QI 0 "memory_operand" "")
18655         (const_int 0))]
18656   "! optimize_size
18657    && ! TARGET_USE_MOV0
18658    && TARGET_SPLIT_LONG_MOVES
18659    && get_attr_length (insn) >= ix86_cost->large_insn
18660    && peep2_regno_dead_p (0, FLAGS_REG)"
18661   [(parallel [(set (match_dup 2) (const_int 0))
18662               (clobber (reg:CC FLAGS_REG))])
18663    (set (match_dup 0) (match_dup 1))]
18664   "operands[2] = gen_lowpart (SImode, operands[1]);")
18665
18666 (define_peephole2
18667   [(match_scratch:SI 2 "r")
18668    (set (match_operand:SI 0 "memory_operand" "")
18669         (match_operand:SI 1 "immediate_operand" ""))]
18670   "! optimize_size
18671    && get_attr_length (insn) >= ix86_cost->large_insn
18672    && TARGET_SPLIT_LONG_MOVES"
18673   [(set (match_dup 2) (match_dup 1))
18674    (set (match_dup 0) (match_dup 2))]
18675   "")
18676
18677 (define_peephole2
18678   [(match_scratch:HI 2 "r")
18679    (set (match_operand:HI 0 "memory_operand" "")
18680         (match_operand:HI 1 "immediate_operand" ""))]
18681   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18682   && TARGET_SPLIT_LONG_MOVES"
18683   [(set (match_dup 2) (match_dup 1))
18684    (set (match_dup 0) (match_dup 2))]
18685   "")
18686
18687 (define_peephole2
18688   [(match_scratch:QI 2 "q")
18689    (set (match_operand:QI 0 "memory_operand" "")
18690         (match_operand:QI 1 "immediate_operand" ""))]
18691   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18692   && TARGET_SPLIT_LONG_MOVES"
18693   [(set (match_dup 2) (match_dup 1))
18694    (set (match_dup 0) (match_dup 2))]
18695   "")
18696
18697 ;; Don't compare memory with zero, load and use a test instead.
18698 (define_peephole2
18699   [(set (reg 17)
18700         (compare (match_operand:SI 0 "memory_operand" "")
18701                  (const_int 0)))
18702    (match_scratch:SI 3 "r")]
18703   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18704   [(set (match_dup 3) (match_dup 0))
18705    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
18706   "")
18707
18708 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18709 ;; Don't split NOTs with a displacement operand, because resulting XOR
18710 ;; will not be pairable anyway.
18711 ;;
18712 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18713 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18714 ;; so this split helps here as well.
18715 ;;
18716 ;; Note: Can't do this as a regular split because we can't get proper
18717 ;; lifetime information then.
18718
18719 (define_peephole2
18720   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18721         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18722   "!optimize_size
18723    && peep2_regno_dead_p (0, FLAGS_REG)
18724    && ((TARGET_PENTIUM 
18725         && (GET_CODE (operands[0]) != MEM
18726             || !memory_displacement_operand (operands[0], SImode)))
18727        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18728   [(parallel [(set (match_dup 0)
18729                    (xor:SI (match_dup 1) (const_int -1)))
18730               (clobber (reg:CC FLAGS_REG))])]
18731   "")
18732
18733 (define_peephole2
18734   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18735         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18736   "!optimize_size
18737    && peep2_regno_dead_p (0, FLAGS_REG)
18738    && ((TARGET_PENTIUM 
18739         && (GET_CODE (operands[0]) != MEM
18740             || !memory_displacement_operand (operands[0], HImode)))
18741        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18742   [(parallel [(set (match_dup 0)
18743                    (xor:HI (match_dup 1) (const_int -1)))
18744               (clobber (reg:CC FLAGS_REG))])]
18745   "")
18746
18747 (define_peephole2
18748   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18749         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18750   "!optimize_size
18751    && peep2_regno_dead_p (0, FLAGS_REG)
18752    && ((TARGET_PENTIUM 
18753         && (GET_CODE (operands[0]) != MEM
18754             || !memory_displacement_operand (operands[0], QImode)))
18755        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18756   [(parallel [(set (match_dup 0)
18757                    (xor:QI (match_dup 1) (const_int -1)))
18758               (clobber (reg:CC FLAGS_REG))])]
18759   "")
18760
18761 ;; Non pairable "test imm, reg" instructions can be translated to
18762 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18763 ;; byte opcode instead of two, have a short form for byte operands),
18764 ;; so do it for other CPUs as well.  Given that the value was dead,
18765 ;; this should not create any new dependencies.  Pass on the sub-word
18766 ;; versions if we're concerned about partial register stalls.
18767
18768 (define_peephole2
18769   [(set (reg 17)
18770         (compare (and:SI (match_operand:SI 0 "register_operand" "")
18771                          (match_operand:SI 1 "immediate_operand" ""))
18772                  (const_int 0)))]
18773   "ix86_match_ccmode (insn, CCNOmode)
18774    && (true_regnum (operands[0]) != 0
18775        || (GET_CODE (operands[1]) == CONST_INT
18776            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18777    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18778   [(parallel
18779      [(set (reg:CCNO FLAGS_REG)
18780            (compare:CCNO (and:SI (match_dup 0)
18781                                  (match_dup 1))
18782                          (const_int 0)))
18783       (set (match_dup 0)
18784            (and:SI (match_dup 0) (match_dup 1)))])]
18785   "")
18786
18787 ;; We don't need to handle HImode case, because it will be promoted to SImode
18788 ;; on ! TARGET_PARTIAL_REG_STALL
18789
18790 (define_peephole2
18791   [(set (reg 17)
18792         (compare (and:QI (match_operand:QI 0 "register_operand" "")
18793                          (match_operand:QI 1 "immediate_operand" ""))
18794                  (const_int 0)))]
18795   "! TARGET_PARTIAL_REG_STALL
18796    && ix86_match_ccmode (insn, CCNOmode)
18797    && true_regnum (operands[0]) != 0
18798    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18799   [(parallel
18800      [(set (reg:CCNO FLAGS_REG)
18801            (compare:CCNO (and:QI (match_dup 0)
18802                                  (match_dup 1))
18803                          (const_int 0)))
18804       (set (match_dup 0)
18805            (and:QI (match_dup 0) (match_dup 1)))])]
18806   "")
18807
18808 (define_peephole2
18809   [(set (reg 17)
18810         (compare
18811           (and:SI
18812             (zero_extract:SI
18813               (match_operand 0 "ext_register_operand" "")
18814               (const_int 8)
18815               (const_int 8))
18816             (match_operand 1 "const_int_operand" ""))
18817           (const_int 0)))]
18818   "! TARGET_PARTIAL_REG_STALL
18819    && ix86_match_ccmode (insn, CCNOmode)
18820    && true_regnum (operands[0]) != 0
18821    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18822   [(parallel [(set (reg:CCNO FLAGS_REG)
18823                    (compare:CCNO
18824                        (and:SI
18825                          (zero_extract:SI
18826                          (match_dup 0)
18827                          (const_int 8)
18828                          (const_int 8))
18829                         (match_dup 1))
18830                    (const_int 0)))
18831               (set (zero_extract:SI (match_dup 0)
18832                                     (const_int 8)
18833                                     (const_int 8))
18834                    (and:SI 
18835                      (zero_extract:SI
18836                        (match_dup 0)
18837                        (const_int 8)
18838                        (const_int 8))
18839                      (match_dup 1)))])]
18840   "")
18841
18842 ;; Don't do logical operations with memory inputs.
18843 (define_peephole2
18844   [(match_scratch:SI 2 "r")
18845    (parallel [(set (match_operand:SI 0 "register_operand" "")
18846                    (match_operator:SI 3 "arith_or_logical_operator"
18847                      [(match_dup 0)
18848                       (match_operand:SI 1 "memory_operand" "")]))
18849               (clobber (reg:CC FLAGS_REG))])]
18850   "! optimize_size && ! TARGET_READ_MODIFY"
18851   [(set (match_dup 2) (match_dup 1))
18852    (parallel [(set (match_dup 0)
18853                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18854               (clobber (reg:CC FLAGS_REG))])]
18855   "")
18856
18857 (define_peephole2
18858   [(match_scratch:SI 2 "r")
18859    (parallel [(set (match_operand:SI 0 "register_operand" "")
18860                    (match_operator:SI 3 "arith_or_logical_operator"
18861                      [(match_operand:SI 1 "memory_operand" "")
18862                       (match_dup 0)]))
18863               (clobber (reg:CC FLAGS_REG))])]
18864   "! optimize_size && ! TARGET_READ_MODIFY"
18865   [(set (match_dup 2) (match_dup 1))
18866    (parallel [(set (match_dup 0)
18867                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18868               (clobber (reg:CC FLAGS_REG))])]
18869   "")
18870
18871 ; Don't do logical operations with memory outputs
18872 ;
18873 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18874 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18875 ; the same decoder scheduling characteristics as the original.
18876
18877 (define_peephole2
18878   [(match_scratch:SI 2 "r")
18879    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18880                    (match_operator:SI 3 "arith_or_logical_operator"
18881                      [(match_dup 0)
18882                       (match_operand:SI 1 "nonmemory_operand" "")]))
18883               (clobber (reg:CC FLAGS_REG))])]
18884   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18885   [(set (match_dup 2) (match_dup 0))
18886    (parallel [(set (match_dup 2)
18887                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18888               (clobber (reg:CC FLAGS_REG))])
18889    (set (match_dup 0) (match_dup 2))]
18890   "")
18891
18892 (define_peephole2
18893   [(match_scratch:SI 2 "r")
18894    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18895                    (match_operator:SI 3 "arith_or_logical_operator"
18896                      [(match_operand:SI 1 "nonmemory_operand" "")
18897                       (match_dup 0)]))
18898               (clobber (reg:CC FLAGS_REG))])]
18899   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18900   [(set (match_dup 2) (match_dup 0))
18901    (parallel [(set (match_dup 2)
18902                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18903               (clobber (reg:CC FLAGS_REG))])
18904    (set (match_dup 0) (match_dup 2))]
18905   "")
18906
18907 ;; Attempt to always use XOR for zeroing registers.
18908 (define_peephole2
18909   [(set (match_operand 0 "register_operand" "")
18910         (const_int 0))]
18911   "(GET_MODE (operands[0]) == QImode
18912     || GET_MODE (operands[0]) == HImode
18913     || GET_MODE (operands[0]) == SImode
18914     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18915    && (! TARGET_USE_MOV0 || optimize_size)
18916    && peep2_regno_dead_p (0, FLAGS_REG)"
18917   [(parallel [(set (match_dup 0) (const_int 0))
18918               (clobber (reg:CC FLAGS_REG))])]
18919   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18920                               operands[0]);")
18921
18922 (define_peephole2
18923   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18924         (const_int 0))]
18925   "(GET_MODE (operands[0]) == QImode
18926     || GET_MODE (operands[0]) == HImode)
18927    && (! TARGET_USE_MOV0 || optimize_size)
18928    && peep2_regno_dead_p (0, FLAGS_REG)"
18929   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18930               (clobber (reg:CC FLAGS_REG))])])
18931
18932 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18933 (define_peephole2
18934   [(set (match_operand 0 "register_operand" "")
18935         (const_int -1))]
18936   "(GET_MODE (operands[0]) == HImode
18937     || GET_MODE (operands[0]) == SImode 
18938     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18939    && (optimize_size || TARGET_PENTIUM)
18940    && peep2_regno_dead_p (0, FLAGS_REG)"
18941   [(parallel [(set (match_dup 0) (const_int -1))
18942               (clobber (reg:CC FLAGS_REG))])]
18943   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18944                               operands[0]);")
18945
18946 ;; Attempt to convert simple leas to adds. These can be created by
18947 ;; move expanders.
18948 (define_peephole2
18949   [(set (match_operand:SI 0 "register_operand" "")
18950         (plus:SI (match_dup 0)
18951                  (match_operand:SI 1 "nonmemory_operand" "")))]
18952   "peep2_regno_dead_p (0, FLAGS_REG)"
18953   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18954               (clobber (reg:CC FLAGS_REG))])]
18955   "")
18956
18957 (define_peephole2
18958   [(set (match_operand:SI 0 "register_operand" "")
18959         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18960                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18961   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18962   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18963               (clobber (reg:CC FLAGS_REG))])]
18964   "operands[2] = gen_lowpart (SImode, operands[2]);")
18965
18966 (define_peephole2
18967   [(set (match_operand:DI 0 "register_operand" "")
18968         (plus:DI (match_dup 0)
18969                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18970   "peep2_regno_dead_p (0, FLAGS_REG)"
18971   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18972               (clobber (reg:CC FLAGS_REG))])]
18973   "")
18974
18975 (define_peephole2
18976   [(set (match_operand:SI 0 "register_operand" "")
18977         (mult:SI (match_dup 0)
18978                  (match_operand:SI 1 "const_int_operand" "")))]
18979   "exact_log2 (INTVAL (operands[1])) >= 0
18980    && peep2_regno_dead_p (0, FLAGS_REG)"
18981   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18982               (clobber (reg:CC FLAGS_REG))])]
18983   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18984
18985 (define_peephole2
18986   [(set (match_operand:DI 0 "register_operand" "")
18987         (mult:DI (match_dup 0)
18988                  (match_operand:DI 1 "const_int_operand" "")))]
18989   "exact_log2 (INTVAL (operands[1])) >= 0
18990    && peep2_regno_dead_p (0, FLAGS_REG)"
18991   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18992               (clobber (reg:CC FLAGS_REG))])]
18993   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18994
18995 (define_peephole2
18996   [(set (match_operand:SI 0 "register_operand" "")
18997         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18998                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18999   "exact_log2 (INTVAL (operands[2])) >= 0
19000    && REGNO (operands[0]) == REGNO (operands[1])
19001    && peep2_regno_dead_p (0, FLAGS_REG)"
19002   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19003               (clobber (reg:CC FLAGS_REG))])]
19004   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19005
19006 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19007 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19008 ;; many CPUs it is also faster, since special hardware to avoid esp
19009 ;; dependencies is present.
19010
19011 ;; While some of these conversions may be done using splitters, we use peepholes
19012 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19013
19014 ;; Convert prologue esp subtractions to push.
19015 ;; We need register to push.  In order to keep verify_flow_info happy we have
19016 ;; two choices
19017 ;; - use scratch and clobber it in order to avoid dependencies
19018 ;; - use already live register
19019 ;; We can't use the second way right now, since there is no reliable way how to
19020 ;; verify that given register is live.  First choice will also most likely in
19021 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19022 ;; call clobbered registers are dead.  We may want to use base pointer as an
19023 ;; alternative when no register is available later.
19024
19025 (define_peephole2
19026   [(match_scratch:SI 0 "r")
19027    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19028               (clobber (reg:CC FLAGS_REG))
19029               (clobber (mem:BLK (scratch)))])]
19030   "optimize_size || !TARGET_SUB_ESP_4"
19031   [(clobber (match_dup 0))
19032    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19033               (clobber (mem:BLK (scratch)))])])
19034
19035 (define_peephole2
19036   [(match_scratch:SI 0 "r")
19037    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19038               (clobber (reg:CC FLAGS_REG))
19039               (clobber (mem:BLK (scratch)))])]
19040   "optimize_size || !TARGET_SUB_ESP_8"
19041   [(clobber (match_dup 0))
19042    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (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 ;; Convert esp subtractions to push.
19047 (define_peephole2
19048   [(match_scratch:SI 0 "r")
19049    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19050               (clobber (reg:CC FLAGS_REG))])]
19051   "optimize_size || !TARGET_SUB_ESP_4"
19052   [(clobber (match_dup 0))
19053    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19054
19055 (define_peephole2
19056   [(match_scratch:SI 0 "r")
19057    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19058               (clobber (reg:CC FLAGS_REG))])]
19059   "optimize_size || !TARGET_SUB_ESP_8"
19060   [(clobber (match_dup 0))
19061    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19062    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19063
19064 ;; Convert epilogue deallocator to pop.
19065 (define_peephole2
19066   [(match_scratch:SI 0 "r")
19067    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19068               (clobber (reg:CC FLAGS_REG))
19069               (clobber (mem:BLK (scratch)))])]
19070   "optimize_size || !TARGET_ADD_ESP_4"
19071   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19072               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19073               (clobber (mem:BLK (scratch)))])]
19074   "")
19075
19076 ;; Two pops case is tricky, since pop causes dependency on destination register.
19077 ;; We use two registers if available.
19078 (define_peephole2
19079   [(match_scratch:SI 0 "r")
19080    (match_scratch:SI 1 "r")
19081    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19082               (clobber (reg:CC FLAGS_REG))
19083               (clobber (mem:BLK (scratch)))])]
19084   "optimize_size || !TARGET_ADD_ESP_8"
19085   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19086               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19087               (clobber (mem:BLK (scratch)))])
19088    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19089               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19090   "")
19091
19092 (define_peephole2
19093   [(match_scratch:SI 0 "r")
19094    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19095               (clobber (reg:CC FLAGS_REG))
19096               (clobber (mem:BLK (scratch)))])]
19097   "optimize_size"
19098   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19099               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19100               (clobber (mem:BLK (scratch)))])
19101    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19102               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19103   "")
19104
19105 ;; Convert esp additions to pop.
19106 (define_peephole2
19107   [(match_scratch:SI 0 "r")
19108    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19109               (clobber (reg:CC FLAGS_REG))])]
19110   ""
19111   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19112               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19113   "")
19114
19115 ;; Two pops case is tricky, since pop causes dependency on destination register.
19116 ;; We use two registers if available.
19117 (define_peephole2
19118   [(match_scratch:SI 0 "r")
19119    (match_scratch:SI 1 "r")
19120    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19121               (clobber (reg:CC FLAGS_REG))])]
19122   ""
19123   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19124               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19125    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19126               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19127   "")
19128
19129 (define_peephole2
19130   [(match_scratch:SI 0 "r")
19131    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19132               (clobber (reg:CC FLAGS_REG))])]
19133   "optimize_size"
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 0) (mem:SI (reg:SI SP_REG)))
19137               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19138   "")
19139 \f
19140 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19141 ;; required and register dies.
19142 (define_peephole2
19143   [(set (reg 17)
19144         (compare (match_operand:SI 0 "register_operand" "")
19145                  (match_operand:SI 1 "incdec_operand" "")))]
19146   "ix86_match_ccmode (insn, CCGCmode)
19147    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19148   [(parallel [(set (reg:CCGC FLAGS_REG)
19149                    (compare:CCGC (match_dup 0)
19150                                  (match_dup 1)))
19151               (clobber (match_dup 0))])]
19152   "")
19153
19154 (define_peephole2
19155   [(set (reg 17)
19156         (compare (match_operand:HI 0 "register_operand" "")
19157                  (match_operand:HI 1 "incdec_operand" "")))]
19158   "ix86_match_ccmode (insn, CCGCmode)
19159    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19160   [(parallel [(set (reg:CCGC FLAGS_REG)
19161                    (compare:CCGC (match_dup 0)
19162                                  (match_dup 1)))
19163               (clobber (match_dup 0))])]
19164   "")
19165
19166 (define_peephole2
19167   [(set (reg 17)
19168         (compare (match_operand:QI 0 "register_operand" "")
19169                  (match_operand:QI 1 "incdec_operand" "")))]
19170   "ix86_match_ccmode (insn, CCGCmode)
19171    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19172   [(parallel [(set (reg:CCGC FLAGS_REG)
19173                    (compare:CCGC (match_dup 0)
19174                                  (match_dup 1)))
19175               (clobber (match_dup 0))])]
19176   "")
19177
19178 ;; Convert compares with 128 to shorter add -128
19179 (define_peephole2
19180   [(set (reg 17)
19181         (compare (match_operand:SI 0 "register_operand" "")
19182                  (const_int 128)))]
19183   "ix86_match_ccmode (insn, CCGCmode)
19184    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19185   [(parallel [(set (reg:CCGC FLAGS_REG)
19186                    (compare:CCGC (match_dup 0)
19187                                  (const_int 128)))
19188               (clobber (match_dup 0))])]
19189   "")
19190
19191 (define_peephole2
19192   [(set (reg 17)
19193         (compare (match_operand:HI 0 "register_operand" "")
19194                  (const_int 128)))]
19195   "ix86_match_ccmode (insn, CCGCmode)
19196    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19197   [(parallel [(set (reg:CCGC FLAGS_REG)
19198                    (compare:CCGC (match_dup 0)
19199                                  (const_int 128)))
19200               (clobber (match_dup 0))])]
19201   "")
19202 \f
19203 (define_peephole2
19204   [(match_scratch:DI 0 "r")
19205    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19206               (clobber (reg:CC FLAGS_REG))
19207               (clobber (mem:BLK (scratch)))])]
19208   "optimize_size || !TARGET_SUB_ESP_4"
19209   [(clobber (match_dup 0))
19210    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19211               (clobber (mem:BLK (scratch)))])])
19212
19213 (define_peephole2
19214   [(match_scratch:DI 0 "r")
19215    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19216               (clobber (reg:CC FLAGS_REG))
19217               (clobber (mem:BLK (scratch)))])]
19218   "optimize_size || !TARGET_SUB_ESP_8"
19219   [(clobber (match_dup 0))
19220    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (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 ;; Convert esp subtractions to push.
19225 (define_peephole2
19226   [(match_scratch:DI 0 "r")
19227    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19228               (clobber (reg:CC FLAGS_REG))])]
19229   "optimize_size || !TARGET_SUB_ESP_4"
19230   [(clobber (match_dup 0))
19231    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19232
19233 (define_peephole2
19234   [(match_scratch:DI 0 "r")
19235    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19236               (clobber (reg:CC FLAGS_REG))])]
19237   "optimize_size || !TARGET_SUB_ESP_8"
19238   [(clobber (match_dup 0))
19239    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19240    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19241
19242 ;; Convert epilogue deallocator to pop.
19243 (define_peephole2
19244   [(match_scratch:DI 0 "r")
19245    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19246               (clobber (reg:CC FLAGS_REG))
19247               (clobber (mem:BLK (scratch)))])]
19248   "optimize_size || !TARGET_ADD_ESP_4"
19249   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19250               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19251               (clobber (mem:BLK (scratch)))])]
19252   "")
19253
19254 ;; Two pops case is tricky, since pop causes dependency on destination register.
19255 ;; We use two registers if available.
19256 (define_peephole2
19257   [(match_scratch:DI 0 "r")
19258    (match_scratch:DI 1 "r")
19259    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19260               (clobber (reg:CC FLAGS_REG))
19261               (clobber (mem:BLK (scratch)))])]
19262   "optimize_size || !TARGET_ADD_ESP_8"
19263   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19264               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19265               (clobber (mem:BLK (scratch)))])
19266    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19267               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19268   "")
19269
19270 (define_peephole2
19271   [(match_scratch:DI 0 "r")
19272    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19273               (clobber (reg:CC FLAGS_REG))
19274               (clobber (mem:BLK (scratch)))])]
19275   "optimize_size"
19276   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19277               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19278               (clobber (mem:BLK (scratch)))])
19279    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19280               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19281   "")
19282
19283 ;; Convert esp additions to pop.
19284 (define_peephole2
19285   [(match_scratch:DI 0 "r")
19286    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19287               (clobber (reg:CC FLAGS_REG))])]
19288   ""
19289   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19290               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19291   "")
19292
19293 ;; Two pops case is tricky, since pop causes dependency on destination register.
19294 ;; We use two registers if available.
19295 (define_peephole2
19296   [(match_scratch:DI 0 "r")
19297    (match_scratch:DI 1 "r")
19298    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19299               (clobber (reg:CC FLAGS_REG))])]
19300   ""
19301   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19302               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19303    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19304               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19305   "")
19306
19307 (define_peephole2
19308   [(match_scratch:DI 0 "r")
19309    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19310               (clobber (reg:CC FLAGS_REG))])]
19311   "optimize_size"
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 0) (mem:DI (reg:DI SP_REG)))
19315               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19316   "")
19317 \f
19318 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19319 ;; imul $32bit_imm, reg, reg is direct decoded.
19320 (define_peephole2
19321   [(match_scratch:DI 3 "r")
19322    (parallel [(set (match_operand:DI 0 "register_operand" "")
19323                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19324                             (match_operand:DI 2 "immediate_operand" "")))
19325               (clobber (reg:CC FLAGS_REG))])]
19326   "TARGET_K8 && !optimize_size
19327    && (GET_CODE (operands[2]) != CONST_INT
19328        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19329   [(set (match_dup 3) (match_dup 1))
19330    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19331               (clobber (reg:CC FLAGS_REG))])]
19332 "")
19333
19334 (define_peephole2
19335   [(match_scratch:SI 3 "r")
19336    (parallel [(set (match_operand:SI 0 "register_operand" "")
19337                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19338                             (match_operand:SI 2 "immediate_operand" "")))
19339               (clobber (reg:CC FLAGS_REG))])]
19340   "TARGET_K8 && !optimize_size
19341    && (GET_CODE (operands[2]) != CONST_INT
19342        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19343   [(set (match_dup 3) (match_dup 1))
19344    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19345               (clobber (reg:CC FLAGS_REG))])]
19346 "")
19347
19348 (define_peephole2
19349   [(match_scratch:SI 3 "r")
19350    (parallel [(set (match_operand:DI 0 "register_operand" "")
19351                    (zero_extend:DI
19352                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19353                               (match_operand:SI 2 "immediate_operand" ""))))
19354               (clobber (reg:CC FLAGS_REG))])]
19355   "TARGET_K8 && !optimize_size
19356    && (GET_CODE (operands[2]) != CONST_INT
19357        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19358   [(set (match_dup 3) (match_dup 1))
19359    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19360               (clobber (reg:CC FLAGS_REG))])]
19361 "")
19362
19363 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19364 ;; Convert it into imul reg, reg
19365 ;; It would be better to force assembler to encode instruction using long
19366 ;; immediate, but there is apparently no way to do so.
19367 (define_peephole2
19368   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19369                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19370                             (match_operand:DI 2 "const_int_operand" "")))
19371               (clobber (reg:CC FLAGS_REG))])
19372    (match_scratch:DI 3 "r")]
19373   "TARGET_K8 && !optimize_size
19374    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19375   [(set (match_dup 3) (match_dup 2))
19376    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19377               (clobber (reg:CC FLAGS_REG))])]
19378 {
19379   if (!rtx_equal_p (operands[0], operands[1]))
19380     emit_move_insn (operands[0], operands[1]);
19381 })
19382
19383 (define_peephole2
19384   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19385                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19386                             (match_operand:SI 2 "const_int_operand" "")))
19387               (clobber (reg:CC FLAGS_REG))])
19388    (match_scratch:SI 3 "r")]
19389   "TARGET_K8 && !optimize_size
19390    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19391   [(set (match_dup 3) (match_dup 2))
19392    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19393               (clobber (reg:CC FLAGS_REG))])]
19394 {
19395   if (!rtx_equal_p (operands[0], operands[1]))
19396     emit_move_insn (operands[0], operands[1]);
19397 })
19398
19399 (define_peephole2
19400   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19401                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19402                             (match_operand:HI 2 "immediate_operand" "")))
19403               (clobber (reg:CC FLAGS_REG))])
19404    (match_scratch:HI 3 "r")]
19405   "TARGET_K8 && !optimize_size"
19406   [(set (match_dup 3) (match_dup 2))
19407    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19408               (clobber (reg:CC FLAGS_REG))])]
19409 {
19410   if (!rtx_equal_p (operands[0], operands[1]))
19411     emit_move_insn (operands[0], operands[1]);
19412 })
19413 \f
19414 ;; Call-value patterns last so that the wildcard operand does not
19415 ;; disrupt insn-recog's switch tables.
19416
19417 (define_insn "*call_value_pop_0"
19418   [(set (match_operand 0 "" "")
19419         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19420               (match_operand:SI 2 "" "")))
19421    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19422                             (match_operand:SI 3 "immediate_operand" "")))]
19423   "!TARGET_64BIT"
19424 {
19425   if (SIBLING_CALL_P (insn))
19426     return "jmp\t%P1";
19427   else
19428     return "call\t%P1";
19429 }
19430   [(set_attr "type" "callv")])
19431
19432 (define_insn "*call_value_pop_1"
19433   [(set (match_operand 0 "" "")
19434         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19435               (match_operand:SI 2 "" "")))
19436    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19437                             (match_operand:SI 3 "immediate_operand" "i")))]
19438   "!TARGET_64BIT"
19439 {
19440   if (constant_call_address_operand (operands[1], QImode))
19441     {
19442       if (SIBLING_CALL_P (insn))
19443         return "jmp\t%P1";
19444       else
19445         return "call\t%P1";
19446     }
19447   if (SIBLING_CALL_P (insn))
19448     return "jmp\t%A1";
19449   else
19450     return "call\t%A1";
19451 }
19452   [(set_attr "type" "callv")])
19453
19454 (define_insn "*call_value_0"
19455   [(set (match_operand 0 "" "")
19456         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19457               (match_operand:SI 2 "" "")))]
19458   "!TARGET_64BIT"
19459 {
19460   if (SIBLING_CALL_P (insn))
19461     return "jmp\t%P1";
19462   else
19463     return "call\t%P1";
19464 }
19465   [(set_attr "type" "callv")])
19466
19467 (define_insn "*call_value_0_rex64"
19468   [(set (match_operand 0 "" "")
19469         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19470               (match_operand:DI 2 "const_int_operand" "")))]
19471   "TARGET_64BIT"
19472 {
19473   if (SIBLING_CALL_P (insn))
19474     return "jmp\t%P1";
19475   else
19476     return "call\t%P1";
19477 }
19478   [(set_attr "type" "callv")])
19479
19480 (define_insn "*call_value_1"
19481   [(set (match_operand 0 "" "")
19482         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19483               (match_operand:SI 2 "" "")))]
19484   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19485 {
19486   if (constant_call_address_operand (operands[1], QImode))
19487     return "call\t%P1";
19488   return "call\t%*%1";
19489 }
19490   [(set_attr "type" "callv")])
19491
19492 (define_insn "*sibcall_value_1"
19493   [(set (match_operand 0 "" "")
19494         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19495               (match_operand:SI 2 "" "")))]
19496   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19497 {
19498   if (constant_call_address_operand (operands[1], QImode))
19499     return "jmp\t%P1";
19500   return "jmp\t%*%1";
19501 }
19502   [(set_attr "type" "callv")])
19503
19504 (define_insn "*call_value_1_rex64"
19505   [(set (match_operand 0 "" "")
19506         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19507               (match_operand:DI 2 "" "")))]
19508   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19509 {
19510   if (constant_call_address_operand (operands[1], QImode))
19511     return "call\t%P1";
19512   return "call\t%A1";
19513 }
19514   [(set_attr "type" "callv")])
19515
19516 (define_insn "*sibcall_value_1_rex64"
19517   [(set (match_operand 0 "" "")
19518         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19519               (match_operand:DI 2 "" "")))]
19520   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19521   "jmp\t%P1"
19522   [(set_attr "type" "callv")])
19523
19524 (define_insn "*sibcall_value_1_rex64_v"
19525   [(set (match_operand 0 "" "")
19526         (call (mem:QI (reg:DI 40))
19527               (match_operand:DI 1 "" "")))]
19528   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19529   "jmp\t*%%r11"
19530   [(set_attr "type" "callv")])
19531 \f
19532 (define_insn "trap"
19533   [(trap_if (const_int 1) (const_int 5))]
19534   ""
19535   "int\t$5")
19536
19537 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19538 ;;; for the sake of bounds checking.  By emitting bounds checks as
19539 ;;; conditional traps rather than as conditional jumps around
19540 ;;; unconditional traps we avoid introducing spurious basic-block
19541 ;;; boundaries and facilitate elimination of redundant checks.  In
19542 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19543 ;;; interrupt 5.
19544 ;;; 
19545 ;;; FIXME: Static branch prediction rules for ix86 are such that
19546 ;;; forward conditional branches predict as untaken.  As implemented
19547 ;;; below, pseudo conditional traps violate that rule.  We should use
19548 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19549 ;;; section loaded at the end of the text segment and branch forward
19550 ;;; there on bounds-failure, and then jump back immediately (in case
19551 ;;; the system chooses to ignore bounds violations, or to report
19552 ;;; violations and continue execution).
19553
19554 (define_expand "conditional_trap"
19555   [(trap_if (match_operator 0 "comparison_operator"
19556              [(match_dup 2) (const_int 0)])
19557             (match_operand 1 "const_int_operand" ""))]
19558   ""
19559 {
19560   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19561                               ix86_expand_compare (GET_CODE (operands[0]),
19562                                                    NULL, NULL),
19563                               operands[1]));
19564   DONE;
19565 })
19566
19567 (define_insn "*conditional_trap_1"
19568   [(trap_if (match_operator 0 "comparison_operator"
19569              [(reg 17) (const_int 0)])
19570             (match_operand 1 "const_int_operand" ""))]
19571   ""
19572 {
19573   operands[2] = gen_label_rtx ();
19574   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19575   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19576                              CODE_LABEL_NUMBER (operands[2]));
19577   RET;
19578 })
19579
19580         ;; Pentium III SIMD instructions.
19581
19582 ;; Moves for SSE/MMX regs.
19583
19584 (define_insn "movv4sf_internal"
19585   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19586         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19587   "TARGET_SSE"
19588   "@
19589     xorps\t%0, %0
19590     movaps\t{%1, %0|%0, %1}
19591     movaps\t{%1, %0|%0, %1}"
19592   [(set_attr "type" "ssemov")
19593    (set_attr "mode" "V4SF")])
19594
19595 (define_split
19596   [(set (match_operand:V4SF 0 "register_operand" "")
19597         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19598   "TARGET_SSE"
19599   [(set (match_dup 0)
19600         (vec_merge:V4SF
19601          (vec_duplicate:V4SF (match_dup 1))
19602          (match_dup 2)
19603          (const_int 1)))]
19604 {
19605   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19606   operands[2] = CONST0_RTX (V4SFmode);
19607 })
19608
19609 (define_insn "movv4si_internal"
19610   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19611         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19612   "TARGET_SSE"
19613 {
19614   switch (which_alternative)
19615     {
19616     case 0:
19617       if (get_attr_mode (insn) == MODE_V4SF)
19618         return "xorps\t%0, %0";
19619       else
19620         return "pxor\t%0, %0";
19621     case 1:
19622     case 2:
19623       if (get_attr_mode (insn) == MODE_V4SF)
19624         return "movaps\t{%1, %0|%0, %1}";
19625       else
19626         return "movdqa\t{%1, %0|%0, %1}";
19627     default:
19628       abort ();
19629     }
19630 }
19631   [(set_attr "type" "ssemov")
19632    (set (attr "mode")
19633         (cond [(eq_attr "alternative" "0,1")
19634                  (if_then_else
19635                    (ne (symbol_ref "optimize_size")
19636                        (const_int 0))
19637                    (const_string "V4SF")
19638                    (const_string "TI"))
19639                (eq_attr "alternative" "2")
19640                  (if_then_else
19641                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19642                             (const_int 0))
19643                         (ne (symbol_ref "optimize_size")
19644                             (const_int 0)))
19645                    (const_string "V4SF")
19646                    (const_string "TI"))]
19647                (const_string "TI")))])
19648
19649 (define_insn "movv2di_internal"
19650   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19651         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19652   "TARGET_SSE"
19653 {
19654   switch (which_alternative)
19655     {
19656     case 0:
19657       if (get_attr_mode (insn) == MODE_V4SF)
19658         return "xorps\t%0, %0";
19659       else
19660         return "pxor\t%0, %0";
19661     case 1:
19662     case 2:
19663       if (get_attr_mode (insn) == MODE_V4SF)
19664         return "movaps\t{%1, %0|%0, %1}";
19665       else
19666         return "movdqa\t{%1, %0|%0, %1}";
19667     default:
19668       abort ();
19669     }
19670 }
19671   [(set_attr "type" "ssemov")
19672    (set (attr "mode")
19673         (cond [(eq_attr "alternative" "0,1")
19674                  (if_then_else
19675                    (ne (symbol_ref "optimize_size")
19676                        (const_int 0))
19677                    (const_string "V4SF")
19678                    (const_string "TI"))
19679                (eq_attr "alternative" "2")
19680                  (if_then_else
19681                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19682                             (const_int 0))
19683                         (ne (symbol_ref "optimize_size")
19684                             (const_int 0)))
19685                    (const_string "V4SF")
19686                    (const_string "TI"))]
19687                (const_string "TI")))])
19688
19689 (define_split
19690   [(set (match_operand:V2DF 0 "register_operand" "")
19691         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19692   "TARGET_SSE2"
19693   [(set (match_dup 0)
19694         (vec_merge:V2DF
19695          (vec_duplicate:V2DF (match_dup 1))
19696          (match_dup 2)
19697          (const_int 1)))]
19698 {
19699   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19700   operands[2] = CONST0_RTX (V2DFmode);
19701 })
19702
19703 (define_insn "movv8qi_internal"
19704   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19705         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19706   "TARGET_MMX
19707    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19708   "@
19709     pxor\t%0, %0
19710     movq\t{%1, %0|%0, %1}
19711     movq\t{%1, %0|%0, %1}"
19712   [(set_attr "type" "mmxmov")
19713    (set_attr "mode" "DI")])
19714
19715 (define_insn "movv4hi_internal"
19716   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19717         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19718   "TARGET_MMX
19719    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19720   "@
19721     pxor\t%0, %0
19722     movq\t{%1, %0|%0, %1}
19723     movq\t{%1, %0|%0, %1}"
19724   [(set_attr "type" "mmxmov")
19725    (set_attr "mode" "DI")])
19726
19727 (define_insn "movv2si_internal"
19728   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19729         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19730   "TARGET_MMX
19731    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19732   "@
19733     pxor\t%0, %0
19734     movq\t{%1, %0|%0, %1}
19735     movq\t{%1, %0|%0, %1}"
19736   [(set_attr "type" "mmxcvt")
19737    (set_attr "mode" "DI")])
19738
19739 (define_insn "movv2sf_internal"
19740   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19741         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19742   "TARGET_3DNOW
19743    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19744   "@
19745     pxor\t%0, %0
19746     movq\t{%1, %0|%0, %1}
19747     movq\t{%1, %0|%0, %1}"
19748   [(set_attr "type" "mmxcvt")
19749    (set_attr "mode" "DI")])
19750
19751 (define_expand "movti"
19752   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19753         (match_operand:TI 1 "nonimmediate_operand" ""))]
19754   "TARGET_SSE || TARGET_64BIT"
19755 {
19756   if (TARGET_64BIT)
19757     ix86_expand_move (TImode, operands);
19758   else
19759     ix86_expand_vector_move (TImode, operands);
19760   DONE;
19761 })
19762
19763 (define_expand "movtf"
19764   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19765         (match_operand:TF 1 "nonimmediate_operand" ""))]
19766   "TARGET_64BIT"
19767 {
19768   if (TARGET_64BIT)
19769     ix86_expand_move (TFmode, operands);
19770   else
19771     ix86_expand_vector_move (TFmode, operands);
19772   DONE;
19773 })
19774
19775 (define_insn "movv2df_internal"
19776   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19777         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19778   "TARGET_SSE2
19779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19780 {
19781   switch (which_alternative)
19782     {
19783     case 0:
19784       if (get_attr_mode (insn) == MODE_V4SF)
19785         return "xorps\t%0, %0";
19786       else
19787         return "xorpd\t%0, %0";
19788     case 1:
19789     case 2:
19790       if (get_attr_mode (insn) == MODE_V4SF)
19791         return "movaps\t{%1, %0|%0, %1}";
19792       else
19793         return "movapd\t{%1, %0|%0, %1}";
19794     default:
19795       abort ();
19796     }
19797 }
19798   [(set_attr "type" "ssemov")
19799    (set (attr "mode")
19800         (cond [(eq_attr "alternative" "0,1")
19801                  (if_then_else
19802                    (ne (symbol_ref "optimize_size")
19803                        (const_int 0))
19804                    (const_string "V4SF")
19805                    (const_string "V2DF"))
19806                (eq_attr "alternative" "2")
19807                  (if_then_else
19808                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19809                             (const_int 0))
19810                         (ne (symbol_ref "optimize_size")
19811                             (const_int 0)))
19812                    (const_string "V4SF")
19813                    (const_string "V2DF"))]
19814                (const_string "V2DF")))])
19815
19816 (define_insn "movv8hi_internal"
19817   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19818         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19819   "TARGET_SSE2
19820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19821 {
19822   switch (which_alternative)
19823     {
19824     case 0:
19825       if (get_attr_mode (insn) == MODE_V4SF)
19826         return "xorps\t%0, %0";
19827       else
19828         return "pxor\t%0, %0";
19829     case 1:
19830     case 2:
19831       if (get_attr_mode (insn) == MODE_V4SF)
19832         return "movaps\t{%1, %0|%0, %1}";
19833       else
19834         return "movdqa\t{%1, %0|%0, %1}";
19835     default:
19836       abort ();
19837     }
19838 }
19839   [(set_attr "type" "ssemov")
19840    (set (attr "mode")
19841         (cond [(eq_attr "alternative" "0,1")
19842                  (if_then_else
19843                    (ne (symbol_ref "optimize_size")
19844                        (const_int 0))
19845                    (const_string "V4SF")
19846                    (const_string "TI"))
19847                (eq_attr "alternative" "2")
19848                  (if_then_else
19849                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19850                             (const_int 0))
19851                         (ne (symbol_ref "optimize_size")
19852                             (const_int 0)))
19853                    (const_string "V4SF")
19854                    (const_string "TI"))]
19855                (const_string "TI")))])
19856
19857 (define_insn "movv16qi_internal"
19858   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19859         (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19860   "TARGET_SSE2
19861    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19862 {
19863   switch (which_alternative)
19864     {
19865     case 0:
19866       if (get_attr_mode (insn) == MODE_V4SF)
19867         return "xorps\t%0, %0";
19868       else
19869         return "pxor\t%0, %0";
19870     case 1:
19871     case 2:
19872       if (get_attr_mode (insn) == MODE_V4SF)
19873         return "movaps\t{%1, %0|%0, %1}";
19874       else
19875         return "movdqa\t{%1, %0|%0, %1}";
19876     default:
19877       abort ();
19878     }
19879 }
19880   [(set_attr "type" "ssemov")
19881    (set (attr "mode")
19882         (cond [(eq_attr "alternative" "0,1")
19883                  (if_then_else
19884                    (ne (symbol_ref "optimize_size")
19885                        (const_int 0))
19886                    (const_string "V4SF")
19887                    (const_string "TI"))
19888                (eq_attr "alternative" "2")
19889                  (if_then_else
19890                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19891                             (const_int 0))
19892                         (ne (symbol_ref "optimize_size")
19893                             (const_int 0)))
19894                    (const_string "V4SF")
19895                    (const_string "TI"))]
19896                (const_string "TI")))])
19897
19898 (define_expand "movv2df"
19899   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19900         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19901   "TARGET_SSE2"
19902 {
19903   ix86_expand_vector_move (V2DFmode, operands);
19904   DONE;
19905 })
19906
19907 (define_expand "movv8hi"
19908   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19909         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19910   "TARGET_SSE2"
19911 {
19912   ix86_expand_vector_move (V8HImode, operands);
19913   DONE;
19914 })
19915
19916 (define_expand "movv16qi"
19917   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19918         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19919   "TARGET_SSE2"
19920 {
19921   ix86_expand_vector_move (V16QImode, operands);
19922   DONE;
19923 })
19924
19925 (define_expand "movv4sf"
19926   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19927         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19928   "TARGET_SSE"
19929 {
19930   ix86_expand_vector_move (V4SFmode, operands);
19931   DONE;
19932 })
19933
19934 (define_expand "movv4si"
19935   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19936         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19937   "TARGET_SSE"
19938 {
19939   ix86_expand_vector_move (V4SImode, operands);
19940   DONE;
19941 })
19942
19943 (define_expand "movv2di"
19944   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19945         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19946   "TARGET_SSE"
19947 {
19948   ix86_expand_vector_move (V2DImode, operands);
19949   DONE;
19950 })
19951
19952 (define_expand "movv2si"
19953   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19954         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19955   "TARGET_MMX"
19956 {
19957   ix86_expand_vector_move (V2SImode, operands);
19958   DONE;
19959 })
19960
19961 (define_expand "movv4hi"
19962   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19963         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19964   "TARGET_MMX"
19965 {
19966   ix86_expand_vector_move (V4HImode, operands);
19967   DONE;
19968 })
19969
19970 (define_expand "movv8qi"
19971   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19972         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19973   "TARGET_MMX"
19974 {
19975   ix86_expand_vector_move (V8QImode, operands);
19976   DONE;
19977 })
19978
19979 (define_expand "movv2sf"
19980   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19981         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19982    "TARGET_3DNOW"
19983 {
19984   ix86_expand_vector_move (V2SFmode, operands);
19985   DONE;
19986 })
19987
19988 (define_insn "*pushti"
19989   [(set (match_operand:TI 0 "push_operand" "=<")
19990         (match_operand:TI 1 "register_operand" "x"))]
19991   "TARGET_SSE"
19992   "#")
19993
19994 (define_insn "*pushv2df"
19995   [(set (match_operand:V2DF 0 "push_operand" "=<")
19996         (match_operand:V2DF 1 "register_operand" "x"))]
19997   "TARGET_SSE"
19998   "#")
19999
20000 (define_insn "*pushv2di"
20001   [(set (match_operand:V2DI 0 "push_operand" "=<")
20002         (match_operand:V2DI 1 "register_operand" "x"))]
20003   "TARGET_SSE2"
20004   "#")
20005
20006 (define_insn "*pushv8hi"
20007   [(set (match_operand:V8HI 0 "push_operand" "=<")
20008         (match_operand:V8HI 1 "register_operand" "x"))]
20009   "TARGET_SSE2"
20010   "#")
20011
20012 (define_insn "*pushv16qi"
20013   [(set (match_operand:V16QI 0 "push_operand" "=<")
20014         (match_operand:V16QI 1 "register_operand" "x"))]
20015   "TARGET_SSE2"
20016   "#")
20017
20018 (define_insn "*pushv4sf"
20019   [(set (match_operand:V4SF 0 "push_operand" "=<")
20020         (match_operand:V4SF 1 "register_operand" "x"))]
20021   "TARGET_SSE"
20022   "#")
20023
20024 (define_insn "*pushv4si"
20025   [(set (match_operand:V4SI 0 "push_operand" "=<")
20026         (match_operand:V4SI 1 "register_operand" "x"))]
20027   "TARGET_SSE2"
20028   "#")
20029
20030 (define_insn "*pushv2si"
20031   [(set (match_operand:V2SI 0 "push_operand" "=<")
20032         (match_operand:V2SI 1 "register_operand" "y"))]
20033   "TARGET_MMX"
20034   "#")
20035
20036 (define_insn "*pushv4hi"
20037   [(set (match_operand:V4HI 0 "push_operand" "=<")
20038         (match_operand:V4HI 1 "register_operand" "y"))]
20039   "TARGET_MMX"
20040   "#")
20041
20042 (define_insn "*pushv8qi"
20043   [(set (match_operand:V8QI 0 "push_operand" "=<")
20044         (match_operand:V8QI 1 "register_operand" "y"))]
20045   "TARGET_MMX"
20046   "#")
20047
20048 (define_insn "*pushv2sf"
20049   [(set (match_operand:V2SF 0 "push_operand" "=<")
20050         (match_operand:V2SF 1 "register_operand" "y"))]
20051   "TARGET_3DNOW"
20052   "#")
20053
20054 (define_split
20055   [(set (match_operand 0 "push_operand" "")
20056         (match_operand 1 "register_operand" ""))]
20057   "!TARGET_64BIT && reload_completed
20058    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20059   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20060    (set (match_dup 2) (match_dup 1))]
20061   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20062                                  stack_pointer_rtx);
20063    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20064
20065 (define_split
20066   [(set (match_operand 0 "push_operand" "")
20067         (match_operand 1 "register_operand" ""))]
20068   "TARGET_64BIT && reload_completed
20069    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20070   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20071    (set (match_dup 2) (match_dup 1))]
20072   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20073                                  stack_pointer_rtx);
20074    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20075
20076
20077 (define_insn "movti_internal"
20078   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20079         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20080   "TARGET_SSE && !TARGET_64BIT
20081    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20082 {
20083   switch (which_alternative)
20084     {
20085     case 0:
20086       if (get_attr_mode (insn) == MODE_V4SF)
20087         return "xorps\t%0, %0";
20088       else
20089         return "pxor\t%0, %0";
20090     case 1:
20091     case 2:
20092       if (get_attr_mode (insn) == MODE_V4SF)
20093         return "movaps\t{%1, %0|%0, %1}";
20094       else
20095         return "movdqa\t{%1, %0|%0, %1}";
20096     default:
20097       abort ();
20098     }
20099 }
20100   [(set_attr "type" "ssemov,ssemov,ssemov")
20101    (set (attr "mode")
20102         (cond [(eq_attr "alternative" "0,1")
20103                  (if_then_else
20104                    (ne (symbol_ref "optimize_size")
20105                        (const_int 0))
20106                    (const_string "V4SF")
20107                    (const_string "TI"))
20108                (eq_attr "alternative" "2")
20109                  (if_then_else
20110                    (ne (symbol_ref "optimize_size")
20111                        (const_int 0))
20112                    (const_string "V4SF")
20113                    (const_string "TI"))]
20114                (const_string "TI")))])
20115
20116 (define_insn "*movti_rex64"
20117   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20118         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20119   "TARGET_64BIT
20120    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20121 {
20122   switch (which_alternative)
20123     {
20124     case 0:
20125     case 1:
20126       return "#";
20127     case 2:
20128       if (get_attr_mode (insn) == MODE_V4SF)
20129         return "xorps\t%0, %0";
20130       else
20131         return "pxor\t%0, %0";
20132     case 3:
20133     case 4:
20134       if (get_attr_mode (insn) == MODE_V4SF)
20135         return "movaps\t{%1, %0|%0, %1}";
20136       else
20137         return "movdqa\t{%1, %0|%0, %1}";
20138     default:
20139       abort ();
20140     }
20141 }
20142   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20143    (set (attr "mode")
20144         (cond [(eq_attr "alternative" "2,3")
20145                  (if_then_else
20146                    (ne (symbol_ref "optimize_size")
20147                        (const_int 0))
20148                    (const_string "V4SF")
20149                    (const_string "TI"))
20150                (eq_attr "alternative" "4")
20151                  (if_then_else
20152                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20153                             (const_int 0))
20154                         (ne (symbol_ref "optimize_size")
20155                             (const_int 0)))
20156                    (const_string "V4SF")
20157                    (const_string "TI"))]
20158                (const_string "DI")))])
20159
20160 (define_insn "*movtf_rex64"
20161   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20162         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20163   "TARGET_64BIT
20164    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20165 {
20166   switch (which_alternative)
20167     {
20168     case 0:
20169     case 1:
20170       return "#";
20171     case 2:
20172       if (get_attr_mode (insn) == MODE_V4SF)
20173         return "xorps\t%0, %0";
20174       else
20175         return "pxor\t%0, %0";
20176     case 3:
20177     case 4:
20178       if (get_attr_mode (insn) == MODE_V4SF)
20179         return "movaps\t{%1, %0|%0, %1}";
20180       else
20181         return "movdqa\t{%1, %0|%0, %1}";
20182     default:
20183       abort ();
20184     }
20185 }
20186   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20187    (set (attr "mode")
20188         (cond [(eq_attr "alternative" "2,3")
20189                  (if_then_else
20190                    (ne (symbol_ref "optimize_size")
20191                        (const_int 0))
20192                    (const_string "V4SF")
20193                    (const_string "TI"))
20194                (eq_attr "alternative" "4")
20195                  (if_then_else
20196                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20197                             (const_int 0))
20198                         (ne (symbol_ref "optimize_size")
20199                             (const_int 0)))
20200                    (const_string "V4SF")
20201                    (const_string "TI"))]
20202                (const_string "DI")))])
20203
20204 (define_split
20205   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20206         (match_operand:TI 1 "general_operand" ""))]
20207   "reload_completed && !SSE_REG_P (operands[0])
20208    && !SSE_REG_P (operands[1])"
20209   [(const_int 0)]
20210   "ix86_split_long_move (operands); DONE;")
20211
20212 (define_split
20213   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20214         (match_operand:TF 1 "general_operand" ""))]
20215   "reload_completed && !SSE_REG_P (operands[0])
20216    && !SSE_REG_P (operands[1])"
20217   [(const_int 0)]
20218   "ix86_split_long_move (operands); DONE;")
20219
20220 ;; These two patterns are useful for specifying exactly whether to use
20221 ;; movaps or movups
20222 (define_expand "sse_movaps"
20223   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20224         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20225                      UNSPEC_MOVA))]
20226   "TARGET_SSE"
20227 {
20228   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20229     {
20230       rtx tmp = gen_reg_rtx (V4SFmode);
20231       emit_insn (gen_sse_movaps (tmp, operands[1]));
20232       emit_move_insn (operands[0], tmp);
20233       DONE;
20234     }
20235 })
20236
20237 (define_insn "*sse_movaps_1"
20238   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20239         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20240                      UNSPEC_MOVA))]
20241   "TARGET_SSE
20242    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20243   "movaps\t{%1, %0|%0, %1}"
20244   [(set_attr "type" "ssemov,ssemov")
20245    (set_attr "mode" "V4SF")])
20246
20247 (define_expand "sse_movups"
20248   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20249         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20250                      UNSPEC_MOVU))]
20251   "TARGET_SSE"
20252 {
20253   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20254     {
20255       rtx tmp = gen_reg_rtx (V4SFmode);
20256       emit_insn (gen_sse_movups (tmp, operands[1]));
20257       emit_move_insn (operands[0], tmp);
20258       DONE;
20259     }
20260 })
20261
20262 (define_insn "*sse_movups_1"
20263   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20264         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20265                      UNSPEC_MOVU))]
20266   "TARGET_SSE
20267    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20268   "movups\t{%1, %0|%0, %1}"
20269   [(set_attr "type" "ssecvt,ssecvt")
20270    (set_attr "mode" "V4SF")])
20271
20272 ;; SSE Strange Moves.
20273
20274 (define_insn "sse_movmskps"
20275   [(set (match_operand:SI 0 "register_operand" "=r")
20276         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20277                    UNSPEC_MOVMSK))]
20278   "TARGET_SSE"
20279   "movmskps\t{%1, %0|%0, %1}"
20280   [(set_attr "type" "ssecvt")
20281    (set_attr "mode" "V4SF")])
20282
20283 (define_insn "mmx_pmovmskb"
20284   [(set (match_operand:SI 0 "register_operand" "=r")
20285         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20286                    UNSPEC_MOVMSK))]
20287   "TARGET_SSE || TARGET_3DNOW_A"
20288   "pmovmskb\t{%1, %0|%0, %1}"
20289   [(set_attr "type" "ssecvt")
20290    (set_attr "mode" "V4SF")])
20291
20292
20293 (define_insn "mmx_maskmovq"
20294   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20295         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20296                       (match_operand:V8QI 2 "register_operand" "y")]
20297                      UNSPEC_MASKMOV))]
20298   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20299   ;; @@@ check ordering of operands in intel/nonintel syntax
20300   "maskmovq\t{%2, %1|%1, %2}"
20301   [(set_attr "type" "mmxcvt")
20302    (set_attr "mode" "DI")])
20303
20304 (define_insn "mmx_maskmovq_rex"
20305   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20306         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20307                       (match_operand:V8QI 2 "register_operand" "y")]
20308                      UNSPEC_MASKMOV))]
20309   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20310   ;; @@@ check ordering of operands in intel/nonintel syntax
20311   "maskmovq\t{%2, %1|%1, %2}"
20312   [(set_attr "type" "mmxcvt")
20313    (set_attr "mode" "DI")])
20314
20315 (define_insn "sse_movntv4sf"
20316   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20317         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20318                      UNSPEC_MOVNT))]
20319   "TARGET_SSE"
20320   "movntps\t{%1, %0|%0, %1}"
20321   [(set_attr "type" "ssemov")
20322    (set_attr "mode" "V4SF")])
20323
20324 (define_insn "sse_movntdi"
20325   [(set (match_operand:DI 0 "memory_operand" "=m")
20326         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20327                    UNSPEC_MOVNT))]
20328   "TARGET_SSE || TARGET_3DNOW_A"
20329   "movntq\t{%1, %0|%0, %1}"
20330   [(set_attr "type" "mmxmov")
20331    (set_attr "mode" "DI")])
20332
20333 (define_insn "sse_movhlps"
20334   [(set (match_operand:V4SF 0 "register_operand" "=x")
20335         (vec_merge:V4SF
20336          (match_operand:V4SF 1 "register_operand" "0")
20337          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20338                           (parallel [(const_int 2)
20339                                      (const_int 3)
20340                                      (const_int 0)
20341                                      (const_int 1)]))
20342          (const_int 3)))]
20343   "TARGET_SSE"
20344   "movhlps\t{%2, %0|%0, %2}"
20345   [(set_attr "type" "ssecvt")
20346    (set_attr "mode" "V4SF")])
20347
20348 (define_insn "sse_movlhps"
20349   [(set (match_operand:V4SF 0 "register_operand" "=x")
20350         (vec_merge:V4SF
20351          (match_operand:V4SF 1 "register_operand" "0")
20352          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20353                           (parallel [(const_int 2)
20354                                      (const_int 3)
20355                                      (const_int 0)
20356                                      (const_int 1)]))
20357          (const_int 12)))]
20358   "TARGET_SSE"
20359   "movlhps\t{%2, %0|%0, %2}"
20360   [(set_attr "type" "ssecvt")
20361    (set_attr "mode" "V4SF")])
20362
20363 (define_insn "sse_movhps"
20364   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20365         (vec_merge:V4SF
20366          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20367          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20368          (const_int 12)))]
20369   "TARGET_SSE
20370    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20371   "movhps\t{%2, %0|%0, %2}"
20372   [(set_attr "type" "ssecvt")
20373    (set_attr "mode" "V4SF")])
20374
20375 (define_insn "sse_movlps"
20376   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20377         (vec_merge:V4SF
20378          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20379          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20380          (const_int 3)))]
20381   "TARGET_SSE
20382    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20383   "movlps\t{%2, %0|%0, %2}"
20384   [(set_attr "type" "ssecvt")
20385    (set_attr "mode" "V4SF")])
20386
20387 (define_expand "sse_loadss"
20388   [(match_operand:V4SF 0 "register_operand" "")
20389    (match_operand:SF 1 "memory_operand" "")]
20390   "TARGET_SSE"
20391 {
20392   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20393                                CONST0_RTX (V4SFmode)));
20394   DONE;
20395 })
20396
20397 (define_insn "sse_loadss_1"
20398   [(set (match_operand:V4SF 0 "register_operand" "=x")
20399         (vec_merge:V4SF
20400          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20401          (match_operand:V4SF 2 "const0_operand" "X")
20402          (const_int 1)))]
20403   "TARGET_SSE"
20404   "movss\t{%1, %0|%0, %1}"
20405   [(set_attr "type" "ssemov")
20406    (set_attr "mode" "SF")])
20407
20408 (define_insn "sse_movss"
20409   [(set (match_operand:V4SF 0 "register_operand" "=x")
20410         (vec_merge:V4SF
20411          (match_operand:V4SF 1 "register_operand" "0")
20412          (match_operand:V4SF 2 "register_operand" "x")
20413          (const_int 1)))]
20414   "TARGET_SSE"
20415   "movss\t{%2, %0|%0, %2}"
20416   [(set_attr "type" "ssemov")
20417    (set_attr "mode" "SF")])
20418
20419 (define_insn "sse_storess"
20420   [(set (match_operand:SF 0 "memory_operand" "=m")
20421         (vec_select:SF
20422          (match_operand:V4SF 1 "register_operand" "x")
20423          (parallel [(const_int 0)])))]
20424   "TARGET_SSE"
20425   "movss\t{%1, %0|%0, %1}"
20426   [(set_attr "type" "ssemov")
20427    (set_attr "mode" "SF")])
20428
20429 (define_insn "sse_shufps"
20430   [(set (match_operand:V4SF 0 "register_operand" "=x")
20431         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20432                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20433                       (match_operand:SI 3 "immediate_operand" "i")]
20434                      UNSPEC_SHUFFLE))]
20435   "TARGET_SSE"
20436   ;; @@@ check operand order for intel/nonintel syntax
20437   "shufps\t{%3, %2, %0|%0, %2, %3}"
20438   [(set_attr "type" "ssecvt")
20439    (set_attr "mode" "V4SF")])
20440
20441
20442 ;; SSE arithmetic
20443
20444 (define_insn "addv4sf3"
20445   [(set (match_operand:V4SF 0 "register_operand" "=x")
20446         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20447                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20448   "TARGET_SSE"
20449   "addps\t{%2, %0|%0, %2}"
20450   [(set_attr "type" "sseadd")
20451    (set_attr "mode" "V4SF")])
20452
20453 (define_insn "vmaddv4sf3"
20454   [(set (match_operand:V4SF 0 "register_operand" "=x")
20455         (vec_merge:V4SF
20456          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20457                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20458          (match_dup 1)
20459          (const_int 1)))]
20460   "TARGET_SSE"
20461   "addss\t{%2, %0|%0, %2}"
20462   [(set_attr "type" "sseadd")
20463    (set_attr "mode" "SF")])
20464
20465 (define_insn "subv4sf3"
20466   [(set (match_operand:V4SF 0 "register_operand" "=x")
20467         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20468                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20469   "TARGET_SSE"
20470   "subps\t{%2, %0|%0, %2}"
20471   [(set_attr "type" "sseadd")
20472    (set_attr "mode" "V4SF")])
20473
20474 (define_insn "vmsubv4sf3"
20475   [(set (match_operand:V4SF 0 "register_operand" "=x")
20476         (vec_merge:V4SF
20477          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20478                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20479          (match_dup 1)
20480          (const_int 1)))]
20481   "TARGET_SSE"
20482   "subss\t{%2, %0|%0, %2}"
20483   [(set_attr "type" "sseadd")
20484    (set_attr "mode" "SF")])
20485
20486 ;; ??? Should probably be done by generic code instead.
20487 (define_expand "negv4sf2"
20488   [(set (match_operand:V4SF 0 "register_operand" "")
20489         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20490                   (match_dup 2)))]
20491   "TARGET_SSE"
20492 {
20493   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20494   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20495   operands[2] = force_reg (V4SFmode, vm0);
20496 })
20497
20498 (define_insn "mulv4sf3"
20499   [(set (match_operand:V4SF 0 "register_operand" "=x")
20500         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20501                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20502   "TARGET_SSE"
20503   "mulps\t{%2, %0|%0, %2}"
20504   [(set_attr "type" "ssemul")
20505    (set_attr "mode" "V4SF")])
20506
20507 (define_insn "vmmulv4sf3"
20508   [(set (match_operand:V4SF 0 "register_operand" "=x")
20509         (vec_merge:V4SF
20510          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20511                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20512          (match_dup 1)
20513          (const_int 1)))]
20514   "TARGET_SSE"
20515   "mulss\t{%2, %0|%0, %2}"
20516   [(set_attr "type" "ssemul")
20517    (set_attr "mode" "SF")])
20518
20519 (define_insn "divv4sf3"
20520   [(set (match_operand:V4SF 0 "register_operand" "=x")
20521         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20522                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20523   "TARGET_SSE"
20524   "divps\t{%2, %0|%0, %2}"
20525   [(set_attr "type" "ssediv")
20526    (set_attr "mode" "V4SF")])
20527
20528 (define_insn "vmdivv4sf3"
20529   [(set (match_operand:V4SF 0 "register_operand" "=x")
20530         (vec_merge:V4SF
20531          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20532                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20533          (match_dup 1)
20534          (const_int 1)))]
20535   "TARGET_SSE"
20536   "divss\t{%2, %0|%0, %2}"
20537   [(set_attr "type" "ssediv")
20538    (set_attr "mode" "SF")])
20539
20540
20541 ;; SSE square root/reciprocal
20542
20543 (define_insn "rcpv4sf2"
20544   [(set (match_operand:V4SF 0 "register_operand" "=x")
20545         (unspec:V4SF
20546          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20547   "TARGET_SSE"
20548   "rcpps\t{%1, %0|%0, %1}"
20549   [(set_attr "type" "sse")
20550    (set_attr "mode" "V4SF")])
20551
20552 (define_insn "vmrcpv4sf2"
20553   [(set (match_operand:V4SF 0 "register_operand" "=x")
20554         (vec_merge:V4SF
20555          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20556                       UNSPEC_RCP)
20557          (match_operand:V4SF 2 "register_operand" "0")
20558          (const_int 1)))]
20559   "TARGET_SSE"
20560   "rcpss\t{%1, %0|%0, %1}"
20561   [(set_attr "type" "sse")
20562    (set_attr "mode" "SF")])
20563
20564 (define_insn "rsqrtv4sf2"
20565   [(set (match_operand:V4SF 0 "register_operand" "=x")
20566         (unspec:V4SF
20567          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20568   "TARGET_SSE"
20569   "rsqrtps\t{%1, %0|%0, %1}"
20570   [(set_attr "type" "sse")
20571    (set_attr "mode" "V4SF")])
20572
20573 (define_insn "vmrsqrtv4sf2"
20574   [(set (match_operand:V4SF 0 "register_operand" "=x")
20575         (vec_merge:V4SF
20576          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20577                       UNSPEC_RSQRT)
20578          (match_operand:V4SF 2 "register_operand" "0")
20579          (const_int 1)))]
20580   "TARGET_SSE"
20581   "rsqrtss\t{%1, %0|%0, %1}"
20582   [(set_attr "type" "sse")
20583    (set_attr "mode" "SF")])
20584
20585 (define_insn "sqrtv4sf2"
20586   [(set (match_operand:V4SF 0 "register_operand" "=x")
20587         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20588   "TARGET_SSE"
20589   "sqrtps\t{%1, %0|%0, %1}"
20590   [(set_attr "type" "sse")
20591    (set_attr "mode" "V4SF")])
20592
20593 (define_insn "vmsqrtv4sf2"
20594   [(set (match_operand:V4SF 0 "register_operand" "=x")
20595         (vec_merge:V4SF
20596          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20597          (match_operand:V4SF 2 "register_operand" "0")
20598          (const_int 1)))]
20599   "TARGET_SSE"
20600   "sqrtss\t{%1, %0|%0, %1}"
20601   [(set_attr "type" "sse")
20602    (set_attr "mode" "SF")])
20603
20604 ;; SSE logical operations.
20605
20606 ;; SSE defines logical operations on floating point values.  This brings
20607 ;; interesting challenge to RTL representation where logicals are only valid
20608 ;; on integral types.  We deal with this by representing the floating point
20609 ;; logical as logical on arguments casted to TImode as this is what hardware
20610 ;; really does.  Unfortunately hardware requires the type information to be
20611 ;; present and thus we must avoid subregs from being simplified and eliminated
20612 ;; in later compilation phases.
20613 ;;
20614 ;; We have following variants from each instruction:
20615 ;; sse_andsf3 - the operation taking V4SF vector operands
20616 ;;              and doing TImode cast on them
20617 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20618 ;;                      TImode, since backend insist on eliminating casts
20619 ;;                      on memory operands
20620 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20621 ;;                   We can not accept memory operand here as instruction reads
20622 ;;                   whole scalar.  This is generated only post reload by GCC
20623 ;;                   scalar float operations that expands to logicals (fabs)
20624 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20625 ;;                   memory operand.  Eventually combine can be able
20626 ;;                   to synthesize these using splitter.
20627 ;; sse2_anddf3, *sse2_anddf3_memory
20628 ;;              
20629 ;; 
20630 ;; These are not called andti3 etc. because we really really don't want
20631 ;; the compiler to widen DImode ands to TImode ands and then try to move
20632 ;; into DImode subregs of SSE registers, and them together, and move out
20633 ;; of DImode subregs again!
20634 ;; SSE1 single precision floating point logical operation
20635 (define_expand "sse_andv4sf3"
20636   [(set (match_operand:V4SF 0 "register_operand" "")
20637         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20638                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20639   "TARGET_SSE"
20640   "")
20641
20642 (define_insn "*sse_andv4sf3"
20643   [(set (match_operand:V4SF 0 "register_operand" "=x")
20644         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20645                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20646   "TARGET_SSE
20647    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20648   "andps\t{%2, %0|%0, %2}"
20649   [(set_attr "type" "sselog")
20650    (set_attr "mode" "V4SF")])
20651
20652 (define_expand "sse_nandv4sf3"
20653   [(set (match_operand:V4SF 0 "register_operand" "")
20654         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20655                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20656   "TARGET_SSE"
20657   "")
20658
20659 (define_insn "*sse_nandv4sf3"
20660   [(set (match_operand:V4SF 0 "register_operand" "=x")
20661         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20662                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20663   "TARGET_SSE"
20664   "andnps\t{%2, %0|%0, %2}"
20665   [(set_attr "type" "sselog")
20666    (set_attr "mode" "V4SF")])
20667
20668 (define_expand "sse_iorv4sf3"
20669   [(set (match_operand:V4SF 0 "register_operand" "")
20670         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20671                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20672   "TARGET_SSE"
20673   "")
20674
20675 (define_insn "*sse_iorv4sf3"
20676   [(set (match_operand:V4SF 0 "register_operand" "=x")
20677         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20678                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20679   "TARGET_SSE
20680    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20681   "orps\t{%2, %0|%0, %2}"
20682   [(set_attr "type" "sselog")
20683    (set_attr "mode" "V4SF")])
20684
20685 (define_expand "sse_xorv4sf3"
20686   [(set (match_operand:V4SF 0 "register_operand" "")
20687         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20688                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20689   "TARGET_SSE"
20690   "")
20691
20692 (define_insn "*sse_xorv4sf3"
20693   [(set (match_operand:V4SF 0 "register_operand" "=x")
20694         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20695                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20696   "TARGET_SSE
20697    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20698   "xorps\t{%2, %0|%0, %2}"
20699   [(set_attr "type" "sselog")
20700    (set_attr "mode" "V4SF")])
20701
20702 ;; SSE2 double precision floating point logical operation
20703
20704 (define_expand "sse2_andv2df3"
20705   [(set (match_operand:V2DF 0 "register_operand" "")
20706         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20707                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20708   "TARGET_SSE2"
20709   "")
20710
20711 (define_insn "*sse2_andv2df3"
20712   [(set (match_operand:V2DF 0 "register_operand" "=x")
20713         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20714                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20715   "TARGET_SSE2
20716    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20717   "andpd\t{%2, %0|%0, %2}"
20718   [(set_attr "type" "sselog")
20719    (set_attr "mode" "V2DF")])
20720
20721 (define_expand "sse2_nandv2df3"
20722   [(set (match_operand:V2DF 0 "register_operand" "")
20723         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20724                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20725   "TARGET_SSE2"
20726   "")
20727
20728 (define_insn "*sse2_nandv2df3"
20729   [(set (match_operand:V2DF 0 "register_operand" "=x")
20730         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20731                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20732   "TARGET_SSE2"
20733   "andnpd\t{%2, %0|%0, %2}"
20734   [(set_attr "type" "sselog")
20735    (set_attr "mode" "V2DF")])
20736
20737 (define_expand "sse2_iorv2df3"
20738   [(set (match_operand:V2DF 0 "register_operand" "")
20739         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20740                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20741   "TARGET_SSE2"
20742   "")
20743
20744 (define_insn "*sse2_iorv2df3"
20745   [(set (match_operand:V2DF 0 "register_operand" "=x")
20746         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20747                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20748   "TARGET_SSE2
20749    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20750   "orpd\t{%2, %0|%0, %2}"
20751   [(set_attr "type" "sselog")
20752    (set_attr "mode" "V2DF")])
20753
20754 (define_expand "sse2_xorv2df3"
20755   [(set (match_operand:V2DF 0 "register_operand" "")
20756         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20757                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20758   "TARGET_SSE2"
20759   "")
20760
20761 (define_insn "*sse2_xorv2df3"
20762   [(set (match_operand:V2DF 0 "register_operand" "=x")
20763         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20764                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20765   "TARGET_SSE2
20766    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20767   "xorpd\t{%2, %0|%0, %2}"
20768   [(set_attr "type" "sselog")
20769    (set_attr "mode" "V2DF")])
20770
20771 ;; SSE2 integral logicals.  These patterns must always come after floating
20772 ;; point ones since we don't want compiler to use integer opcodes on floating
20773 ;; point SSE values to avoid matching of subregs in the match_operand.
20774 (define_insn "*sse2_andti3"
20775   [(set (match_operand:TI 0 "register_operand" "=x")
20776         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20777                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20778   "TARGET_SSE2
20779    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20780   "pand\t{%2, %0|%0, %2}"
20781   [(set_attr "type" "sselog")
20782    (set_attr "mode" "TI")])
20783
20784 (define_insn "sse2_andv2di3"
20785   [(set (match_operand:V2DI 0 "register_operand" "=x")
20786         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20787                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20788   "TARGET_SSE2
20789    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20790   "pand\t{%2, %0|%0, %2}"
20791   [(set_attr "type" "sselog")
20792    (set_attr "mode" "TI")])
20793
20794 (define_insn "*sse2_nandti3"
20795   [(set (match_operand:TI 0 "register_operand" "=x")
20796         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20797                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20798   "TARGET_SSE2"
20799   "pandn\t{%2, %0|%0, %2}"
20800   [(set_attr "type" "sselog")
20801    (set_attr "mode" "TI")])
20802
20803 (define_insn "sse2_nandv2di3"
20804   [(set (match_operand:V2DI 0 "register_operand" "=x")
20805         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20806                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20807   "TARGET_SSE2
20808    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20809   "pandn\t{%2, %0|%0, %2}"
20810   [(set_attr "type" "sselog")
20811    (set_attr "mode" "TI")])
20812
20813 (define_insn "*sse2_iorti3"
20814   [(set (match_operand:TI 0 "register_operand" "=x")
20815         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20816                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20817   "TARGET_SSE2
20818    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20819   "por\t{%2, %0|%0, %2}"
20820   [(set_attr "type" "sselog")
20821    (set_attr "mode" "TI")])
20822
20823 (define_insn "sse2_iorv2di3"
20824   [(set (match_operand:V2DI 0 "register_operand" "=x")
20825         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20826                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20827   "TARGET_SSE2
20828    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20829   "por\t{%2, %0|%0, %2}"
20830   [(set_attr "type" "sselog")
20831    (set_attr "mode" "TI")])
20832
20833 (define_insn "*sse2_xorti3"
20834   [(set (match_operand:TI 0 "register_operand" "=x")
20835         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20836                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20837   "TARGET_SSE2
20838    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20839   "pxor\t{%2, %0|%0, %2}"
20840   [(set_attr "type" "sselog")
20841    (set_attr "mode" "TI")])
20842
20843 (define_insn "sse2_xorv2di3"
20844   [(set (match_operand:V2DI 0 "register_operand" "=x")
20845         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20846                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20847   "TARGET_SSE2
20848    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20849   "pxor\t{%2, %0|%0, %2}"
20850   [(set_attr "type" "sselog")
20851    (set_attr "mode" "TI")])
20852
20853 ;; Use xor, but don't show input operands so they aren't live before
20854 ;; this insn.
20855 (define_insn "sse_clrv4sf"
20856   [(set (match_operand:V4SF 0 "register_operand" "=x")
20857         (match_operand:V4SF 1 "const0_operand" "X"))]
20858   "TARGET_SSE"
20859 {
20860   if (get_attr_mode (insn) == MODE_TI)
20861     return "pxor\t{%0, %0|%0, %0}";
20862   else
20863     return "xorps\t{%0, %0|%0, %0}";
20864 }
20865   [(set_attr "type" "sselog")
20866    (set_attr "memory" "none")
20867    (set (attr "mode")
20868         (if_then_else
20869            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20870                          (const_int 0))
20871                      (ne (symbol_ref "TARGET_SSE2")
20872                          (const_int 0)))
20873                 (eq (symbol_ref "optimize_size")
20874                     (const_int 0)))
20875          (const_string "TI")
20876          (const_string "V4SF")))])
20877
20878 ;; Use xor, but don't show input operands so they aren't live before
20879 ;; this insn.
20880 (define_insn "sse_clrv2df"
20881   [(set (match_operand:V2DF 0 "register_operand" "=x")
20882         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20883   "TARGET_SSE2"
20884   "xorpd\t{%0, %0|%0, %0}"
20885   [(set_attr "type" "sselog")
20886    (set_attr "memory" "none")
20887    (set_attr "mode" "V4SF")])
20888
20889 ;; SSE mask-generating compares
20890
20891 (define_insn "maskcmpv4sf3"
20892   [(set (match_operand:V4SI 0 "register_operand" "=x")
20893         (match_operator:V4SI 3 "sse_comparison_operator"
20894                 [(match_operand:V4SF 1 "register_operand" "0")
20895                  (match_operand:V4SF 2 "register_operand" "x")]))]
20896   "TARGET_SSE"
20897   "cmp%D3ps\t{%2, %0|%0, %2}"
20898   [(set_attr "type" "ssecmp")
20899    (set_attr "mode" "V4SF")])
20900
20901 (define_insn "maskncmpv4sf3"
20902   [(set (match_operand:V4SI 0 "register_operand" "=x")
20903         (not:V4SI
20904          (match_operator:V4SI 3 "sse_comparison_operator"
20905                 [(match_operand:V4SF 1 "register_operand" "0")
20906                  (match_operand:V4SF 2 "register_operand" "x")])))]
20907   "TARGET_SSE"
20908 {
20909   if (GET_CODE (operands[3]) == UNORDERED)
20910     return "cmpordps\t{%2, %0|%0, %2}";
20911   else
20912     return "cmpn%D3ps\t{%2, %0|%0, %2}";
20913 }
20914   [(set_attr "type" "ssecmp")
20915    (set_attr "mode" "V4SF")])
20916
20917 (define_insn "vmmaskcmpv4sf3"
20918   [(set (match_operand:V4SI 0 "register_operand" "=x")
20919         (vec_merge:V4SI
20920          (match_operator:V4SI 3 "sse_comparison_operator"
20921                 [(match_operand:V4SF 1 "register_operand" "0")
20922                  (match_operand:V4SF 2 "register_operand" "x")])
20923          (subreg:V4SI (match_dup 1) 0)
20924          (const_int 1)))]
20925   "TARGET_SSE"
20926   "cmp%D3ss\t{%2, %0|%0, %2}"
20927   [(set_attr "type" "ssecmp")
20928    (set_attr "mode" "SF")])
20929
20930 (define_insn "vmmaskncmpv4sf3"
20931   [(set (match_operand:V4SI 0 "register_operand" "=x")
20932         (vec_merge:V4SI
20933          (not:V4SI
20934           (match_operator:V4SI 3 "sse_comparison_operator"
20935                 [(match_operand:V4SF 1 "register_operand" "0")
20936                  (match_operand:V4SF 2 "register_operand" "x")]))
20937          (subreg:V4SI (match_dup 1) 0)
20938          (const_int 1)))]
20939   "TARGET_SSE"
20940 {
20941   if (GET_CODE (operands[3]) == UNORDERED)
20942     return "cmpordss\t{%2, %0|%0, %2}";
20943   else
20944     return "cmpn%D3ss\t{%2, %0|%0, %2}";
20945 }
20946   [(set_attr "type" "ssecmp")
20947    (set_attr "mode" "SF")])
20948
20949 (define_insn "sse_comi"
20950   [(set (reg:CCFP FLAGS_REG)
20951         (compare:CCFP (vec_select:SF
20952                        (match_operand:V4SF 0 "register_operand" "x")
20953                        (parallel [(const_int 0)]))
20954                       (vec_select:SF
20955                        (match_operand:V4SF 1 "register_operand" "x")
20956                        (parallel [(const_int 0)]))))]
20957   "TARGET_SSE"
20958   "comiss\t{%1, %0|%0, %1}"
20959   [(set_attr "type" "ssecomi")
20960    (set_attr "mode" "SF")])
20961
20962 (define_insn "sse_ucomi"
20963   [(set (reg:CCFPU FLAGS_REG)
20964         (compare:CCFPU (vec_select:SF
20965                         (match_operand:V4SF 0 "register_operand" "x")
20966                         (parallel [(const_int 0)]))
20967                        (vec_select:SF
20968                         (match_operand:V4SF 1 "register_operand" "x")
20969                         (parallel [(const_int 0)]))))]
20970   "TARGET_SSE"
20971   "ucomiss\t{%1, %0|%0, %1}"
20972   [(set_attr "type" "ssecomi")
20973    (set_attr "mode" "SF")])
20974
20975
20976 ;; SSE unpack
20977
20978 (define_insn "sse_unpckhps"
20979   [(set (match_operand:V4SF 0 "register_operand" "=x")
20980         (vec_merge:V4SF
20981          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20982                           (parallel [(const_int 2)
20983                                      (const_int 0)
20984                                      (const_int 3)
20985                                      (const_int 1)]))
20986          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20987                           (parallel [(const_int 0)
20988                                      (const_int 2)
20989                                      (const_int 1)
20990                                      (const_int 3)]))
20991          (const_int 5)))]
20992   "TARGET_SSE"
20993   "unpckhps\t{%2, %0|%0, %2}"
20994   [(set_attr "type" "ssecvt")
20995    (set_attr "mode" "V4SF")])
20996
20997 (define_insn "sse_unpcklps"
20998   [(set (match_operand:V4SF 0 "register_operand" "=x")
20999         (vec_merge:V4SF
21000          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21001                           (parallel [(const_int 0)
21002                                      (const_int 2)
21003                                      (const_int 1)
21004                                      (const_int 3)]))
21005          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21006                           (parallel [(const_int 2)
21007                                      (const_int 0)
21008                                      (const_int 3)
21009                                      (const_int 1)]))
21010          (const_int 5)))]
21011   "TARGET_SSE"
21012   "unpcklps\t{%2, %0|%0, %2}"
21013   [(set_attr "type" "ssecvt")
21014    (set_attr "mode" "V4SF")])
21015
21016
21017 ;; SSE min/max
21018
21019 (define_insn "smaxv4sf3"
21020   [(set (match_operand:V4SF 0 "register_operand" "=x")
21021         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21022                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21023   "TARGET_SSE"
21024   "maxps\t{%2, %0|%0, %2}"
21025   [(set_attr "type" "sse")
21026    (set_attr "mode" "V4SF")])
21027
21028 (define_insn "vmsmaxv4sf3"
21029   [(set (match_operand:V4SF 0 "register_operand" "=x")
21030         (vec_merge:V4SF
21031          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21032                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21033          (match_dup 1)
21034          (const_int 1)))]
21035   "TARGET_SSE"
21036   "maxss\t{%2, %0|%0, %2}"
21037   [(set_attr "type" "sse")
21038    (set_attr "mode" "SF")])
21039
21040 (define_insn "sminv4sf3"
21041   [(set (match_operand:V4SF 0 "register_operand" "=x")
21042         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21043                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21044   "TARGET_SSE"
21045   "minps\t{%2, %0|%0, %2}"
21046   [(set_attr "type" "sse")
21047    (set_attr "mode" "V4SF")])
21048
21049 (define_insn "vmsminv4sf3"
21050   [(set (match_operand:V4SF 0 "register_operand" "=x")
21051         (vec_merge:V4SF
21052          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21053                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21054          (match_dup 1)
21055          (const_int 1)))]
21056   "TARGET_SSE"
21057   "minss\t{%2, %0|%0, %2}"
21058   [(set_attr "type" "sse")
21059    (set_attr "mode" "SF")])
21060
21061 ;; SSE <-> integer/MMX conversions
21062
21063 (define_insn "cvtpi2ps"
21064   [(set (match_operand:V4SF 0 "register_operand" "=x")
21065         (vec_merge:V4SF
21066          (match_operand:V4SF 1 "register_operand" "0")
21067          (vec_duplicate:V4SF
21068           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21069          (const_int 12)))]
21070   "TARGET_SSE"
21071   "cvtpi2ps\t{%2, %0|%0, %2}"
21072   [(set_attr "type" "ssecvt")
21073    (set_attr "mode" "V4SF")])
21074
21075 (define_insn "cvtps2pi"
21076   [(set (match_operand:V2SI 0 "register_operand" "=y")
21077         (vec_select:V2SI
21078          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21079          (parallel [(const_int 0) (const_int 1)])))]
21080   "TARGET_SSE"
21081   "cvtps2pi\t{%1, %0|%0, %1}"
21082   [(set_attr "type" "ssecvt")
21083    (set_attr "mode" "V4SF")])
21084
21085 (define_insn "cvttps2pi"
21086   [(set (match_operand:V2SI 0 "register_operand" "=y")
21087         (vec_select:V2SI
21088          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21089                       UNSPEC_FIX)
21090          (parallel [(const_int 0) (const_int 1)])))]
21091   "TARGET_SSE"
21092   "cvttps2pi\t{%1, %0|%0, %1}"
21093   [(set_attr "type" "ssecvt")
21094    (set_attr "mode" "SF")])
21095
21096 (define_insn "cvtsi2ss"
21097   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21098         (vec_merge:V4SF
21099          (match_operand:V4SF 1 "register_operand" "0,0")
21100          (vec_duplicate:V4SF
21101           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21102          (const_int 14)))]
21103   "TARGET_SSE"
21104   "cvtsi2ss\t{%2, %0|%0, %2}"
21105   [(set_attr "type" "sseicvt")
21106    (set_attr "athlon_decode" "vector,double")
21107    (set_attr "mode" "SF")])
21108
21109 (define_insn "cvtsi2ssq"
21110   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21111         (vec_merge:V4SF
21112          (match_operand:V4SF 1 "register_operand" "0,0")
21113          (vec_duplicate:V4SF
21114           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21115          (const_int 14)))]
21116   "TARGET_SSE && TARGET_64BIT"
21117   "cvtsi2ssq\t{%2, %0|%0, %2}"
21118   [(set_attr "type" "sseicvt")
21119    (set_attr "athlon_decode" "vector,double")
21120    (set_attr "mode" "SF")])
21121
21122 (define_insn "cvtss2si"
21123   [(set (match_operand:SI 0 "register_operand" "=r,r")
21124         (vec_select:SI
21125          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21126          (parallel [(const_int 0)])))]
21127   "TARGET_SSE"
21128   "cvtss2si\t{%1, %0|%0, %1}"
21129   [(set_attr "type" "sseicvt")
21130    (set_attr "athlon_decode" "double,vector")
21131    (set_attr "mode" "SI")])
21132
21133 (define_insn "cvtss2siq"
21134   [(set (match_operand:DI 0 "register_operand" "=r,r")
21135         (vec_select:DI
21136          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21137          (parallel [(const_int 0)])))]
21138   "TARGET_SSE"
21139   "cvtss2siq\t{%1, %0|%0, %1}"
21140   [(set_attr "type" "sseicvt")
21141    (set_attr "athlon_decode" "double,vector")
21142    (set_attr "mode" "DI")])
21143
21144 (define_insn "cvttss2si"
21145   [(set (match_operand:SI 0 "register_operand" "=r,r")
21146         (vec_select:SI
21147          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21148                       UNSPEC_FIX)
21149          (parallel [(const_int 0)])))]
21150   "TARGET_SSE"
21151   "cvttss2si\t{%1, %0|%0, %1}"
21152   [(set_attr "type" "sseicvt")
21153    (set_attr "mode" "SF")
21154    (set_attr "athlon_decode" "double,vector")])
21155
21156 (define_insn "cvttss2siq"
21157   [(set (match_operand:DI 0 "register_operand" "=r,r")
21158         (vec_select:DI
21159          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21160                       UNSPEC_FIX)
21161          (parallel [(const_int 0)])))]
21162   "TARGET_SSE && TARGET_64BIT"
21163   "cvttss2siq\t{%1, %0|%0, %1}"
21164   [(set_attr "type" "sseicvt")
21165    (set_attr "mode" "SF")
21166    (set_attr "athlon_decode" "double,vector")])
21167
21168
21169 ;; MMX insns
21170
21171 ;; MMX arithmetic
21172
21173 (define_insn "addv8qi3"
21174   [(set (match_operand:V8QI 0 "register_operand" "=y")
21175         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21176                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21177   "TARGET_MMX"
21178   "paddb\t{%2, %0|%0, %2}"
21179   [(set_attr "type" "mmxadd")
21180    (set_attr "mode" "DI")])
21181
21182 (define_insn "addv4hi3"
21183   [(set (match_operand:V4HI 0 "register_operand" "=y")
21184         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21185                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21186   "TARGET_MMX"
21187   "paddw\t{%2, %0|%0, %2}"
21188   [(set_attr "type" "mmxadd")
21189    (set_attr "mode" "DI")])
21190
21191 (define_insn "addv2si3"
21192   [(set (match_operand:V2SI 0 "register_operand" "=y")
21193         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21194                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21195   "TARGET_MMX"
21196   "paddd\t{%2, %0|%0, %2}"
21197   [(set_attr "type" "mmxadd")
21198    (set_attr "mode" "DI")])
21199
21200 (define_insn "mmx_adddi3"
21201   [(set (match_operand:DI 0 "register_operand" "=y")
21202         (unspec:DI
21203          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21204                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21205          UNSPEC_NOP))]
21206   "TARGET_MMX"
21207   "paddq\t{%2, %0|%0, %2}"
21208   [(set_attr "type" "mmxadd")
21209    (set_attr "mode" "DI")])
21210
21211 (define_insn "ssaddv8qi3"
21212   [(set (match_operand:V8QI 0 "register_operand" "=y")
21213         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21214                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21215   "TARGET_MMX"
21216   "paddsb\t{%2, %0|%0, %2}"
21217   [(set_attr "type" "mmxadd")
21218    (set_attr "mode" "DI")])
21219
21220 (define_insn "ssaddv4hi3"
21221   [(set (match_operand:V4HI 0 "register_operand" "=y")
21222         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21223                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21224   "TARGET_MMX"
21225   "paddsw\t{%2, %0|%0, %2}"
21226   [(set_attr "type" "mmxadd")
21227    (set_attr "mode" "DI")])
21228
21229 (define_insn "usaddv8qi3"
21230   [(set (match_operand:V8QI 0 "register_operand" "=y")
21231         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21232                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21233   "TARGET_MMX"
21234   "paddusb\t{%2, %0|%0, %2}"
21235   [(set_attr "type" "mmxadd")
21236    (set_attr "mode" "DI")])
21237
21238 (define_insn "usaddv4hi3"
21239   [(set (match_operand:V4HI 0 "register_operand" "=y")
21240         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21241                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21242   "TARGET_MMX"
21243   "paddusw\t{%2, %0|%0, %2}"
21244   [(set_attr "type" "mmxadd")
21245    (set_attr "mode" "DI")])
21246
21247 (define_insn "subv8qi3"
21248   [(set (match_operand:V8QI 0 "register_operand" "=y")
21249         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21250                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21251   "TARGET_MMX"
21252   "psubb\t{%2, %0|%0, %2}"
21253   [(set_attr "type" "mmxadd")
21254    (set_attr "mode" "DI")])
21255
21256 (define_insn "subv4hi3"
21257   [(set (match_operand:V4HI 0 "register_operand" "=y")
21258         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21259                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21260   "TARGET_MMX"
21261   "psubw\t{%2, %0|%0, %2}"
21262   [(set_attr "type" "mmxadd")
21263    (set_attr "mode" "DI")])
21264
21265 (define_insn "subv2si3"
21266   [(set (match_operand:V2SI 0 "register_operand" "=y")
21267         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21268                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21269   "TARGET_MMX"
21270   "psubd\t{%2, %0|%0, %2}"
21271   [(set_attr "type" "mmxadd")
21272    (set_attr "mode" "DI")])
21273
21274 (define_insn "mmx_subdi3"
21275   [(set (match_operand:DI 0 "register_operand" "=y")
21276         (unspec:DI
21277          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21278                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21279          UNSPEC_NOP))]
21280   "TARGET_MMX"
21281   "psubq\t{%2, %0|%0, %2}"
21282   [(set_attr "type" "mmxadd")
21283    (set_attr "mode" "DI")])
21284
21285 (define_insn "sssubv8qi3"
21286   [(set (match_operand:V8QI 0 "register_operand" "=y")
21287         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21288                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21289   "TARGET_MMX"
21290   "psubsb\t{%2, %0|%0, %2}"
21291   [(set_attr "type" "mmxadd")
21292    (set_attr "mode" "DI")])
21293
21294 (define_insn "sssubv4hi3"
21295   [(set (match_operand:V4HI 0 "register_operand" "=y")
21296         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21297                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21298   "TARGET_MMX"
21299   "psubsw\t{%2, %0|%0, %2}"
21300   [(set_attr "type" "mmxadd")
21301    (set_attr "mode" "DI")])
21302
21303 (define_insn "ussubv8qi3"
21304   [(set (match_operand:V8QI 0 "register_operand" "=y")
21305         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21306                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21307   "TARGET_MMX"
21308   "psubusb\t{%2, %0|%0, %2}"
21309   [(set_attr "type" "mmxadd")
21310    (set_attr "mode" "DI")])
21311
21312 (define_insn "ussubv4hi3"
21313   [(set (match_operand:V4HI 0 "register_operand" "=y")
21314         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21315                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21316   "TARGET_MMX"
21317   "psubusw\t{%2, %0|%0, %2}"
21318   [(set_attr "type" "mmxadd")
21319    (set_attr "mode" "DI")])
21320
21321 (define_insn "mulv4hi3"
21322   [(set (match_operand:V4HI 0 "register_operand" "=y")
21323         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21324                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21325   "TARGET_MMX"
21326   "pmullw\t{%2, %0|%0, %2}"
21327   [(set_attr "type" "mmxmul")
21328    (set_attr "mode" "DI")])
21329
21330 (define_insn "smulv4hi3_highpart"
21331   [(set (match_operand:V4HI 0 "register_operand" "=y")
21332         (truncate:V4HI
21333          (lshiftrt:V4SI
21334           (mult:V4SI (sign_extend:V4SI
21335                       (match_operand:V4HI 1 "register_operand" "0"))
21336                      (sign_extend:V4SI
21337                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21338           (const_int 16))))]
21339   "TARGET_MMX"
21340   "pmulhw\t{%2, %0|%0, %2}"
21341   [(set_attr "type" "mmxmul")
21342    (set_attr "mode" "DI")])
21343
21344 (define_insn "umulv4hi3_highpart"
21345   [(set (match_operand:V4HI 0 "register_operand" "=y")
21346         (truncate:V4HI
21347          (lshiftrt:V4SI
21348           (mult:V4SI (zero_extend:V4SI
21349                       (match_operand:V4HI 1 "register_operand" "0"))
21350                      (zero_extend:V4SI
21351                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21352           (const_int 16))))]
21353   "TARGET_SSE || TARGET_3DNOW_A"
21354   "pmulhuw\t{%2, %0|%0, %2}"
21355   [(set_attr "type" "mmxmul")
21356    (set_attr "mode" "DI")])
21357
21358 (define_insn "mmx_pmaddwd"
21359   [(set (match_operand:V2SI 0 "register_operand" "=y")
21360         (plus:V2SI
21361          (mult:V2SI
21362           (sign_extend:V2SI
21363            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21364                             (parallel [(const_int 0) (const_int 2)])))
21365           (sign_extend:V2SI
21366            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21367                             (parallel [(const_int 0) (const_int 2)]))))
21368          (mult:V2SI
21369           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21370                                              (parallel [(const_int 1)
21371                                                         (const_int 3)])))
21372           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21373                                              (parallel [(const_int 1)
21374                                                         (const_int 3)]))))))]
21375   "TARGET_MMX"
21376   "pmaddwd\t{%2, %0|%0, %2}"
21377   [(set_attr "type" "mmxmul")
21378    (set_attr "mode" "DI")])
21379
21380
21381 ;; MMX logical operations
21382 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21383 ;; normal code that also wants to use the FPU from getting broken.
21384 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21385 (define_insn "mmx_iordi3"
21386   [(set (match_operand:DI 0 "register_operand" "=y")
21387         (unspec:DI
21388          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21389                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21390          UNSPEC_NOP))]
21391   "TARGET_MMX"
21392   "por\t{%2, %0|%0, %2}"
21393   [(set_attr "type" "mmxadd")
21394    (set_attr "mode" "DI")])
21395
21396 (define_insn "mmx_xordi3"
21397   [(set (match_operand:DI 0 "register_operand" "=y")
21398         (unspec:DI
21399          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21400                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21401          UNSPEC_NOP))]
21402   "TARGET_MMX"
21403   "pxor\t{%2, %0|%0, %2}"
21404   [(set_attr "type" "mmxadd")
21405    (set_attr "mode" "DI")
21406    (set_attr "memory" "none")])
21407
21408 ;; Same as pxor, but don't show input operands so that we don't think
21409 ;; they are live.
21410 (define_insn "mmx_clrdi"
21411   [(set (match_operand:DI 0 "register_operand" "=y")
21412         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21413   "TARGET_MMX"
21414   "pxor\t{%0, %0|%0, %0}"
21415   [(set_attr "type" "mmxadd")
21416    (set_attr "mode" "DI")
21417    (set_attr "memory" "none")])
21418
21419 (define_insn "mmx_anddi3"
21420   [(set (match_operand:DI 0 "register_operand" "=y")
21421         (unspec:DI
21422          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21423                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21424          UNSPEC_NOP))]
21425   "TARGET_MMX"
21426   "pand\t{%2, %0|%0, %2}"
21427   [(set_attr "type" "mmxadd")
21428    (set_attr "mode" "DI")])
21429
21430 (define_insn "mmx_nanddi3"
21431   [(set (match_operand:DI 0 "register_operand" "=y")
21432         (unspec:DI
21433          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21434                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21435          UNSPEC_NOP))]
21436   "TARGET_MMX"
21437   "pandn\t{%2, %0|%0, %2}"
21438   [(set_attr "type" "mmxadd")
21439    (set_attr "mode" "DI")])
21440
21441
21442 ;; MMX unsigned averages/sum of absolute differences
21443
21444 (define_insn "mmx_uavgv8qi3"
21445   [(set (match_operand:V8QI 0 "register_operand" "=y")
21446         (ashiftrt:V8QI
21447          (plus:V8QI (plus:V8QI
21448                      (match_operand:V8QI 1 "register_operand" "0")
21449                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21450                     (const_vector:V8QI [(const_int 1)
21451                                         (const_int 1)
21452                                         (const_int 1)
21453                                         (const_int 1)
21454                                         (const_int 1)
21455                                         (const_int 1)
21456                                         (const_int 1)
21457                                         (const_int 1)]))
21458          (const_int 1)))]
21459   "TARGET_SSE || TARGET_3DNOW_A"
21460   "pavgb\t{%2, %0|%0, %2}"
21461   [(set_attr "type" "mmxshft")
21462    (set_attr "mode" "DI")])
21463
21464 (define_insn "mmx_uavgv4hi3"
21465   [(set (match_operand:V4HI 0 "register_operand" "=y")
21466         (ashiftrt:V4HI
21467          (plus:V4HI (plus:V4HI
21468                      (match_operand:V4HI 1 "register_operand" "0")
21469                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21470                     (const_vector:V4HI [(const_int 1)
21471                                         (const_int 1)
21472                                         (const_int 1)
21473                                         (const_int 1)]))
21474          (const_int 1)))]
21475   "TARGET_SSE || TARGET_3DNOW_A"
21476   "pavgw\t{%2, %0|%0, %2}"
21477   [(set_attr "type" "mmxshft")
21478    (set_attr "mode" "DI")])
21479
21480 (define_insn "mmx_psadbw"
21481   [(set (match_operand:DI 0 "register_operand" "=y")
21482         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21483                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21484                    UNSPEC_PSADBW))]
21485   "TARGET_SSE || TARGET_3DNOW_A"
21486   "psadbw\t{%2, %0|%0, %2}"
21487   [(set_attr "type" "mmxshft")
21488    (set_attr "mode" "DI")])
21489
21490
21491 ;; MMX insert/extract/shuffle
21492
21493 (define_insn "mmx_pinsrw"
21494   [(set (match_operand:V4HI 0 "register_operand" "=y")
21495         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21496                         (vec_duplicate:V4HI
21497                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21498                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21499   "TARGET_SSE || TARGET_3DNOW_A"
21500   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21501   [(set_attr "type" "mmxcvt")
21502    (set_attr "mode" "DI")])
21503
21504 (define_insn "mmx_pextrw"
21505   [(set (match_operand:SI 0 "register_operand" "=r")
21506         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21507                                        (parallel
21508                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21509   "TARGET_SSE || TARGET_3DNOW_A"
21510   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21511   [(set_attr "type" "mmxcvt")
21512    (set_attr "mode" "DI")])
21513
21514 (define_insn "mmx_pshufw"
21515   [(set (match_operand:V4HI 0 "register_operand" "=y")
21516         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21517                       (match_operand:SI 2 "immediate_operand" "i")]
21518                      UNSPEC_SHUFFLE))]
21519   "TARGET_SSE || TARGET_3DNOW_A"
21520   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21521   [(set_attr "type" "mmxcvt")
21522    (set_attr "mode" "DI")])
21523
21524
21525 ;; MMX mask-generating comparisons
21526
21527 (define_insn "eqv8qi3"
21528   [(set (match_operand:V8QI 0 "register_operand" "=y")
21529         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21530                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21531   "TARGET_MMX"
21532   "pcmpeqb\t{%2, %0|%0, %2}"
21533   [(set_attr "type" "mmxcmp")
21534    (set_attr "mode" "DI")])
21535
21536 (define_insn "eqv4hi3"
21537   [(set (match_operand:V4HI 0 "register_operand" "=y")
21538         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21539                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21540   "TARGET_MMX"
21541   "pcmpeqw\t{%2, %0|%0, %2}"
21542   [(set_attr "type" "mmxcmp")
21543    (set_attr "mode" "DI")])
21544
21545 (define_insn "eqv2si3"
21546   [(set (match_operand:V2SI 0 "register_operand" "=y")
21547         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21548                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21549   "TARGET_MMX"
21550   "pcmpeqd\t{%2, %0|%0, %2}"
21551   [(set_attr "type" "mmxcmp")
21552    (set_attr "mode" "DI")])
21553
21554 (define_insn "gtv8qi3"
21555   [(set (match_operand:V8QI 0 "register_operand" "=y")
21556         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21557                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21558   "TARGET_MMX"
21559   "pcmpgtb\t{%2, %0|%0, %2}"
21560   [(set_attr "type" "mmxcmp")
21561    (set_attr "mode" "DI")])
21562
21563 (define_insn "gtv4hi3"
21564   [(set (match_operand:V4HI 0 "register_operand" "=y")
21565         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21566                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21567   "TARGET_MMX"
21568   "pcmpgtw\t{%2, %0|%0, %2}"
21569   [(set_attr "type" "mmxcmp")
21570    (set_attr "mode" "DI")])
21571
21572 (define_insn "gtv2si3"
21573   [(set (match_operand:V2SI 0 "register_operand" "=y")
21574         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21575                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21576   "TARGET_MMX"
21577   "pcmpgtd\t{%2, %0|%0, %2}"
21578   [(set_attr "type" "mmxcmp")
21579    (set_attr "mode" "DI")])
21580
21581
21582 ;; MMX max/min insns
21583
21584 (define_insn "umaxv8qi3"
21585   [(set (match_operand:V8QI 0 "register_operand" "=y")
21586         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21587                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21588   "TARGET_SSE || TARGET_3DNOW_A"
21589   "pmaxub\t{%2, %0|%0, %2}"
21590   [(set_attr "type" "mmxadd")
21591    (set_attr "mode" "DI")])
21592
21593 (define_insn "smaxv4hi3"
21594   [(set (match_operand:V4HI 0 "register_operand" "=y")
21595         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21596                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21597   "TARGET_SSE || TARGET_3DNOW_A"
21598   "pmaxsw\t{%2, %0|%0, %2}"
21599   [(set_attr "type" "mmxadd")
21600    (set_attr "mode" "DI")])
21601
21602 (define_insn "uminv8qi3"
21603   [(set (match_operand:V8QI 0 "register_operand" "=y")
21604         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21605                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21606   "TARGET_SSE || TARGET_3DNOW_A"
21607   "pminub\t{%2, %0|%0, %2}"
21608   [(set_attr "type" "mmxadd")
21609    (set_attr "mode" "DI")])
21610
21611 (define_insn "sminv4hi3"
21612   [(set (match_operand:V4HI 0 "register_operand" "=y")
21613         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21614                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21615   "TARGET_SSE || TARGET_3DNOW_A"
21616   "pminsw\t{%2, %0|%0, %2}"
21617   [(set_attr "type" "mmxadd")
21618    (set_attr "mode" "DI")])
21619
21620
21621 ;; MMX shifts
21622
21623 (define_insn "ashrv4hi3"
21624   [(set (match_operand:V4HI 0 "register_operand" "=y")
21625         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21626                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21627   "TARGET_MMX"
21628   "psraw\t{%2, %0|%0, %2}"
21629   [(set_attr "type" "mmxshft")
21630    (set_attr "mode" "DI")])
21631
21632 (define_insn "ashrv2si3"
21633   [(set (match_operand:V2SI 0 "register_operand" "=y")
21634         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21635                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21636   "TARGET_MMX"
21637   "psrad\t{%2, %0|%0, %2}"
21638   [(set_attr "type" "mmxshft")
21639    (set_attr "mode" "DI")])
21640
21641 (define_insn "lshrv4hi3"
21642   [(set (match_operand:V4HI 0 "register_operand" "=y")
21643         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21644                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21645   "TARGET_MMX"
21646   "psrlw\t{%2, %0|%0, %2}"
21647   [(set_attr "type" "mmxshft")
21648    (set_attr "mode" "DI")])
21649
21650 (define_insn "lshrv2si3"
21651   [(set (match_operand:V2SI 0 "register_operand" "=y")
21652         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21653                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21654   "TARGET_MMX"
21655   "psrld\t{%2, %0|%0, %2}"
21656   [(set_attr "type" "mmxshft")
21657    (set_attr "mode" "DI")])
21658
21659 ;; See logical MMX insns.
21660 (define_insn "mmx_lshrdi3"
21661   [(set (match_operand:DI 0 "register_operand" "=y")
21662         (unspec:DI
21663           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21664                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21665           UNSPEC_NOP))]
21666   "TARGET_MMX"
21667   "psrlq\t{%2, %0|%0, %2}"
21668   [(set_attr "type" "mmxshft")
21669    (set_attr "mode" "DI")])
21670
21671 (define_insn "ashlv4hi3"
21672   [(set (match_operand:V4HI 0 "register_operand" "=y")
21673         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21674                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21675   "TARGET_MMX"
21676   "psllw\t{%2, %0|%0, %2}"
21677   [(set_attr "type" "mmxshft")
21678    (set_attr "mode" "DI")])
21679
21680 (define_insn "ashlv2si3"
21681   [(set (match_operand:V2SI 0 "register_operand" "=y")
21682         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21683                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21684   "TARGET_MMX"
21685   "pslld\t{%2, %0|%0, %2}"
21686   [(set_attr "type" "mmxshft")
21687    (set_attr "mode" "DI")])
21688
21689 ;; See logical MMX insns.
21690 (define_insn "mmx_ashldi3"
21691   [(set (match_operand:DI 0 "register_operand" "=y")
21692         (unspec:DI
21693          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21694                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21695          UNSPEC_NOP))]
21696   "TARGET_MMX"
21697   "psllq\t{%2, %0|%0, %2}"
21698   [(set_attr "type" "mmxshft")
21699    (set_attr "mode" "DI")])
21700
21701
21702 ;; MMX pack/unpack insns.
21703
21704 (define_insn "mmx_packsswb"
21705   [(set (match_operand:V8QI 0 "register_operand" "=y")
21706         (vec_concat:V8QI
21707          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21708          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21709   "TARGET_MMX"
21710   "packsswb\t{%2, %0|%0, %2}"
21711   [(set_attr "type" "mmxshft")
21712    (set_attr "mode" "DI")])
21713
21714 (define_insn "mmx_packssdw"
21715   [(set (match_operand:V4HI 0 "register_operand" "=y")
21716         (vec_concat:V4HI
21717          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21718          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21719   "TARGET_MMX"
21720   "packssdw\t{%2, %0|%0, %2}"
21721   [(set_attr "type" "mmxshft")
21722    (set_attr "mode" "DI")])
21723
21724 (define_insn "mmx_packuswb"
21725   [(set (match_operand:V8QI 0 "register_operand" "=y")
21726         (vec_concat:V8QI
21727          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21728          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21729   "TARGET_MMX"
21730   "packuswb\t{%2, %0|%0, %2}"
21731   [(set_attr "type" "mmxshft")
21732    (set_attr "mode" "DI")])
21733
21734 (define_insn "mmx_punpckhbw"
21735   [(set (match_operand:V8QI 0 "register_operand" "=y")
21736         (vec_merge:V8QI
21737          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21738                           (parallel [(const_int 4)
21739                                      (const_int 0)
21740                                      (const_int 5)
21741                                      (const_int 1)
21742                                      (const_int 6)
21743                                      (const_int 2)
21744                                      (const_int 7)
21745                                      (const_int 3)]))
21746          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21747                           (parallel [(const_int 0)
21748                                      (const_int 4)
21749                                      (const_int 1)
21750                                      (const_int 5)
21751                                      (const_int 2)
21752                                      (const_int 6)
21753                                      (const_int 3)
21754                                      (const_int 7)]))
21755          (const_int 85)))]
21756   "TARGET_MMX"
21757   "punpckhbw\t{%2, %0|%0, %2}"
21758   [(set_attr "type" "mmxcvt")
21759    (set_attr "mode" "DI")])
21760
21761 (define_insn "mmx_punpckhwd"
21762   [(set (match_operand:V4HI 0 "register_operand" "=y")
21763         (vec_merge:V4HI
21764          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21765                           (parallel [(const_int 0)
21766                                      (const_int 2)
21767                                      (const_int 1)
21768                                      (const_int 3)]))
21769          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21770                           (parallel [(const_int 2)
21771                                      (const_int 0)
21772                                      (const_int 3)
21773                                      (const_int 1)]))
21774          (const_int 5)))]
21775   "TARGET_MMX"
21776   "punpckhwd\t{%2, %0|%0, %2}"
21777   [(set_attr "type" "mmxcvt")
21778    (set_attr "mode" "DI")])
21779
21780 (define_insn "mmx_punpckhdq"
21781   [(set (match_operand:V2SI 0 "register_operand" "=y")
21782         (vec_merge:V2SI
21783          (match_operand:V2SI 1 "register_operand" "0")
21784          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21785                           (parallel [(const_int 1)
21786                                      (const_int 0)]))
21787          (const_int 1)))]
21788   "TARGET_MMX"
21789   "punpckhdq\t{%2, %0|%0, %2}"
21790   [(set_attr "type" "mmxcvt")
21791    (set_attr "mode" "DI")])
21792
21793 (define_insn "mmx_punpcklbw"
21794   [(set (match_operand:V8QI 0 "register_operand" "=y")
21795         (vec_merge:V8QI
21796          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21797                           (parallel [(const_int 0)
21798                                      (const_int 4)
21799                                      (const_int 1)
21800                                      (const_int 5)
21801                                      (const_int 2)
21802                                      (const_int 6)
21803                                      (const_int 3)
21804                                      (const_int 7)]))
21805          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21806                           (parallel [(const_int 4)
21807                                      (const_int 0)
21808                                      (const_int 5)
21809                                      (const_int 1)
21810                                      (const_int 6)
21811                                      (const_int 2)
21812                                      (const_int 7)
21813                                      (const_int 3)]))
21814          (const_int 85)))]
21815   "TARGET_MMX"
21816   "punpcklbw\t{%2, %0|%0, %2}"
21817   [(set_attr "type" "mmxcvt")
21818    (set_attr "mode" "DI")])
21819
21820 (define_insn "mmx_punpcklwd"
21821   [(set (match_operand:V4HI 0 "register_operand" "=y")
21822         (vec_merge:V4HI
21823          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21824                           (parallel [(const_int 2)
21825                                      (const_int 0)
21826                                      (const_int 3)
21827                                      (const_int 1)]))
21828          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21829                           (parallel [(const_int 0)
21830                                      (const_int 2)
21831                                      (const_int 1)
21832                                      (const_int 3)]))
21833          (const_int 5)))]
21834   "TARGET_MMX"
21835   "punpcklwd\t{%2, %0|%0, %2}"
21836   [(set_attr "type" "mmxcvt")
21837    (set_attr "mode" "DI")])
21838
21839 (define_insn "mmx_punpckldq"
21840   [(set (match_operand:V2SI 0 "register_operand" "=y")
21841         (vec_merge:V2SI
21842          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21843                            (parallel [(const_int 1)
21844                                       (const_int 0)]))
21845          (match_operand:V2SI 2 "register_operand" "y")
21846          (const_int 1)))]
21847   "TARGET_MMX"
21848   "punpckldq\t{%2, %0|%0, %2}"
21849   [(set_attr "type" "mmxcvt")
21850    (set_attr "mode" "DI")])
21851
21852
21853 ;; Miscellaneous stuff
21854
21855 (define_insn "emms"
21856   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21857    (clobber (reg:XF 8))
21858    (clobber (reg:XF 9))
21859    (clobber (reg:XF 10))
21860    (clobber (reg:XF 11))
21861    (clobber (reg:XF 12))
21862    (clobber (reg:XF 13))
21863    (clobber (reg:XF 14))
21864    (clobber (reg:XF 15))
21865    (clobber (reg:DI 29))
21866    (clobber (reg:DI 30))
21867    (clobber (reg:DI 31))
21868    (clobber (reg:DI 32))
21869    (clobber (reg:DI 33))
21870    (clobber (reg:DI 34))
21871    (clobber (reg:DI 35))
21872    (clobber (reg:DI 36))]
21873   "TARGET_MMX"
21874   "emms"
21875   [(set_attr "type" "mmx")
21876    (set_attr "memory" "unknown")])
21877
21878 (define_insn "ldmxcsr"
21879   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21880                     UNSPECV_LDMXCSR)]
21881   "TARGET_SSE"
21882   "ldmxcsr\t%0"
21883   [(set_attr "type" "sse")
21884    (set_attr "memory" "load")])
21885
21886 (define_insn "stmxcsr"
21887   [(set (match_operand:SI 0 "memory_operand" "=m")
21888         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21889   "TARGET_SSE"
21890   "stmxcsr\t%0"
21891   [(set_attr "type" "sse")
21892    (set_attr "memory" "store")])
21893
21894 (define_expand "sfence"
21895   [(set (match_dup 0)
21896         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21897   "TARGET_SSE || TARGET_3DNOW_A"
21898 {
21899   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21900   MEM_VOLATILE_P (operands[0]) = 1;
21901 })
21902
21903 (define_insn "*sfence_insn"
21904   [(set (match_operand:BLK 0 "" "")
21905         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21906   "TARGET_SSE || TARGET_3DNOW_A"
21907   "sfence"
21908   [(set_attr "type" "sse")
21909    (set_attr "memory" "unknown")])
21910
21911 (define_expand "sse_prologue_save"
21912   [(parallel [(set (match_operand:BLK 0 "" "")
21913                    (unspec:BLK [(reg:DI 21)
21914                                 (reg:DI 22)
21915                                 (reg:DI 23)
21916                                 (reg:DI 24)
21917                                 (reg:DI 25)
21918                                 (reg:DI 26)
21919                                 (reg:DI 27)
21920                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21921               (use (match_operand:DI 1 "register_operand" ""))
21922               (use (match_operand:DI 2 "immediate_operand" ""))
21923               (use (label_ref:DI (match_operand 3 "" "")))])]
21924   "TARGET_64BIT"
21925   "")
21926
21927 (define_insn "*sse_prologue_save_insn"
21928   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21929                           (match_operand:DI 4 "const_int_operand" "n")))
21930         (unspec:BLK [(reg:DI 21)
21931                      (reg:DI 22)
21932                      (reg:DI 23)
21933                      (reg:DI 24)
21934                      (reg:DI 25)
21935                      (reg:DI 26)
21936                      (reg:DI 27)
21937                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21938    (use (match_operand:DI 1 "register_operand" "r"))
21939    (use (match_operand:DI 2 "const_int_operand" "i"))
21940    (use (label_ref:DI (match_operand 3 "" "X")))]
21941   "TARGET_64BIT
21942    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21943    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21944   "*
21945 {
21946   int i;
21947   operands[0] = gen_rtx_MEM (Pmode,
21948                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21949   output_asm_insn (\"jmp\\t%A1\", operands);
21950   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21951     {
21952       operands[4] = adjust_address (operands[0], DImode, i*16);
21953       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21954       PUT_MODE (operands[4], TImode);
21955       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21956         output_asm_insn (\"rex\", operands);
21957       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21958     }
21959   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21960                              CODE_LABEL_NUMBER (operands[3]));
21961   RET;
21962 }
21963   "
21964   [(set_attr "type" "other")
21965    (set_attr "length_immediate" "0")
21966    (set_attr "length_address" "0")
21967    (set_attr "length" "135")
21968    (set_attr "memory" "store")
21969    (set_attr "modrm" "0")
21970    (set_attr "mode" "DI")])
21971
21972 ;; 3Dnow! instructions
21973
21974 (define_insn "addv2sf3"
21975   [(set (match_operand:V2SF 0 "register_operand" "=y")
21976         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21977                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21978   "TARGET_3DNOW"
21979   "pfadd\\t{%2, %0|%0, %2}"
21980   [(set_attr "type" "mmxadd")
21981    (set_attr "mode" "V2SF")])
21982
21983 (define_insn "subv2sf3"
21984   [(set (match_operand:V2SF 0 "register_operand" "=y")
21985         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21986                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21987   "TARGET_3DNOW"
21988   "pfsub\\t{%2, %0|%0, %2}"
21989   [(set_attr "type" "mmxadd")
21990    (set_attr "mode" "V2SF")])
21991
21992 (define_insn "subrv2sf3"
21993   [(set (match_operand:V2SF 0 "register_operand" "=y")
21994         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21995                     (match_operand:V2SF 1 "register_operand" "0")))]
21996   "TARGET_3DNOW"
21997   "pfsubr\\t{%2, %0|%0, %2}"
21998   [(set_attr "type" "mmxadd")
21999    (set_attr "mode" "V2SF")])
22000
22001 (define_insn "gtv2sf3"
22002   [(set (match_operand:V2SI 0 "register_operand" "=y")
22003         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22004                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22005  "TARGET_3DNOW"
22006   "pfcmpgt\\t{%2, %0|%0, %2}"
22007   [(set_attr "type" "mmxcmp")
22008    (set_attr "mode" "V2SF")])
22009
22010 (define_insn "gev2sf3"
22011   [(set (match_operand:V2SI 0 "register_operand" "=y")
22012         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22013                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22014   "TARGET_3DNOW"
22015   "pfcmpge\\t{%2, %0|%0, %2}"
22016   [(set_attr "type" "mmxcmp")
22017    (set_attr "mode" "V2SF")])
22018
22019 (define_insn "eqv2sf3"
22020   [(set (match_operand:V2SI 0 "register_operand" "=y")
22021         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22022                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22023   "TARGET_3DNOW"
22024   "pfcmpeq\\t{%2, %0|%0, %2}"
22025   [(set_attr "type" "mmxcmp")
22026    (set_attr "mode" "V2SF")])
22027
22028 (define_insn "pfmaxv2sf3"
22029   [(set (match_operand:V2SF 0 "register_operand" "=y")
22030         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22031                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22032   "TARGET_3DNOW"
22033   "pfmax\\t{%2, %0|%0, %2}"
22034   [(set_attr "type" "mmxadd")
22035    (set_attr "mode" "V2SF")])
22036
22037 (define_insn "pfminv2sf3"
22038   [(set (match_operand:V2SF 0 "register_operand" "=y")
22039         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22040                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22041   "TARGET_3DNOW"
22042   "pfmin\\t{%2, %0|%0, %2}"
22043   [(set_attr "type" "mmxadd")
22044    (set_attr "mode" "V2SF")])
22045
22046 (define_insn "mulv2sf3"
22047   [(set (match_operand:V2SF 0 "register_operand" "=y")
22048         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22049                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22050   "TARGET_3DNOW"
22051   "pfmul\\t{%2, %0|%0, %2}"
22052   [(set_attr "type" "mmxmul")
22053    (set_attr "mode" "V2SF")])
22054
22055 (define_insn "femms"
22056   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22057    (clobber (reg:XF 8))
22058    (clobber (reg:XF 9))
22059    (clobber (reg:XF 10))
22060    (clobber (reg:XF 11))
22061    (clobber (reg:XF 12))
22062    (clobber (reg:XF 13))
22063    (clobber (reg:XF 14))
22064    (clobber (reg:XF 15))
22065    (clobber (reg:DI 29))
22066    (clobber (reg:DI 30))
22067    (clobber (reg:DI 31))
22068    (clobber (reg:DI 32))
22069    (clobber (reg:DI 33))
22070    (clobber (reg:DI 34))
22071    (clobber (reg:DI 35))
22072    (clobber (reg:DI 36))]
22073   "TARGET_3DNOW"
22074   "femms"
22075   [(set_attr "type" "mmx")
22076    (set_attr "memory" "none")]) 
22077
22078 (define_insn "pf2id"
22079   [(set (match_operand:V2SI 0 "register_operand" "=y")
22080         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22081   "TARGET_3DNOW"
22082   "pf2id\\t{%1, %0|%0, %1}"
22083   [(set_attr "type" "mmxcvt")
22084    (set_attr "mode" "V2SF")])
22085
22086 (define_insn "pf2iw"
22087   [(set (match_operand:V2SI 0 "register_operand" "=y")
22088         (sign_extend:V2SI
22089            (ss_truncate:V2HI
22090               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22091   "TARGET_3DNOW_A"
22092   "pf2iw\\t{%1, %0|%0, %1}"
22093   [(set_attr "type" "mmxcvt")
22094    (set_attr "mode" "V2SF")])
22095
22096 (define_insn "pfacc"
22097   [(set (match_operand:V2SF 0 "register_operand" "=y")
22098         (vec_concat:V2SF
22099            (plus:SF
22100               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22101                              (parallel [(const_int  0)]))
22102               (vec_select:SF (match_dup 1)
22103                              (parallel [(const_int 1)])))
22104            (plus:SF
22105               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22106                              (parallel [(const_int  0)]))
22107               (vec_select:SF (match_dup 2)
22108                              (parallel [(const_int 1)])))))]
22109   "TARGET_3DNOW"
22110   "pfacc\\t{%2, %0|%0, %2}"
22111   [(set_attr "type" "mmxadd")
22112    (set_attr "mode" "V2SF")])
22113
22114 (define_insn "pfnacc"
22115   [(set (match_operand:V2SF 0 "register_operand" "=y")
22116         (vec_concat:V2SF
22117            (minus:SF
22118               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22119                              (parallel [(const_int 0)]))
22120               (vec_select:SF (match_dup 1)
22121                              (parallel [(const_int 1)])))
22122            (minus:SF
22123               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22124                              (parallel [(const_int  0)]))
22125               (vec_select:SF (match_dup 2)
22126                              (parallel [(const_int 1)])))))]
22127   "TARGET_3DNOW_A"
22128   "pfnacc\\t{%2, %0|%0, %2}"
22129   [(set_attr "type" "mmxadd")
22130    (set_attr "mode" "V2SF")])
22131
22132 (define_insn "pfpnacc"
22133   [(set (match_operand:V2SF 0 "register_operand" "=y")
22134         (vec_concat:V2SF
22135            (minus:SF
22136               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22137                              (parallel [(const_int 0)]))
22138               (vec_select:SF (match_dup 1)
22139                              (parallel [(const_int 1)])))
22140            (plus:SF
22141               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22142                              (parallel [(const_int 0)]))
22143               (vec_select:SF (match_dup 2)
22144                              (parallel [(const_int 1)])))))]
22145   "TARGET_3DNOW_A"
22146   "pfpnacc\\t{%2, %0|%0, %2}"
22147   [(set_attr "type" "mmxadd")
22148    (set_attr "mode" "V2SF")])
22149
22150 (define_insn "pi2fw"
22151   [(set (match_operand:V2SF 0 "register_operand" "=y")
22152         (float:V2SF
22153            (vec_concat:V2SI
22154               (sign_extend:SI
22155                  (truncate:HI
22156                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22157                                    (parallel [(const_int 0)]))))
22158               (sign_extend:SI
22159                  (truncate:HI
22160                     (vec_select:SI (match_dup 1)
22161                                    (parallel [(const_int  1)])))))))]
22162   "TARGET_3DNOW_A"
22163   "pi2fw\\t{%1, %0|%0, %1}"
22164   [(set_attr "type" "mmxcvt")
22165    (set_attr "mode" "V2SF")])
22166
22167 (define_insn "floatv2si2"
22168   [(set (match_operand:V2SF 0 "register_operand" "=y")
22169         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22170   "TARGET_3DNOW"
22171   "pi2fd\\t{%1, %0|%0, %1}"
22172   [(set_attr "type" "mmxcvt")
22173    (set_attr "mode" "V2SF")])
22174
22175 ;; This insn is identical to pavgb in operation, but the opcode is
22176 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22177
22178 (define_insn "pavgusb"
22179  [(set (match_operand:V8QI 0 "register_operand" "=y")
22180        (unspec:V8QI
22181           [(match_operand:V8QI 1 "register_operand" "0")
22182            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22183           UNSPEC_PAVGUSB))]
22184   "TARGET_3DNOW"
22185   "pavgusb\\t{%2, %0|%0, %2}"
22186   [(set_attr "type" "mmxshft")
22187    (set_attr "mode" "TI")])
22188
22189 ;; 3DNow reciprocal and sqrt
22190  
22191 (define_insn "pfrcpv2sf2"
22192   [(set (match_operand:V2SF 0 "register_operand" "=y")
22193         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22194         UNSPEC_PFRCP))]
22195   "TARGET_3DNOW"
22196   "pfrcp\\t{%1, %0|%0, %1}"
22197   [(set_attr "type" "mmx")
22198    (set_attr "mode" "TI")])
22199
22200 (define_insn "pfrcpit1v2sf3"
22201   [(set (match_operand:V2SF 0 "register_operand" "=y")
22202         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22203                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22204                      UNSPEC_PFRCPIT1))]
22205   "TARGET_3DNOW"
22206   "pfrcpit1\\t{%2, %0|%0, %2}"
22207   [(set_attr "type" "mmx")
22208    (set_attr "mode" "TI")])
22209
22210 (define_insn "pfrcpit2v2sf3"
22211   [(set (match_operand:V2SF 0 "register_operand" "=y")
22212         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22213                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22214                      UNSPEC_PFRCPIT2))]
22215   "TARGET_3DNOW"
22216   "pfrcpit2\\t{%2, %0|%0, %2}"
22217   [(set_attr "type" "mmx")
22218    (set_attr "mode" "TI")])
22219
22220 (define_insn "pfrsqrtv2sf2"
22221   [(set (match_operand:V2SF 0 "register_operand" "=y")
22222         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22223                      UNSPEC_PFRSQRT))]
22224   "TARGET_3DNOW"
22225   "pfrsqrt\\t{%1, %0|%0, %1}"
22226   [(set_attr "type" "mmx")
22227    (set_attr "mode" "TI")])
22228                 
22229 (define_insn "pfrsqit1v2sf3"
22230   [(set (match_operand:V2SF 0 "register_operand" "=y")
22231         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22232                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22233                      UNSPEC_PFRSQIT1))]
22234   "TARGET_3DNOW"
22235   "pfrsqit1\\t{%2, %0|%0, %2}"
22236   [(set_attr "type" "mmx")
22237    (set_attr "mode" "TI")])
22238
22239 (define_insn "pmulhrwv4hi3"
22240   [(set (match_operand:V4HI 0 "register_operand" "=y")
22241         (truncate:V4HI
22242            (lshiftrt:V4SI
22243               (plus:V4SI
22244                  (mult:V4SI
22245                     (sign_extend:V4SI
22246                        (match_operand:V4HI 1 "register_operand" "0"))
22247                     (sign_extend:V4SI
22248                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22249                  (const_vector:V4SI [(const_int 32768)
22250                                      (const_int 32768)
22251                                      (const_int 32768)
22252                                      (const_int 32768)]))
22253               (const_int 16))))]
22254   "TARGET_3DNOW"
22255   "pmulhrw\\t{%2, %0|%0, %2}"
22256   [(set_attr "type" "mmxmul")
22257    (set_attr "mode" "TI")])
22258
22259 (define_insn "pswapdv2si2"
22260   [(set (match_operand:V2SI 0 "register_operand" "=y")
22261         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22262                          (parallel [(const_int 1) (const_int 0)])))]
22263   "TARGET_3DNOW_A"
22264   "pswapd\\t{%1, %0|%0, %1}"
22265   [(set_attr "type" "mmxcvt")
22266    (set_attr "mode" "TI")])
22267
22268 (define_insn "pswapdv2sf2"
22269   [(set (match_operand:V2SF 0 "register_operand" "=y")
22270         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22271                          (parallel [(const_int 1) (const_int 0)])))]
22272   "TARGET_3DNOW_A"
22273   "pswapd\\t{%1, %0|%0, %1}"
22274   [(set_attr "type" "mmxcvt")
22275    (set_attr "mode" "TI")])
22276
22277 (define_expand "prefetch"
22278   [(prefetch (match_operand 0 "address_operand" "")
22279              (match_operand:SI 1 "const_int_operand" "")
22280              (match_operand:SI 2 "const_int_operand" ""))]
22281   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22282 {
22283   int rw = INTVAL (operands[1]);
22284   int locality = INTVAL (operands[2]);
22285
22286   if (rw != 0 && rw != 1)
22287     abort ();
22288   if (locality < 0 || locality > 3)
22289     abort ();
22290   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22291     abort ();
22292
22293   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22294      suported by SSE counterpart or the SSE prefetch is not available
22295      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22296      of locality.  */
22297   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22298     operands[2] = GEN_INT (3);
22299   else
22300     operands[1] = const0_rtx;
22301 })
22302
22303 (define_insn "*prefetch_sse"
22304   [(prefetch (match_operand:SI 0 "address_operand" "p")
22305              (const_int 0)
22306              (match_operand:SI 1 "const_int_operand" ""))]
22307   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22308 {
22309   static const char * const patterns[4] = {
22310    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22311   };
22312
22313   int locality = INTVAL (operands[1]);
22314   if (locality < 0 || locality > 3)
22315     abort ();
22316
22317   return patterns[locality];  
22318 }
22319   [(set_attr "type" "sse")
22320    (set_attr "memory" "none")])
22321
22322 (define_insn "*prefetch_sse_rex"
22323   [(prefetch (match_operand:DI 0 "address_operand" "p")
22324              (const_int 0)
22325              (match_operand:SI 1 "const_int_operand" ""))]
22326   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22327 {
22328   static const char * const patterns[4] = {
22329    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22330   };
22331
22332   int locality = INTVAL (operands[1]);
22333   if (locality < 0 || locality > 3)
22334     abort ();
22335
22336   return patterns[locality];  
22337 }
22338   [(set_attr "type" "sse")
22339    (set_attr "memory" "none")])
22340
22341 (define_insn "*prefetch_3dnow"
22342   [(prefetch (match_operand:SI 0 "address_operand" "p")
22343              (match_operand:SI 1 "const_int_operand" "n")
22344              (const_int 3))]
22345   "TARGET_3DNOW && !TARGET_64BIT"
22346 {
22347   if (INTVAL (operands[1]) == 0)
22348     return "prefetch\t%a0";
22349   else
22350     return "prefetchw\t%a0";
22351 }
22352   [(set_attr "type" "mmx")
22353    (set_attr "memory" "none")])
22354
22355 (define_insn "*prefetch_3dnow_rex"
22356   [(prefetch (match_operand:DI 0 "address_operand" "p")
22357              (match_operand:SI 1 "const_int_operand" "n")
22358              (const_int 3))]
22359   "TARGET_3DNOW && TARGET_64BIT"
22360 {
22361   if (INTVAL (operands[1]) == 0)
22362     return "prefetch\t%a0";
22363   else
22364     return "prefetchw\t%a0";
22365 }
22366   [(set_attr "type" "mmx")
22367    (set_attr "memory" "none")])
22368
22369 ;; SSE2 support
22370
22371 (define_insn "addv2df3"
22372   [(set (match_operand:V2DF 0 "register_operand" "=x")
22373         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22374                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22375   "TARGET_SSE2"
22376   "addpd\t{%2, %0|%0, %2}"
22377   [(set_attr "type" "sseadd")
22378    (set_attr "mode" "V2DF")])
22379
22380 (define_insn "vmaddv2df3"
22381   [(set (match_operand:V2DF 0 "register_operand" "=x")
22382         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22383                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22384                         (match_dup 1)
22385                         (const_int 1)))]
22386   "TARGET_SSE2"
22387   "addsd\t{%2, %0|%0, %2}"
22388   [(set_attr "type" "sseadd")
22389    (set_attr "mode" "DF")])
22390
22391 (define_insn "subv2df3"
22392   [(set (match_operand:V2DF 0 "register_operand" "=x")
22393         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22394                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22395   "TARGET_SSE2"
22396   "subpd\t{%2, %0|%0, %2}"
22397   [(set_attr "type" "sseadd")
22398    (set_attr "mode" "V2DF")])
22399
22400 (define_insn "vmsubv2df3"
22401   [(set (match_operand:V2DF 0 "register_operand" "=x")
22402         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22403                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22404                         (match_dup 1)
22405                         (const_int 1)))]
22406   "TARGET_SSE2"
22407   "subsd\t{%2, %0|%0, %2}"
22408   [(set_attr "type" "sseadd")
22409    (set_attr "mode" "DF")])
22410
22411 (define_insn "mulv2df3"
22412   [(set (match_operand:V2DF 0 "register_operand" "=x")
22413         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22414                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22415   "TARGET_SSE2"
22416   "mulpd\t{%2, %0|%0, %2}"
22417   [(set_attr "type" "ssemul")
22418    (set_attr "mode" "V2DF")])
22419
22420 (define_insn "vmmulv2df3"
22421   [(set (match_operand:V2DF 0 "register_operand" "=x")
22422         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22423                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22424                         (match_dup 1)
22425                         (const_int 1)))]
22426   "TARGET_SSE2"
22427   "mulsd\t{%2, %0|%0, %2}"
22428   [(set_attr "type" "ssemul")
22429    (set_attr "mode" "DF")])
22430
22431 (define_insn "divv2df3"
22432   [(set (match_operand:V2DF 0 "register_operand" "=x")
22433         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22434                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22435   "TARGET_SSE2"
22436   "divpd\t{%2, %0|%0, %2}"
22437   [(set_attr "type" "ssediv")
22438    (set_attr "mode" "V2DF")])
22439
22440 (define_insn "vmdivv2df3"
22441   [(set (match_operand:V2DF 0 "register_operand" "=x")
22442         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22443                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22444                         (match_dup 1)
22445                         (const_int 1)))]
22446   "TARGET_SSE2"
22447   "divsd\t{%2, %0|%0, %2}"
22448   [(set_attr "type" "ssediv")
22449    (set_attr "mode" "DF")])
22450
22451 ;; SSE min/max
22452
22453 (define_insn "smaxv2df3"
22454   [(set (match_operand:V2DF 0 "register_operand" "=x")
22455         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22456                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22457   "TARGET_SSE2"
22458   "maxpd\t{%2, %0|%0, %2}"
22459   [(set_attr "type" "sseadd")
22460    (set_attr "mode" "V2DF")])
22461
22462 (define_insn "vmsmaxv2df3"
22463   [(set (match_operand:V2DF 0 "register_operand" "=x")
22464         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22465                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22466                         (match_dup 1)
22467                         (const_int 1)))]
22468   "TARGET_SSE2"
22469   "maxsd\t{%2, %0|%0, %2}"
22470   [(set_attr "type" "sseadd")
22471    (set_attr "mode" "DF")])
22472
22473 (define_insn "sminv2df3"
22474   [(set (match_operand:V2DF 0 "register_operand" "=x")
22475         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22476                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22477   "TARGET_SSE2"
22478   "minpd\t{%2, %0|%0, %2}"
22479   [(set_attr "type" "sseadd")
22480    (set_attr "mode" "V2DF")])
22481
22482 (define_insn "vmsminv2df3"
22483   [(set (match_operand:V2DF 0 "register_operand" "=x")
22484         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22485                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22486                         (match_dup 1)
22487                         (const_int 1)))]
22488   "TARGET_SSE2"
22489   "minsd\t{%2, %0|%0, %2}"
22490   [(set_attr "type" "sseadd")
22491    (set_attr "mode" "DF")])
22492 ;; SSE2 square root.  There doesn't appear to be an extension for the
22493 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22494
22495 (define_insn "sqrtv2df2"
22496   [(set (match_operand:V2DF 0 "register_operand" "=x")
22497         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22498   "TARGET_SSE2"
22499   "sqrtpd\t{%1, %0|%0, %1}"
22500   [(set_attr "type" "sse")
22501    (set_attr "mode" "V2DF")])
22502
22503 (define_insn "vmsqrtv2df2"
22504   [(set (match_operand:V2DF 0 "register_operand" "=x")
22505         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22506                         (match_operand:V2DF 2 "register_operand" "0")
22507                         (const_int 1)))]
22508   "TARGET_SSE2"
22509   "sqrtsd\t{%1, %0|%0, %1}"
22510   [(set_attr "type" "sse")
22511    (set_attr "mode" "SF")])
22512
22513 ;; SSE mask-generating compares
22514
22515 (define_insn "maskcmpv2df3"
22516   [(set (match_operand:V2DI 0 "register_operand" "=x")
22517         (match_operator:V2DI 3 "sse_comparison_operator"
22518                              [(match_operand:V2DF 1 "register_operand" "0")
22519                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22520   "TARGET_SSE2"
22521   "cmp%D3pd\t{%2, %0|%0, %2}"
22522   [(set_attr "type" "ssecmp")
22523    (set_attr "mode" "V2DF")])
22524
22525 (define_insn "maskncmpv2df3"
22526   [(set (match_operand:V2DI 0 "register_operand" "=x")
22527         (not:V2DI
22528          (match_operator:V2DI 3 "sse_comparison_operator"
22529                               [(match_operand:V2DF 1 "register_operand" "0")
22530                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22531   "TARGET_SSE2"
22532 {
22533   if (GET_CODE (operands[3]) == UNORDERED)
22534     return "cmpordps\t{%2, %0|%0, %2}";
22535   else
22536     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22537 }
22538   [(set_attr "type" "ssecmp")
22539    (set_attr "mode" "V2DF")])
22540
22541 (define_insn "vmmaskcmpv2df3"
22542   [(set (match_operand:V2DI 0 "register_operand" "=x")
22543         (vec_merge:V2DI
22544          (match_operator:V2DI 3 "sse_comparison_operator"
22545                               [(match_operand:V2DF 1 "register_operand" "0")
22546                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22547          (subreg:V2DI (match_dup 1) 0)
22548          (const_int 1)))]
22549   "TARGET_SSE2"
22550   "cmp%D3sd\t{%2, %0|%0, %2}"
22551   [(set_attr "type" "ssecmp")
22552    (set_attr "mode" "DF")])
22553
22554 (define_insn "vmmaskncmpv2df3"
22555   [(set (match_operand:V2DI 0 "register_operand" "=x")
22556         (vec_merge:V2DI
22557          (not:V2DI
22558           (match_operator:V2DI 3 "sse_comparison_operator"
22559                                [(match_operand:V2DF 1 "register_operand" "0")
22560                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22561          (subreg:V2DI (match_dup 1) 0)
22562          (const_int 1)))]
22563   "TARGET_SSE2"
22564 {
22565   if (GET_CODE (operands[3]) == UNORDERED)
22566     return "cmpordsd\t{%2, %0|%0, %2}";
22567   else
22568     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22569 }
22570   [(set_attr "type" "ssecmp")
22571    (set_attr "mode" "DF")])
22572
22573 (define_insn "sse2_comi"
22574   [(set (reg:CCFP FLAGS_REG)
22575         (compare:CCFP (vec_select:DF
22576                        (match_operand:V2DF 0 "register_operand" "x")
22577                        (parallel [(const_int 0)]))
22578                       (vec_select:DF
22579                        (match_operand:V2DF 1 "register_operand" "x")
22580                        (parallel [(const_int 0)]))))]
22581   "TARGET_SSE2"
22582   "comisd\t{%1, %0|%0, %1}"
22583   [(set_attr "type" "ssecomi")
22584    (set_attr "mode" "DF")])
22585
22586 (define_insn "sse2_ucomi"
22587   [(set (reg:CCFPU FLAGS_REG)
22588         (compare:CCFPU (vec_select:DF
22589                          (match_operand:V2DF 0 "register_operand" "x")
22590                          (parallel [(const_int 0)]))
22591                         (vec_select:DF
22592                          (match_operand:V2DF 1 "register_operand" "x")
22593                          (parallel [(const_int 0)]))))]
22594   "TARGET_SSE2"
22595   "ucomisd\t{%1, %0|%0, %1}"
22596   [(set_attr "type" "ssecomi")
22597    (set_attr "mode" "DF")])
22598
22599 ;; SSE Strange Moves.
22600
22601 (define_insn "sse2_movmskpd"
22602   [(set (match_operand:SI 0 "register_operand" "=r")
22603         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22604                    UNSPEC_MOVMSK))]
22605   "TARGET_SSE2"
22606   "movmskpd\t{%1, %0|%0, %1}"
22607   [(set_attr "type" "ssecvt")
22608    (set_attr "mode" "V2DF")])
22609
22610 (define_insn "sse2_pmovmskb"
22611   [(set (match_operand:SI 0 "register_operand" "=r")
22612         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22613                    UNSPEC_MOVMSK))]
22614   "TARGET_SSE2"
22615   "pmovmskb\t{%1, %0|%0, %1}"
22616   [(set_attr "type" "ssecvt")
22617    (set_attr "mode" "V2DF")])
22618
22619 (define_insn "sse2_maskmovdqu"
22620   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22621         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22622                        (match_operand:V16QI 2 "register_operand" "x")]
22623                       UNSPEC_MASKMOV))]
22624   "TARGET_SSE2"
22625   ;; @@@ check ordering of operands in intel/nonintel syntax
22626   "maskmovdqu\t{%2, %1|%1, %2}"
22627   [(set_attr "type" "ssecvt")
22628    (set_attr "mode" "TI")])
22629
22630 (define_insn "sse2_maskmovdqu_rex64"
22631   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22632         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22633                        (match_operand:V16QI 2 "register_operand" "x")]
22634                       UNSPEC_MASKMOV))]
22635   "TARGET_SSE2"
22636   ;; @@@ check ordering of operands in intel/nonintel syntax
22637   "maskmovdqu\t{%2, %1|%1, %2}"
22638   [(set_attr "type" "ssecvt")
22639    (set_attr "mode" "TI")])
22640
22641 (define_insn "sse2_movntv2df"
22642   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22643         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22644                      UNSPEC_MOVNT))]
22645   "TARGET_SSE2"
22646   "movntpd\t{%1, %0|%0, %1}"
22647   [(set_attr "type" "ssecvt")
22648    (set_attr "mode" "V2DF")])
22649
22650 (define_insn "sse2_movntv2di"
22651   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22652         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22653                      UNSPEC_MOVNT))]
22654   "TARGET_SSE2"
22655   "movntdq\t{%1, %0|%0, %1}"
22656   [(set_attr "type" "ssecvt")
22657    (set_attr "mode" "TI")])
22658
22659 (define_insn "sse2_movntsi"
22660   [(set (match_operand:SI 0 "memory_operand" "=m")
22661         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22662                    UNSPEC_MOVNT))]
22663   "TARGET_SSE2"
22664   "movnti\t{%1, %0|%0, %1}"
22665   [(set_attr "type" "ssecvt")
22666    (set_attr "mode" "V2DF")])
22667
22668 ;; SSE <-> integer/MMX conversions
22669
22670 ;; Conversions between SI and SF
22671
22672 (define_insn "cvtdq2ps"
22673   [(set (match_operand:V4SF 0 "register_operand" "=x")
22674         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22675   "TARGET_SSE2"
22676   "cvtdq2ps\t{%1, %0|%0, %1}"
22677   [(set_attr "type" "ssecvt")
22678    (set_attr "mode" "V2DF")])
22679
22680 (define_insn "cvtps2dq"
22681   [(set (match_operand:V4SI 0 "register_operand" "=x")
22682         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22683   "TARGET_SSE2"
22684   "cvtps2dq\t{%1, %0|%0, %1}"
22685   [(set_attr "type" "ssecvt")
22686    (set_attr "mode" "TI")])
22687
22688 (define_insn "cvttps2dq"
22689   [(set (match_operand:V4SI 0 "register_operand" "=x")
22690         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22691                      UNSPEC_FIX))]
22692   "TARGET_SSE2"
22693   "cvttps2dq\t{%1, %0|%0, %1}"
22694   [(set_attr "type" "ssecvt")
22695    (set_attr "mode" "TI")])
22696
22697 ;; Conversions between SI and DF
22698
22699 (define_insn "cvtdq2pd"
22700   [(set (match_operand:V2DF 0 "register_operand" "=x")
22701         (float:V2DF (vec_select:V2SI
22702                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22703                      (parallel
22704                       [(const_int 0)
22705                        (const_int 1)]))))]
22706   "TARGET_SSE2"
22707   "cvtdq2pd\t{%1, %0|%0, %1}"
22708   [(set_attr "type" "ssecvt")
22709    (set_attr "mode" "V2DF")])
22710
22711 (define_insn "cvtpd2dq"
22712   [(set (match_operand:V4SI 0 "register_operand" "=x")
22713         (vec_concat:V4SI
22714          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22715          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22716   "TARGET_SSE2"
22717   "cvtpd2dq\t{%1, %0|%0, %1}"
22718   [(set_attr "type" "ssecvt")
22719    (set_attr "mode" "TI")])
22720
22721 (define_insn "cvttpd2dq"
22722   [(set (match_operand:V4SI 0 "register_operand" "=x")
22723         (vec_concat:V4SI
22724          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22725                       UNSPEC_FIX)
22726          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22727   "TARGET_SSE2"
22728   "cvttpd2dq\t{%1, %0|%0, %1}"
22729   [(set_attr "type" "ssecvt")
22730    (set_attr "mode" "TI")])
22731
22732 (define_insn "cvtpd2pi"
22733   [(set (match_operand:V2SI 0 "register_operand" "=y")
22734         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22735   "TARGET_SSE2"
22736   "cvtpd2pi\t{%1, %0|%0, %1}"
22737   [(set_attr "type" "ssecvt")
22738    (set_attr "mode" "TI")])
22739
22740 (define_insn "cvttpd2pi"
22741   [(set (match_operand:V2SI 0 "register_operand" "=y")
22742         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22743                      UNSPEC_FIX))]
22744   "TARGET_SSE2"
22745   "cvttpd2pi\t{%1, %0|%0, %1}"
22746   [(set_attr "type" "ssecvt")
22747    (set_attr "mode" "TI")])
22748
22749 (define_insn "cvtpi2pd"
22750   [(set (match_operand:V2DF 0 "register_operand" "=x")
22751         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22752   "TARGET_SSE2"
22753   "cvtpi2pd\t{%1, %0|%0, %1}"
22754   [(set_attr "type" "ssecvt")
22755    (set_attr "mode" "TI")])
22756
22757 ;; Conversions between SI and DF
22758
22759 (define_insn "cvtsd2si"
22760   [(set (match_operand:SI 0 "register_operand" "=r,r")
22761         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22762                                (parallel [(const_int 0)]))))]
22763   "TARGET_SSE2"
22764   "cvtsd2si\t{%1, %0|%0, %1}"
22765   [(set_attr "type" "sseicvt")
22766    (set_attr "athlon_decode" "double,vector")
22767    (set_attr "mode" "SI")])
22768
22769 (define_insn "cvtsd2siq"
22770   [(set (match_operand:DI 0 "register_operand" "=r,r")
22771         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22772                                (parallel [(const_int 0)]))))]
22773   "TARGET_SSE2 && TARGET_64BIT"
22774   "cvtsd2siq\t{%1, %0|%0, %1}"
22775   [(set_attr "type" "sseicvt")
22776    (set_attr "athlon_decode" "double,vector")
22777    (set_attr "mode" "DI")])
22778
22779 (define_insn "cvttsd2si"
22780   [(set (match_operand:SI 0 "register_operand" "=r,r")
22781         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22782                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22783   "TARGET_SSE2"
22784   "cvttsd2si\t{%1, %0|%0, %1}"
22785   [(set_attr "type" "sseicvt")
22786    (set_attr "mode" "SI")
22787    (set_attr "athlon_decode" "double,vector")])
22788
22789 (define_insn "cvttsd2siq"
22790   [(set (match_operand:DI 0 "register_operand" "=r,r")
22791         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22792                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22793   "TARGET_SSE2 && TARGET_64BIT"
22794   "cvttsd2siq\t{%1, %0|%0, %1}"
22795   [(set_attr "type" "sseicvt")
22796    (set_attr "mode" "DI")
22797    (set_attr "athlon_decode" "double,vector")])
22798
22799 (define_insn "cvtsi2sd"
22800   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22801         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22802                         (vec_duplicate:V2DF
22803                           (float:DF
22804                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22805                         (const_int 2)))]
22806   "TARGET_SSE2"
22807   "cvtsi2sd\t{%2, %0|%0, %2}"
22808   [(set_attr "type" "sseicvt")
22809    (set_attr "mode" "DF")
22810    (set_attr "athlon_decode" "double,direct")])
22811
22812 (define_insn "cvtsi2sdq"
22813   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22814         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22815                         (vec_duplicate:V2DF
22816                           (float:DF
22817                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22818                         (const_int 2)))]
22819   "TARGET_SSE2 && TARGET_64BIT"
22820   "cvtsi2sdq\t{%2, %0|%0, %2}"
22821   [(set_attr "type" "sseicvt")
22822    (set_attr "mode" "DF")
22823    (set_attr "athlon_decode" "double,direct")])
22824
22825 ;; Conversions between SF and DF
22826
22827 (define_insn "cvtsd2ss"
22828   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22829         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22830                         (vec_duplicate:V4SF
22831                           (float_truncate:V2SF
22832                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22833                         (const_int 14)))]
22834   "TARGET_SSE2"
22835   "cvtsd2ss\t{%2, %0|%0, %2}"
22836   [(set_attr "type" "ssecvt")
22837    (set_attr "athlon_decode" "vector,double")
22838    (set_attr "mode" "SF")])
22839
22840 (define_insn "cvtss2sd"
22841   [(set (match_operand:V2DF 0 "register_operand" "=x")
22842         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22843                         (float_extend:V2DF
22844                           (vec_select:V2SF
22845                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22846                             (parallel [(const_int 0)
22847                                        (const_int 1)])))
22848                         (const_int 2)))]
22849   "TARGET_SSE2"
22850   "cvtss2sd\t{%2, %0|%0, %2}"
22851   [(set_attr "type" "ssecvt")
22852    (set_attr "mode" "DF")])
22853
22854 (define_insn "cvtpd2ps"
22855   [(set (match_operand:V4SF 0 "register_operand" "=x")
22856         (subreg:V4SF
22857           (vec_concat:V4SI
22858             (subreg:V2SI (float_truncate:V2SF
22859                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22860             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22861   "TARGET_SSE2"
22862   "cvtpd2ps\t{%1, %0|%0, %1}"
22863   [(set_attr "type" "ssecvt")
22864    (set_attr "mode" "V4SF")])
22865
22866 (define_insn "cvtps2pd"
22867   [(set (match_operand:V2DF 0 "register_operand" "=x")
22868         (float_extend:V2DF
22869           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22870                            (parallel [(const_int 0)
22871                                       (const_int 1)]))))]
22872   "TARGET_SSE2"
22873   "cvtps2pd\t{%1, %0|%0, %1}"
22874   [(set_attr "type" "ssecvt")
22875    (set_attr "mode" "V2DF")])
22876
22877 ;; SSE2 variants of MMX insns
22878
22879 ;; MMX arithmetic
22880
22881 (define_insn "addv16qi3"
22882   [(set (match_operand:V16QI 0 "register_operand" "=x")
22883         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22884                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22885   "TARGET_SSE2"
22886   "paddb\t{%2, %0|%0, %2}"
22887   [(set_attr "type" "sseiadd")
22888    (set_attr "mode" "TI")])
22889
22890 (define_insn "addv8hi3"
22891   [(set (match_operand:V8HI 0 "register_operand" "=x")
22892         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22893                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22894   "TARGET_SSE2"
22895   "paddw\t{%2, %0|%0, %2}"
22896   [(set_attr "type" "sseiadd")
22897    (set_attr "mode" "TI")])
22898
22899 (define_insn "addv4si3"
22900   [(set (match_operand:V4SI 0 "register_operand" "=x")
22901         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22902                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22903   "TARGET_SSE2"
22904   "paddd\t{%2, %0|%0, %2}"
22905   [(set_attr "type" "sseiadd")
22906    (set_attr "mode" "TI")])
22907
22908 (define_insn "addv2di3"
22909   [(set (match_operand:V2DI 0 "register_operand" "=x")
22910         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22911                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22912   "TARGET_SSE2"
22913   "paddq\t{%2, %0|%0, %2}"
22914   [(set_attr "type" "sseiadd")
22915    (set_attr "mode" "TI")])
22916
22917 (define_insn "ssaddv16qi3"
22918   [(set (match_operand:V16QI 0 "register_operand" "=x")
22919         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22920                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22921   "TARGET_SSE2"
22922   "paddsb\t{%2, %0|%0, %2}"
22923   [(set_attr "type" "sseiadd")
22924    (set_attr "mode" "TI")])
22925
22926 (define_insn "ssaddv8hi3"
22927   [(set (match_operand:V8HI 0 "register_operand" "=x")
22928         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22929                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22930   "TARGET_SSE2"
22931   "paddsw\t{%2, %0|%0, %2}"
22932   [(set_attr "type" "sseiadd")
22933    (set_attr "mode" "TI")])
22934
22935 (define_insn "usaddv16qi3"
22936   [(set (match_operand:V16QI 0 "register_operand" "=x")
22937         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22938                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22939   "TARGET_SSE2"
22940   "paddusb\t{%2, %0|%0, %2}"
22941   [(set_attr "type" "sseiadd")
22942    (set_attr "mode" "TI")])
22943
22944 (define_insn "usaddv8hi3"
22945   [(set (match_operand:V8HI 0 "register_operand" "=x")
22946         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22947                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22948   "TARGET_SSE2"
22949   "paddusw\t{%2, %0|%0, %2}"
22950   [(set_attr "type" "sseiadd")
22951    (set_attr "mode" "TI")])
22952
22953 (define_insn "subv16qi3"
22954   [(set (match_operand:V16QI 0 "register_operand" "=x")
22955         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22956                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22957   "TARGET_SSE2"
22958   "psubb\t{%2, %0|%0, %2}"
22959   [(set_attr "type" "sseiadd")
22960    (set_attr "mode" "TI")])
22961
22962 (define_insn "subv8hi3"
22963   [(set (match_operand:V8HI 0 "register_operand" "=x")
22964         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22965                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22966   "TARGET_SSE2"
22967   "psubw\t{%2, %0|%0, %2}"
22968   [(set_attr "type" "sseiadd")
22969    (set_attr "mode" "TI")])
22970
22971 (define_insn "subv4si3"
22972   [(set (match_operand:V4SI 0 "register_operand" "=x")
22973         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22974                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22975   "TARGET_SSE2"
22976   "psubd\t{%2, %0|%0, %2}"
22977   [(set_attr "type" "sseiadd")
22978    (set_attr "mode" "TI")])
22979
22980 (define_insn "subv2di3"
22981   [(set (match_operand:V2DI 0 "register_operand" "=x")
22982         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22983                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22984   "TARGET_SSE2"
22985   "psubq\t{%2, %0|%0, %2}"
22986   [(set_attr "type" "sseiadd")
22987    (set_attr "mode" "TI")])
22988
22989 (define_insn "sssubv16qi3"
22990   [(set (match_operand:V16QI 0 "register_operand" "=x")
22991         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22992                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22993   "TARGET_SSE2"
22994   "psubsb\t{%2, %0|%0, %2}"
22995   [(set_attr "type" "sseiadd")
22996    (set_attr "mode" "TI")])
22997
22998 (define_insn "sssubv8hi3"
22999   [(set (match_operand:V8HI 0 "register_operand" "=x")
23000         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23001                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23002   "TARGET_SSE2"
23003   "psubsw\t{%2, %0|%0, %2}"
23004   [(set_attr "type" "sseiadd")
23005    (set_attr "mode" "TI")])
23006
23007 (define_insn "ussubv16qi3"
23008   [(set (match_operand:V16QI 0 "register_operand" "=x")
23009         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23010                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23011   "TARGET_SSE2"
23012   "psubusb\t{%2, %0|%0, %2}"
23013   [(set_attr "type" "sseiadd")
23014    (set_attr "mode" "TI")])
23015
23016 (define_insn "ussubv8hi3"
23017   [(set (match_operand:V8HI 0 "register_operand" "=x")
23018         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23019                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23020   "TARGET_SSE2"
23021   "psubusw\t{%2, %0|%0, %2}"
23022   [(set_attr "type" "sseiadd")
23023    (set_attr "mode" "TI")])
23024
23025 (define_insn "mulv8hi3"
23026   [(set (match_operand:V8HI 0 "register_operand" "=x")
23027         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23028                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23029   "TARGET_SSE2"
23030   "pmullw\t{%2, %0|%0, %2}"
23031   [(set_attr "type" "sseimul")
23032    (set_attr "mode" "TI")])
23033
23034 (define_insn "smulv8hi3_highpart"
23035   [(set (match_operand:V8HI 0 "register_operand" "=x")
23036         (truncate:V8HI
23037          (lshiftrt:V8SI
23038           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23039                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23040           (const_int 16))))]
23041   "TARGET_SSE2"
23042   "pmulhw\t{%2, %0|%0, %2}"
23043   [(set_attr "type" "sseimul")
23044    (set_attr "mode" "TI")])
23045
23046 (define_insn "umulv8hi3_highpart"
23047   [(set (match_operand:V8HI 0 "register_operand" "=x")
23048         (truncate:V8HI
23049          (lshiftrt:V8SI
23050           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23051                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23052           (const_int 16))))]
23053   "TARGET_SSE2"
23054   "pmulhuw\t{%2, %0|%0, %2}"
23055   [(set_attr "type" "sseimul")
23056    (set_attr "mode" "TI")])
23057
23058 (define_insn "sse2_umulsidi3"
23059   [(set (match_operand:DI 0 "register_operand" "=y")
23060         (mult:DI (zero_extend:DI (vec_select:SI
23061                                   (match_operand:V2SI 1 "register_operand" "0")
23062                                   (parallel [(const_int 0)])))
23063                  (zero_extend:DI (vec_select:SI
23064                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23065                                   (parallel [(const_int 0)])))))]
23066   "TARGET_SSE2"
23067   "pmuludq\t{%2, %0|%0, %2}"
23068   [(set_attr "type" "sseimul")
23069    (set_attr "mode" "TI")])
23070
23071 (define_insn "sse2_umulv2siv2di3"
23072   [(set (match_operand:V2DI 0 "register_operand" "=x")
23073         (mult:V2DI (zero_extend:V2DI
23074                      (vec_select:V2SI
23075                        (match_operand:V4SI 1 "register_operand" "0")
23076                        (parallel [(const_int 0) (const_int 2)])))
23077                    (zero_extend:V2DI
23078                      (vec_select:V2SI
23079                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23080                        (parallel [(const_int 0) (const_int 2)])))))]
23081   "TARGET_SSE2"
23082   "pmuludq\t{%2, %0|%0, %2}"
23083   [(set_attr "type" "sseimul")
23084    (set_attr "mode" "TI")])
23085
23086 (define_insn "sse2_pmaddwd"
23087   [(set (match_operand:V4SI 0 "register_operand" "=x")
23088         (plus:V4SI
23089          (mult:V4SI
23090           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23091                                              (parallel [(const_int 0)
23092                                                         (const_int 2)
23093                                                         (const_int 4)
23094                                                         (const_int 6)])))
23095           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23096                                              (parallel [(const_int 0)
23097                                                         (const_int 2)
23098                                                         (const_int 4)
23099                                                         (const_int 6)]))))
23100          (mult:V4SI
23101           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23102                                              (parallel [(const_int 1)
23103                                                         (const_int 3)
23104                                                         (const_int 5)
23105                                                         (const_int 7)])))
23106           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23107                                              (parallel [(const_int 1)
23108                                                         (const_int 3)
23109                                                         (const_int 5)
23110                                                         (const_int 7)]))))))]
23111   "TARGET_SSE2"
23112   "pmaddwd\t{%2, %0|%0, %2}"
23113   [(set_attr "type" "sseiadd")
23114    (set_attr "mode" "TI")])
23115
23116 ;; Same as pxor, but don't show input operands so that we don't think
23117 ;; they are live.
23118 (define_insn "sse2_clrti"
23119   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23120   "TARGET_SSE2"
23121 {
23122   if (get_attr_mode (insn) == MODE_TI)
23123     return "pxor\t%0, %0";
23124   else
23125     return "xorps\t%0, %0";
23126 }
23127   [(set_attr "type" "ssemov")
23128    (set_attr "memory" "none")
23129    (set (attr "mode")
23130               (if_then_else
23131                 (ne (symbol_ref "optimize_size")
23132                     (const_int 0))
23133                 (const_string "V4SF")
23134                 (const_string "TI")))])
23135
23136 ;; MMX unsigned averages/sum of absolute differences
23137
23138 (define_insn "sse2_uavgv16qi3"
23139   [(set (match_operand:V16QI 0 "register_operand" "=x")
23140         (ashiftrt:V16QI
23141          (plus:V16QI (plus:V16QI
23142                      (match_operand:V16QI 1 "register_operand" "0")
23143                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23144                      (const_vector:V16QI [(const_int 1) (const_int 1)
23145                                           (const_int 1) (const_int 1)
23146                                           (const_int 1) (const_int 1)
23147                                           (const_int 1) (const_int 1)
23148                                           (const_int 1) (const_int 1)
23149                                           (const_int 1) (const_int 1)
23150                                           (const_int 1) (const_int 1)
23151                                           (const_int 1) (const_int 1)]))
23152          (const_int 1)))]
23153   "TARGET_SSE2"
23154   "pavgb\t{%2, %0|%0, %2}"
23155   [(set_attr "type" "sseiadd")
23156    (set_attr "mode" "TI")])
23157
23158 (define_insn "sse2_uavgv8hi3"
23159   [(set (match_operand:V8HI 0 "register_operand" "=x")
23160         (ashiftrt:V8HI
23161          (plus:V8HI (plus:V8HI
23162                      (match_operand:V8HI 1 "register_operand" "0")
23163                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23164                     (const_vector:V8HI [(const_int 1) (const_int 1)
23165                                         (const_int 1) (const_int 1)
23166                                         (const_int 1) (const_int 1)
23167                                         (const_int 1) (const_int 1)]))
23168          (const_int 1)))]
23169   "TARGET_SSE2"
23170   "pavgw\t{%2, %0|%0, %2}"
23171   [(set_attr "type" "sseiadd")
23172    (set_attr "mode" "TI")])
23173
23174 ;; @@@ this isn't the right representation.
23175 (define_insn "sse2_psadbw"
23176   [(set (match_operand:V2DI 0 "register_operand" "=x")
23177         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23178                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23179                      UNSPEC_PSADBW))]
23180   "TARGET_SSE2"
23181   "psadbw\t{%2, %0|%0, %2}"
23182   [(set_attr "type" "sseiadd")
23183    (set_attr "mode" "TI")])
23184
23185
23186 ;; MMX insert/extract/shuffle
23187
23188 (define_insn "sse2_pinsrw"
23189   [(set (match_operand:V8HI 0 "register_operand" "=x")
23190         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23191                         (vec_duplicate:V8HI
23192                          (truncate:HI
23193                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23194                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23195   "TARGET_SSE2"
23196   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23197   [(set_attr "type" "ssecvt")
23198    (set_attr "mode" "TI")])
23199
23200 (define_insn "sse2_pextrw"
23201   [(set (match_operand:SI 0 "register_operand" "=r")
23202         (zero_extend:SI
23203           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23204                          (parallel
23205                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23206   "TARGET_SSE2"
23207   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23208   [(set_attr "type" "ssecvt")
23209    (set_attr "mode" "TI")])
23210
23211 (define_insn "sse2_pshufd"
23212   [(set (match_operand:V4SI 0 "register_operand" "=x")
23213         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23214                       (match_operand:SI 2 "immediate_operand" "i")]
23215                      UNSPEC_SHUFFLE))]
23216   "TARGET_SSE2"
23217   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23218   [(set_attr "type" "ssecvt")
23219    (set_attr "mode" "TI")])
23220
23221 (define_insn "sse2_pshuflw"
23222   [(set (match_operand:V8HI 0 "register_operand" "=x")
23223         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23224                       (match_operand:SI 2 "immediate_operand" "i")]
23225                      UNSPEC_PSHUFLW))]
23226   "TARGET_SSE2"
23227   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23228   [(set_attr "type" "ssecvt")
23229    (set_attr "mode" "TI")])
23230
23231 (define_insn "sse2_pshufhw"
23232   [(set (match_operand:V8HI 0 "register_operand" "=x")
23233         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23234                       (match_operand:SI 2 "immediate_operand" "i")]
23235                      UNSPEC_PSHUFHW))]
23236   "TARGET_SSE2"
23237   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23238   [(set_attr "type" "ssecvt")
23239    (set_attr "mode" "TI")])
23240
23241 ;; MMX mask-generating comparisons
23242
23243 (define_insn "eqv16qi3"
23244   [(set (match_operand:V16QI 0 "register_operand" "=x")
23245         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23246                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23247   "TARGET_SSE2"
23248   "pcmpeqb\t{%2, %0|%0, %2}"
23249   [(set_attr "type" "ssecmp")
23250    (set_attr "mode" "TI")])
23251
23252 (define_insn "eqv8hi3"
23253   [(set (match_operand:V8HI 0 "register_operand" "=x")
23254         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23255                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23256   "TARGET_SSE2"
23257   "pcmpeqw\t{%2, %0|%0, %2}"
23258   [(set_attr "type" "ssecmp")
23259    (set_attr "mode" "TI")])
23260
23261 (define_insn "eqv4si3"
23262   [(set (match_operand:V4SI 0 "register_operand" "=x")
23263         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23264                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23265   "TARGET_SSE2"
23266   "pcmpeqd\t{%2, %0|%0, %2}"
23267   [(set_attr "type" "ssecmp")
23268    (set_attr "mode" "TI")])
23269
23270 (define_insn "gtv16qi3"
23271   [(set (match_operand:V16QI 0 "register_operand" "=x")
23272         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23273                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23274   "TARGET_SSE2"
23275   "pcmpgtb\t{%2, %0|%0, %2}"
23276   [(set_attr "type" "ssecmp")
23277    (set_attr "mode" "TI")])
23278
23279 (define_insn "gtv8hi3"
23280   [(set (match_operand:V8HI 0 "register_operand" "=x")
23281         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23282                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23283   "TARGET_SSE2"
23284   "pcmpgtw\t{%2, %0|%0, %2}"
23285   [(set_attr "type" "ssecmp")
23286    (set_attr "mode" "TI")])
23287
23288 (define_insn "gtv4si3"
23289   [(set (match_operand:V4SI 0 "register_operand" "=x")
23290         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23291                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23292   "TARGET_SSE2"
23293   "pcmpgtd\t{%2, %0|%0, %2}"
23294   [(set_attr "type" "ssecmp")
23295    (set_attr "mode" "TI")])
23296
23297
23298 ;; MMX max/min insns
23299
23300 (define_insn "umaxv16qi3"
23301   [(set (match_operand:V16QI 0 "register_operand" "=x")
23302         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23303                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23304   "TARGET_SSE2"
23305   "pmaxub\t{%2, %0|%0, %2}"
23306   [(set_attr "type" "sseiadd")
23307    (set_attr "mode" "TI")])
23308
23309 (define_insn "smaxv8hi3"
23310   [(set (match_operand:V8HI 0 "register_operand" "=x")
23311         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23312                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23313   "TARGET_SSE2"
23314   "pmaxsw\t{%2, %0|%0, %2}"
23315   [(set_attr "type" "sseiadd")
23316    (set_attr "mode" "TI")])
23317
23318 (define_insn "uminv16qi3"
23319   [(set (match_operand:V16QI 0 "register_operand" "=x")
23320         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23321                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23322   "TARGET_SSE2"
23323   "pminub\t{%2, %0|%0, %2}"
23324   [(set_attr "type" "sseiadd")
23325    (set_attr "mode" "TI")])
23326
23327 (define_insn "sminv8hi3"
23328   [(set (match_operand:V8HI 0 "register_operand" "=x")
23329         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23330                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23331   "TARGET_SSE2"
23332   "pminsw\t{%2, %0|%0, %2}"
23333   [(set_attr "type" "sseiadd")
23334    (set_attr "mode" "TI")])
23335
23336
23337 ;; MMX shifts
23338
23339 (define_insn "ashrv8hi3"
23340   [(set (match_operand:V8HI 0 "register_operand" "=x")
23341         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23342                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23343   "TARGET_SSE2"
23344   "psraw\t{%2, %0|%0, %2}"
23345   [(set_attr "type" "sseishft")
23346    (set_attr "mode" "TI")])
23347
23348 (define_insn "ashrv4si3"
23349   [(set (match_operand:V4SI 0 "register_operand" "=x")
23350         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23351                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23352   "TARGET_SSE2"
23353   "psrad\t{%2, %0|%0, %2}"
23354   [(set_attr "type" "sseishft")
23355    (set_attr "mode" "TI")])
23356
23357 (define_insn "lshrv8hi3"
23358   [(set (match_operand:V8HI 0 "register_operand" "=x")
23359         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23360                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23361   "TARGET_SSE2"
23362   "psrlw\t{%2, %0|%0, %2}"
23363   [(set_attr "type" "sseishft")
23364    (set_attr "mode" "TI")])
23365
23366 (define_insn "lshrv4si3"
23367   [(set (match_operand:V4SI 0 "register_operand" "=x")
23368         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23369                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23370   "TARGET_SSE2"
23371   "psrld\t{%2, %0|%0, %2}"
23372   [(set_attr "type" "sseishft")
23373    (set_attr "mode" "TI")])
23374
23375 (define_insn "lshrv2di3"
23376   [(set (match_operand:V2DI 0 "register_operand" "=x")
23377         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23378                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23379   "TARGET_SSE2"
23380   "psrlq\t{%2, %0|%0, %2}"
23381   [(set_attr "type" "sseishft")
23382    (set_attr "mode" "TI")])
23383
23384 (define_insn "ashlv8hi3"
23385   [(set (match_operand:V8HI 0 "register_operand" "=x")
23386         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23387                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23388   "TARGET_SSE2"
23389   "psllw\t{%2, %0|%0, %2}"
23390   [(set_attr "type" "sseishft")
23391    (set_attr "mode" "TI")])
23392
23393 (define_insn "ashlv4si3"
23394   [(set (match_operand:V4SI 0 "register_operand" "=x")
23395         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23396                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23397   "TARGET_SSE2"
23398   "pslld\t{%2, %0|%0, %2}"
23399   [(set_attr "type" "sseishft")
23400    (set_attr "mode" "TI")])
23401
23402 (define_insn "ashlv2di3"
23403   [(set (match_operand:V2DI 0 "register_operand" "=x")
23404         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23405                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23406   "TARGET_SSE2"
23407   "psllq\t{%2, %0|%0, %2}"
23408   [(set_attr "type" "sseishft")
23409    (set_attr "mode" "TI")])
23410
23411 (define_insn "ashrv8hi3_ti"
23412   [(set (match_operand:V8HI 0 "register_operand" "=x")
23413         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23414                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23415   "TARGET_SSE2"
23416   "psraw\t{%2, %0|%0, %2}"
23417   [(set_attr "type" "sseishft")
23418    (set_attr "mode" "TI")])
23419
23420 (define_insn "ashrv4si3_ti"
23421   [(set (match_operand:V4SI 0 "register_operand" "=x")
23422         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23423                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23424   "TARGET_SSE2"
23425   "psrad\t{%2, %0|%0, %2}"
23426   [(set_attr "type" "sseishft")
23427    (set_attr "mode" "TI")])
23428
23429 (define_insn "lshrv8hi3_ti"
23430   [(set (match_operand:V8HI 0 "register_operand" "=x")
23431         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23432                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23433   "TARGET_SSE2"
23434   "psrlw\t{%2, %0|%0, %2}"
23435   [(set_attr "type" "sseishft")
23436    (set_attr "mode" "TI")])
23437
23438 (define_insn "lshrv4si3_ti"
23439   [(set (match_operand:V4SI 0 "register_operand" "=x")
23440         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23441                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23442   "TARGET_SSE2"
23443   "psrld\t{%2, %0|%0, %2}"
23444   [(set_attr "type" "sseishft")
23445    (set_attr "mode" "TI")])
23446
23447 (define_insn "lshrv2di3_ti"
23448   [(set (match_operand:V2DI 0 "register_operand" "=x")
23449         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23450                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23451   "TARGET_SSE2"
23452   "psrlq\t{%2, %0|%0, %2}"
23453   [(set_attr "type" "sseishft")
23454    (set_attr "mode" "TI")])
23455
23456 (define_insn "ashlv8hi3_ti"
23457   [(set (match_operand:V8HI 0 "register_operand" "=x")
23458         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23459                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23460   "TARGET_SSE2"
23461   "psllw\t{%2, %0|%0, %2}"
23462   [(set_attr "type" "sseishft")
23463    (set_attr "mode" "TI")])
23464
23465 (define_insn "ashlv4si3_ti"
23466   [(set (match_operand:V4SI 0 "register_operand" "=x")
23467         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23468                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23469   "TARGET_SSE2"
23470   "pslld\t{%2, %0|%0, %2}"
23471   [(set_attr "type" "sseishft")
23472    (set_attr "mode" "TI")])
23473
23474 (define_insn "ashlv2di3_ti"
23475   [(set (match_operand:V2DI 0 "register_operand" "=x")
23476         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23477                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23478   "TARGET_SSE2"
23479   "psllq\t{%2, %0|%0, %2}"
23480   [(set_attr "type" "sseishft")
23481    (set_attr "mode" "TI")])
23482
23483 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23484 ;; we wouldn't need here it since we never generate TImode arithmetic.
23485
23486 ;; There has to be some kind of prize for the weirdest new instruction...
23487 (define_insn "sse2_ashlti3"
23488   [(set (match_operand:TI 0 "register_operand" "=x")
23489         (unspec:TI
23490          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23491                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23492                                (const_int 8)))] UNSPEC_NOP))]
23493   "TARGET_SSE2"
23494   "pslldq\t{%2, %0|%0, %2}"
23495   [(set_attr "type" "sseishft")
23496    (set_attr "mode" "TI")])
23497
23498 (define_insn "sse2_lshrti3"
23499   [(set (match_operand:TI 0 "register_operand" "=x")
23500         (unspec:TI
23501          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23502                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23503                                 (const_int 8)))] UNSPEC_NOP))]
23504   "TARGET_SSE2"
23505   "psrldq\t{%2, %0|%0, %2}"
23506   [(set_attr "type" "sseishft")
23507    (set_attr "mode" "TI")])
23508
23509 ;; SSE unpack
23510
23511 (define_insn "sse2_unpckhpd"
23512   [(set (match_operand:V2DF 0 "register_operand" "=x")
23513         (vec_concat:V2DF
23514          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23515                         (parallel [(const_int 1)]))
23516          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23517                         (parallel [(const_int 1)]))))]
23518   "TARGET_SSE2"
23519   "unpckhpd\t{%2, %0|%0, %2}"
23520   [(set_attr "type" "ssecvt")
23521    (set_attr "mode" "V2DF")])
23522
23523 (define_insn "sse2_unpcklpd"
23524   [(set (match_operand:V2DF 0 "register_operand" "=x")
23525         (vec_concat:V2DF
23526          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23527                         (parallel [(const_int 0)]))
23528          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23529                         (parallel [(const_int 0)]))))]
23530   "TARGET_SSE2"
23531   "unpcklpd\t{%2, %0|%0, %2}"
23532   [(set_attr "type" "ssecvt")
23533    (set_attr "mode" "V2DF")])
23534
23535 ;; MMX pack/unpack insns.
23536
23537 (define_insn "sse2_packsswb"
23538   [(set (match_operand:V16QI 0 "register_operand" "=x")
23539         (vec_concat:V16QI
23540          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23541          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23542   "TARGET_SSE2"
23543   "packsswb\t{%2, %0|%0, %2}"
23544   [(set_attr "type" "ssecvt")
23545    (set_attr "mode" "TI")])
23546
23547 (define_insn "sse2_packssdw"
23548   [(set (match_operand:V8HI 0 "register_operand" "=x")
23549         (vec_concat:V8HI
23550          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23551          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23552   "TARGET_SSE2"
23553   "packssdw\t{%2, %0|%0, %2}"
23554   [(set_attr "type" "ssecvt")
23555    (set_attr "mode" "TI")])
23556
23557 (define_insn "sse2_packuswb"
23558   [(set (match_operand:V16QI 0 "register_operand" "=x")
23559         (vec_concat:V16QI
23560          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23561          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23562   "TARGET_SSE2"
23563   "packuswb\t{%2, %0|%0, %2}"
23564   [(set_attr "type" "ssecvt")
23565    (set_attr "mode" "TI")])
23566
23567 (define_insn "sse2_punpckhbw"
23568   [(set (match_operand:V16QI 0 "register_operand" "=x")
23569         (vec_merge:V16QI
23570          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23571                            (parallel [(const_int 8) (const_int 0)
23572                                       (const_int 9) (const_int 1)
23573                                       (const_int 10) (const_int 2)
23574                                       (const_int 11) (const_int 3)
23575                                       (const_int 12) (const_int 4)
23576                                       (const_int 13) (const_int 5)
23577                                       (const_int 14) (const_int 6)
23578                                       (const_int 15) (const_int 7)]))
23579          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23580                            (parallel [(const_int 0) (const_int 8)
23581                                       (const_int 1) (const_int 9)
23582                                       (const_int 2) (const_int 10)
23583                                       (const_int 3) (const_int 11)
23584                                       (const_int 4) (const_int 12)
23585                                       (const_int 5) (const_int 13)
23586                                       (const_int 6) (const_int 14)
23587                                       (const_int 7) (const_int 15)]))
23588          (const_int 21845)))]
23589   "TARGET_SSE2"
23590   "punpckhbw\t{%2, %0|%0, %2}"
23591   [(set_attr "type" "ssecvt")
23592    (set_attr "mode" "TI")])
23593
23594 (define_insn "sse2_punpckhwd"
23595   [(set (match_operand:V8HI 0 "register_operand" "=x")
23596         (vec_merge:V8HI
23597          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23598                           (parallel [(const_int 4) (const_int 0)
23599                                      (const_int 5) (const_int 1)
23600                                      (const_int 6) (const_int 2)
23601                                      (const_int 7) (const_int 3)]))
23602          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23603                           (parallel [(const_int 0) (const_int 4)
23604                                      (const_int 1) (const_int 5)
23605                                      (const_int 2) (const_int 6)
23606                                      (const_int 3) (const_int 7)]))
23607          (const_int 85)))]
23608   "TARGET_SSE2"
23609   "punpckhwd\t{%2, %0|%0, %2}"
23610   [(set_attr "type" "ssecvt")
23611    (set_attr "mode" "TI")])
23612
23613 (define_insn "sse2_punpckhdq"
23614   [(set (match_operand:V4SI 0 "register_operand" "=x")
23615         (vec_merge:V4SI
23616          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23617                           (parallel [(const_int 2) (const_int 0)
23618                                      (const_int 3) (const_int 1)]))
23619          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23620                           (parallel [(const_int 0) (const_int 2)
23621                                      (const_int 1) (const_int 3)]))
23622          (const_int 5)))]
23623   "TARGET_SSE2"
23624   "punpckhdq\t{%2, %0|%0, %2}"
23625   [(set_attr "type" "ssecvt")
23626    (set_attr "mode" "TI")])
23627
23628 (define_insn "sse2_punpcklbw"
23629   [(set (match_operand:V16QI 0 "register_operand" "=x")
23630         (vec_merge:V16QI
23631          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23632                            (parallel [(const_int 0) (const_int 8)
23633                                       (const_int 1) (const_int 9)
23634                                       (const_int 2) (const_int 10)
23635                                       (const_int 3) (const_int 11)
23636                                       (const_int 4) (const_int 12)
23637                                       (const_int 5) (const_int 13)
23638                                       (const_int 6) (const_int 14)
23639                                       (const_int 7) (const_int 15)]))
23640          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23641                            (parallel [(const_int 8) (const_int 0)
23642                                       (const_int 9) (const_int 1)
23643                                       (const_int 10) (const_int 2)
23644                                       (const_int 11) (const_int 3)
23645                                       (const_int 12) (const_int 4)
23646                                       (const_int 13) (const_int 5)
23647                                       (const_int 14) (const_int 6)
23648                                       (const_int 15) (const_int 7)]))
23649          (const_int 21845)))]
23650   "TARGET_SSE2"
23651   "punpcklbw\t{%2, %0|%0, %2}"
23652   [(set_attr "type" "ssecvt")
23653    (set_attr "mode" "TI")])
23654
23655 (define_insn "sse2_punpcklwd"
23656   [(set (match_operand:V8HI 0 "register_operand" "=x")
23657         (vec_merge:V8HI
23658          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23659                           (parallel [(const_int 0) (const_int 4)
23660                                      (const_int 1) (const_int 5)
23661                                      (const_int 2) (const_int 6)
23662                                      (const_int 3) (const_int 7)]))
23663          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23664                           (parallel [(const_int 4) (const_int 0)
23665                                      (const_int 5) (const_int 1)
23666                                      (const_int 6) (const_int 2)
23667                                      (const_int 7) (const_int 3)]))
23668          (const_int 85)))]
23669   "TARGET_SSE2"
23670   "punpcklwd\t{%2, %0|%0, %2}"
23671   [(set_attr "type" "ssecvt")
23672    (set_attr "mode" "TI")])
23673
23674 (define_insn "sse2_punpckldq"
23675   [(set (match_operand:V4SI 0 "register_operand" "=x")
23676         (vec_merge:V4SI
23677          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23678                           (parallel [(const_int 0) (const_int 2)
23679                                      (const_int 1) (const_int 3)]))
23680          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23681                           (parallel [(const_int 2) (const_int 0)
23682                                      (const_int 3) (const_int 1)]))
23683          (const_int 5)))]
23684   "TARGET_SSE2"
23685   "punpckldq\t{%2, %0|%0, %2}"
23686   [(set_attr "type" "ssecvt")
23687    (set_attr "mode" "TI")])
23688
23689 (define_insn "sse2_punpcklqdq"
23690   [(set (match_operand:V2DI 0 "register_operand" "=x")
23691         (vec_merge:V2DI
23692          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23693                           (parallel [(const_int 1)
23694                                      (const_int 0)]))
23695          (match_operand:V2DI 1 "register_operand" "0")
23696          (const_int 1)))]
23697   "TARGET_SSE2"
23698   "punpcklqdq\t{%2, %0|%0, %2}"
23699   [(set_attr "type" "ssecvt")
23700    (set_attr "mode" "TI")])
23701
23702 (define_insn "sse2_punpckhqdq"
23703   [(set (match_operand:V2DI 0 "register_operand" "=x")
23704         (vec_merge:V2DI
23705          (match_operand:V2DI 1 "register_operand" "0")
23706          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23707                           (parallel [(const_int 1)
23708                                      (const_int 0)]))
23709          (const_int 1)))]
23710   "TARGET_SSE2"
23711   "punpckhqdq\t{%2, %0|%0, %2}"
23712   [(set_attr "type" "ssecvt")
23713    (set_attr "mode" "TI")])
23714
23715 ;; SSE2 moves
23716
23717 (define_insn "sse2_movapd"
23718   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23719         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23720                      UNSPEC_MOVA))]
23721   "TARGET_SSE2
23722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23723   "movapd\t{%1, %0|%0, %1}"
23724   [(set_attr "type" "ssemov")
23725    (set_attr "mode" "V2DF")])
23726
23727 (define_insn "sse2_movupd"
23728   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23729         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23730                      UNSPEC_MOVU))]
23731   "TARGET_SSE2
23732    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23733   "movupd\t{%1, %0|%0, %1}"
23734   [(set_attr "type" "ssecvt")
23735    (set_attr "mode" "V2DF")])
23736
23737 (define_insn "sse2_movdqa"
23738   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23739         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23740                        UNSPEC_MOVA))]
23741   "TARGET_SSE2
23742    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23743   "movdqa\t{%1, %0|%0, %1}"
23744   [(set_attr "type" "ssemov")
23745    (set_attr "mode" "TI")])
23746
23747 (define_insn "sse2_movdqu"
23748   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23749         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23750                        UNSPEC_MOVU))]
23751   "TARGET_SSE2
23752    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23753   "movdqu\t{%1, %0|%0, %1}"
23754   [(set_attr "type" "ssecvt")
23755    (set_attr "mode" "TI")])
23756
23757 (define_insn "sse2_movdq2q"
23758   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23759         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23760                        (parallel [(const_int 0)])))]
23761   "TARGET_SSE2 && !TARGET_64BIT"
23762   "@
23763    movq\t{%1, %0|%0, %1}
23764    movdq2q\t{%1, %0|%0, %1}"
23765   [(set_attr "type" "ssecvt")
23766    (set_attr "mode" "TI")])
23767
23768 (define_insn "sse2_movdq2q_rex64"
23769   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23770         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23771                        (parallel [(const_int 0)])))]
23772   "TARGET_SSE2 && TARGET_64BIT"
23773   "@
23774    movq\t{%1, %0|%0, %1}
23775    movdq2q\t{%1, %0|%0, %1}
23776    movd\t{%1, %0|%0, %1}"
23777   [(set_attr "type" "ssecvt")
23778    (set_attr "mode" "TI")])
23779
23780 (define_insn "sse2_movq2dq"
23781   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23782         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23783                          (const_int 0)))]
23784   "TARGET_SSE2 && !TARGET_64BIT"
23785   "@
23786    movq\t{%1, %0|%0, %1}
23787    movq2dq\t{%1, %0|%0, %1}"
23788   [(set_attr "type" "ssecvt,ssemov")
23789    (set_attr "mode" "TI")])
23790
23791 (define_insn "sse2_movq2dq_rex64"
23792   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23793         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23794                          (const_int 0)))]
23795   "TARGET_SSE2 && TARGET_64BIT"
23796   "@
23797    movq\t{%1, %0|%0, %1}
23798    movq2dq\t{%1, %0|%0, %1}
23799    movd\t{%1, %0|%0, %1}"
23800   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23801    (set_attr "mode" "TI")])
23802
23803 (define_insn "sse2_movq"
23804   [(set (match_operand:V2DI 0 "register_operand" "=x")
23805         (vec_concat:V2DI (vec_select:DI
23806                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23807                           (parallel [(const_int 0)]))
23808                          (const_int 0)))]
23809   "TARGET_SSE2"
23810   "movq\t{%1, %0|%0, %1}"
23811   [(set_attr "type" "ssemov")
23812    (set_attr "mode" "TI")])
23813
23814 (define_insn "sse2_loadd"
23815   [(set (match_operand:V4SI 0 "register_operand" "=x")
23816         (vec_merge:V4SI
23817          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23818          (const_vector:V4SI [(const_int 0)
23819                              (const_int 0)
23820                              (const_int 0)
23821                              (const_int 0)])
23822          (const_int 1)))]
23823   "TARGET_SSE2"
23824   "movd\t{%1, %0|%0, %1}"
23825   [(set_attr "type" "ssemov")
23826    (set_attr "mode" "TI")])
23827
23828 (define_insn "sse2_stored"
23829   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23830         (vec_select:SI
23831          (match_operand:V4SI 1 "register_operand" "x")
23832          (parallel [(const_int 0)])))]
23833   "TARGET_SSE2"
23834   "movd\t{%1, %0|%0, %1}"
23835   [(set_attr "type" "ssemov")
23836    (set_attr "mode" "TI")])
23837
23838 (define_insn "sse2_movhpd"
23839   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23840         (vec_merge:V2DF
23841          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23842          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23843          (const_int 2)))]
23844   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23845   "movhpd\t{%2, %0|%0, %2}"
23846   [(set_attr "type" "ssecvt")
23847    (set_attr "mode" "V2DF")])
23848
23849 (define_expand "sse2_loadsd"
23850   [(match_operand:V2DF 0 "register_operand" "")
23851    (match_operand:DF 1 "memory_operand" "")]
23852   "TARGET_SSE2"
23853 {
23854   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23855                                 CONST0_RTX (V2DFmode)));
23856   DONE;
23857 })
23858
23859 (define_insn "sse2_loadsd_1"
23860   [(set (match_operand:V2DF 0 "register_operand" "=x")
23861         (vec_merge:V2DF
23862          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23863          (match_operand:V2DF 2 "const0_operand" "X")
23864          (const_int 1)))]
23865   "TARGET_SSE2"
23866   "movsd\t{%1, %0|%0, %1}"
23867   [(set_attr "type" "ssecvt")
23868    (set_attr "mode" "DF")])
23869
23870 (define_insn "sse2_movsd"
23871   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23872         (vec_merge:V2DF
23873          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23874          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23875          (const_int 1)))]
23876   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
23877   "@movsd\t{%2, %0|%0, %2}
23878     movlpd\t{%2, %0|%0, %2}
23879     movlpd\t{%2, %0|%0, %2}"
23880   [(set_attr "type" "ssecvt")
23881    (set_attr "mode" "DF,V2DF,V2DF")])
23882
23883 (define_insn "sse2_storesd"
23884   [(set (match_operand:DF 0 "memory_operand" "=m")
23885         (vec_select:DF
23886          (match_operand:V2DF 1 "register_operand" "x")
23887          (parallel [(const_int 0)])))]
23888   "TARGET_SSE2"
23889   "movsd\t{%1, %0|%0, %1}"
23890   [(set_attr "type" "ssecvt")
23891    (set_attr "mode" "DF")])
23892
23893 (define_insn "sse2_shufpd"
23894   [(set (match_operand:V2DF 0 "register_operand" "=x")
23895         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23896                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23897                       (match_operand:SI 3 "immediate_operand" "i")]
23898                      UNSPEC_SHUFFLE))]
23899   "TARGET_SSE2"
23900   ;; @@@ check operand order for intel/nonintel syntax
23901   "shufpd\t{%3, %2, %0|%0, %2, %3}"
23902   [(set_attr "type" "ssecvt")
23903    (set_attr "mode" "V2DF")])
23904
23905 (define_insn "sse2_clflush"
23906   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23907                     UNSPECV_CLFLUSH)]
23908   "TARGET_SSE2"
23909   "clflush %0"
23910   [(set_attr "type" "sse")
23911    (set_attr "memory" "unknown")])
23912
23913 (define_expand "sse2_mfence"
23914   [(set (match_dup 0)
23915         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23916   "TARGET_SSE2"
23917 {
23918   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23919   MEM_VOLATILE_P (operands[0]) = 1;
23920 })
23921
23922 (define_insn "*mfence_insn"
23923   [(set (match_operand:BLK 0 "" "")
23924         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23925   "TARGET_SSE2"
23926   "mfence"
23927   [(set_attr "type" "sse")
23928    (set_attr "memory" "unknown")])
23929
23930 (define_expand "sse2_lfence"
23931   [(set (match_dup 0)
23932         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23933   "TARGET_SSE2"
23934 {
23935   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23936   MEM_VOLATILE_P (operands[0]) = 1;
23937 })
23938
23939 (define_insn "*lfence_insn"
23940   [(set (match_operand:BLK 0 "" "")
23941         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23942   "TARGET_SSE2"
23943   "lfence"
23944   [(set_attr "type" "sse")
23945    (set_attr "memory" "unknown")])
23946
23947 ;; SSE3
23948
23949 (define_insn "mwait"
23950   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23951                      (match_operand:SI 1 "register_operand" "c")]
23952                     UNSPECV_MWAIT)]
23953   "TARGET_SSE3"
23954   "mwait\t%0, %1"
23955   [(set_attr "length" "3")])
23956
23957 (define_insn "monitor"
23958   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23959                      (match_operand:SI 1 "register_operand" "c")
23960                      (match_operand:SI 2 "register_operand" "d")]
23961                     UNSPECV_MONITOR)]
23962   "TARGET_SSE3"
23963   "monitor\t%0, %1, %2"
23964   [(set_attr "length" "3")])
23965
23966 ;; SSE3 arithmetic
23967
23968 (define_insn "addsubv4sf3"
23969   [(set (match_operand:V4SF 0 "register_operand" "=x")
23970         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23971                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23972                      UNSPEC_ADDSUB))]
23973   "TARGET_SSE3"
23974   "addsubps\t{%2, %0|%0, %2}"
23975   [(set_attr "type" "sseadd")
23976    (set_attr "mode" "V4SF")])
23977
23978 (define_insn "addsubv2df3"
23979   [(set (match_operand:V2DF 0 "register_operand" "=x")
23980         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23981                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23982                      UNSPEC_ADDSUB))]
23983   "TARGET_SSE3"
23984   "addsubpd\t{%2, %0|%0, %2}"
23985   [(set_attr "type" "sseadd")
23986    (set_attr "mode" "V2DF")])
23987
23988 (define_insn "haddv4sf3"
23989   [(set (match_operand:V4SF 0 "register_operand" "=x")
23990         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23991                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23992                      UNSPEC_HADD))]
23993   "TARGET_SSE3"
23994   "haddps\t{%2, %0|%0, %2}"
23995   [(set_attr "type" "sseadd")
23996    (set_attr "mode" "V4SF")])
23997
23998 (define_insn "haddv2df3"
23999   [(set (match_operand:V2DF 0 "register_operand" "=x")
24000         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24001                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24002                      UNSPEC_HADD))]
24003   "TARGET_SSE3"
24004   "haddpd\t{%2, %0|%0, %2}"
24005   [(set_attr "type" "sseadd")
24006    (set_attr "mode" "V2DF")])
24007
24008 (define_insn "hsubv4sf3"
24009   [(set (match_operand:V4SF 0 "register_operand" "=x")
24010         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24011                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24012                      UNSPEC_HSUB))]
24013   "TARGET_SSE3"
24014   "hsubps\t{%2, %0|%0, %2}"
24015   [(set_attr "type" "sseadd")
24016    (set_attr "mode" "V4SF")])
24017
24018 (define_insn "hsubv2df3"
24019   [(set (match_operand:V2DF 0 "register_operand" "=x")
24020         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24021                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24022                      UNSPEC_HSUB))]
24023   "TARGET_SSE3"
24024   "hsubpd\t{%2, %0|%0, %2}"
24025   [(set_attr "type" "sseadd")
24026    (set_attr "mode" "V2DF")])
24027
24028 (define_insn "movshdup"
24029   [(set (match_operand:V4SF 0 "register_operand" "=x")
24030         (unspec:V4SF
24031          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24032   "TARGET_SSE3"
24033   "movshdup\t{%1, %0|%0, %1}"
24034   [(set_attr "type" "sse")
24035    (set_attr "mode" "V4SF")])
24036
24037 (define_insn "movsldup"
24038   [(set (match_operand:V4SF 0 "register_operand" "=x")
24039         (unspec:V4SF
24040          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24041   "TARGET_SSE3"
24042   "movsldup\t{%1, %0|%0, %1}"
24043   [(set_attr "type" "sse")
24044    (set_attr "mode" "V4SF")])
24045
24046 (define_insn "lddqu"
24047   [(set (match_operand:V16QI 0 "register_operand" "=x")
24048         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24049                        UNSPEC_LDQQU))]
24050   "TARGET_SSE3"
24051   "lddqu\t{%1, %0|%0, %1}"
24052   [(set_attr "type" "ssecvt")
24053    (set_attr "mode" "TI")])
24054
24055 (define_insn "loadddup"
24056   [(set (match_operand:V2DF 0 "register_operand" "=x")
24057         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24058   "TARGET_SSE3"
24059   "movddup\t{%1, %0|%0, %1}"
24060   [(set_attr "type" "ssecvt")
24061    (set_attr "mode" "DF")])
24062
24063 (define_insn "movddup"
24064   [(set (match_operand:V2DF 0 "register_operand" "=x")
24065         (vec_duplicate:V2DF
24066          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24067                         (parallel [(const_int 0)]))))]
24068   "TARGET_SSE3"
24069   "movddup\t{%1, %0|%0, %1}"
24070   [(set_attr "type" "ssecvt")
24071    (set_attr "mode" "DF")])