OSDN Git Service

2004-08-12 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; REP instruction
138    (UNSPEC_REP                  75)
139
140    (UNSPEC_EH_RETURN            76)
141   ])
142
143 (define_constants
144   [(UNSPECV_BLOCKAGE            0)
145    (UNSPECV_STACK_PROBE         10)
146    (UNSPECV_EMMS                31)
147    (UNSPECV_LDMXCSR             37)
148    (UNSPECV_STMXCSR             40)
149    (UNSPECV_FEMMS               46)
150    (UNSPECV_CLFLUSH             57)
151    (UNSPECV_ALIGN               68)
152    (UNSPECV_MONITOR             69)
153    (UNSPECV_MWAIT               70)
154   ])
155
156 ;; Registers by name.
157 (define_constants
158   [(BP_REG                       6)
159    (SP_REG                       7)
160    (FLAGS_REG                   17)
161    (FPSR_REG                    18)
162    (DIRFLAG_REG                 19)
163   ])
164
165 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
166 ;; from i386.c.
167
168 ;; In C guard expressions, put expressions which may be compile-time
169 ;; constants first.  This allows for better optimization.  For
170 ;; example, write "TARGET_64BIT && reload_completed", not
171 ;; "reload_completed && TARGET_64BIT".
172
173 \f
174 ;; Processor type.  This attribute must exactly match the processor_type
175 ;; enumeration in i386.h.
176 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
177   (const (symbol_ref "ix86_tune")))
178
179 ;; A basic instruction type.  Refinements due to arguments to be
180 ;; provided in other attributes.
181 (define_attr "type"
182   "other,multi,
183    alu,alu1,negnot,imov,imovx,lea,
184    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
185    icmp,test,ibr,setcc,icmov,
186    push,pop,call,callv,leave,
187    str,cld,
188    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
189    sselog,sseiadd,sseishft,sseimul,
190    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
191    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
192   (const_string "other"))
193
194 ;; Main data type used by the insn
195 (define_attr "mode"
196   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
197   (const_string "unknown"))
198
199 ;; The CPU unit operations uses.
200 (define_attr "unit" "integer,i387,sse,mmx,unknown"
201   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
202            (const_string "i387")
203          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
204                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
205            (const_string "sse")
206          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
207            (const_string "mmx")
208          (eq_attr "type" "other")
209            (const_string "unknown")]
210          (const_string "integer")))
211
212 ;; The (bounding maximum) length of an instruction immediate.
213 (define_attr "length_immediate" ""
214   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
215            (const_int 0)
216          (eq_attr "unit" "i387,sse,mmx")
217            (const_int 0)
218          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
219                           imul,icmp,push,pop")
220            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
221          (eq_attr "type" "imov,test")
222            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
223          (eq_attr "type" "call")
224            (if_then_else (match_operand 0 "constant_call_address_operand" "")
225              (const_int 4)
226              (const_int 0))
227          (eq_attr "type" "callv")
228            (if_then_else (match_operand 1 "constant_call_address_operand" "")
229              (const_int 4)
230              (const_int 0))
231          ;; We don't know the size before shorten_branches.  Expect
232          ;; the instruction to fit for better scheduling.
233          (eq_attr "type" "ibr")
234            (const_int 1)
235          ]
236          (symbol_ref "/* Update immediate_length and other attributes! */
237                       abort(),1")))
238
239 ;; The (bounding maximum) length of an instruction address.
240 (define_attr "length_address" ""
241   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
242            (const_int 0)
243          (and (eq_attr "type" "call")
244               (match_operand 0 "constant_call_address_operand" ""))
245              (const_int 0)
246          (and (eq_attr "type" "callv")
247               (match_operand 1 "constant_call_address_operand" ""))
248              (const_int 0)
249          ]
250          (symbol_ref "ix86_attr_length_address_default (insn)")))
251
252 ;; Set when length prefix is used.
253 (define_attr "prefix_data16" ""
254   (if_then_else (ior (eq_attr "mode" "HI")
255                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
256     (const_int 1)
257     (const_int 0)))
258
259 ;; Set when string REP prefix is used.
260 (define_attr "prefix_rep" "" 
261   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when 0f opcode prefix is used.
266 (define_attr "prefix_0f" ""
267   (if_then_else 
268     (ior (eq_attr "type" "imovx,setcc,icmov")
269          (eq_attr "unit" "sse,mmx"))
270     (const_int 1)
271     (const_int 0)))
272
273 ;; Set when REX opcode prefix is used.
274 (define_attr "prefix_rex" ""
275   (cond [(and (eq_attr "mode" "DI")
276               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
277            (const_int 1)
278          (and (eq_attr "mode" "QI")
279               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
280                   (const_int 0)))
281            (const_int 1)
282          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
283              (const_int 0))
284            (const_int 1)
285         ]
286         (const_int 0)))
287
288 ;; Set when modrm byte is used.
289 (define_attr "modrm" ""
290   (cond [(eq_attr "type" "str,cld,leave")
291            (const_int 0)
292          (eq_attr "unit" "i387")
293            (const_int 0)
294          (and (eq_attr "type" "incdec")
295               (ior (match_operand:SI 1 "register_operand" "")
296                    (match_operand:HI 1 "register_operand" "")))
297            (const_int 0)
298          (and (eq_attr "type" "push")
299               (not (match_operand 1 "memory_operand" "")))
300            (const_int 0)
301          (and (eq_attr "type" "pop")
302               (not (match_operand 0 "memory_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "imov")
305               (and (match_operand 0 "register_operand" "")
306                    (match_operand 1 "immediate_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "call")
309               (match_operand 0 "constant_call_address_operand" ""))
310              (const_int 0)
311          (and (eq_attr "type" "callv")
312               (match_operand 1 "constant_call_address_operand" ""))
313              (const_int 0)
314          ]
315          (const_int 1)))
316
317 ;; The (bounding maximum) length of an instruction in bytes.
318 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
319 ;; to split it and compute proper length as for other insns.
320 (define_attr "length" ""
321   (cond [(eq_attr "type" "other,multi,fistp")
322            (const_int 16)
323          (eq_attr "type" "fcmp")
324            (const_int 4)
325          (eq_attr "unit" "i387")
326            (plus (const_int 2)
327                  (plus (attr "prefix_data16")
328                        (attr "length_address")))]
329          (plus (plus (attr "modrm")
330                      (plus (attr "prefix_0f")
331                            (plus (attr "prefix_rex")
332                                  (const_int 1))))
333                (plus (attr "prefix_rep")
334                      (plus (attr "prefix_data16")
335                            (plus (attr "length_immediate")
336                                  (attr "length_address")))))))
337
338 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
339 ;; `store' if there is a simple memory reference therein, or `unknown'
340 ;; if the instruction is complex.
341
342 (define_attr "memory" "none,load,store,both,unknown"
343   (cond [(eq_attr "type" "other,multi,str")
344            (const_string "unknown")
345          (eq_attr "type" "lea,fcmov,fpspc,cld")
346            (const_string "none")
347          (eq_attr "type" "fistp,leave")
348            (const_string "both")
349          (eq_attr "type" "push")
350            (if_then_else (match_operand 1 "memory_operand" "")
351              (const_string "both")
352              (const_string "store"))
353          (eq_attr "type" "pop")
354            (if_then_else (match_operand 0 "memory_operand" "")
355              (const_string "both")
356              (const_string "load"))
357          (eq_attr "type" "setcc")
358            (if_then_else (match_operand 0 "memory_operand" "")
359              (const_string "store")
360              (const_string "none"))
361          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
362            (if_then_else (ior (match_operand 0 "memory_operand" "")
363                               (match_operand 1 "memory_operand" ""))
364              (const_string "load")
365              (const_string "none"))
366          (eq_attr "type" "ibr")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "load")
369              (const_string "none"))
370          (eq_attr "type" "call")
371            (if_then_else (match_operand 0 "constant_call_address_operand" "")
372              (const_string "none")
373              (const_string "load"))
374          (eq_attr "type" "callv")
375            (if_then_else (match_operand 1 "constant_call_address_operand" "")
376              (const_string "none")
377              (const_string "load"))
378          (and (eq_attr "type" "alu1,negnot,ishift1")
379               (match_operand 1 "memory_operand" ""))
380            (const_string "both")
381          (and (match_operand 0 "memory_operand" "")
382               (match_operand 1 "memory_operand" ""))
383            (const_string "both")
384          (match_operand 0 "memory_operand" "")
385            (const_string "store")
386          (match_operand 1 "memory_operand" "")
387            (const_string "load")
388          (and (eq_attr "type"
389                  "!alu1,negnot,ishift1,
390                    imov,imovx,icmp,test,
391                    fmov,fcmp,fsgn,
392                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
393                    mmx,mmxmov,mmxcmp,mmxcvt")
394               (match_operand 2 "memory_operand" ""))
395            (const_string "load")
396          (and (eq_attr "type" "icmov")
397               (match_operand 3 "memory_operand" ""))
398            (const_string "load")
399         ]
400         (const_string "none")))
401
402 ;; Indicates if an instruction has both an immediate and a displacement.
403
404 (define_attr "imm_disp" "false,true,unknown"
405   (cond [(eq_attr "type" "other,multi")
406            (const_string "unknown")
407          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
408               (and (match_operand 0 "memory_displacement_operand" "")
409                    (match_operand 1 "immediate_operand" "")))
410            (const_string "true")
411          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
412               (and (match_operand 0 "memory_displacement_operand" "")
413                    (match_operand 2 "immediate_operand" "")))
414            (const_string "true")
415         ]
416         (const_string "false")))
417
418 ;; Indicates if an FP operation has an integer source.
419
420 (define_attr "fp_int_src" "false,true"
421   (const_string "false"))
422
423 ;; Describe a user's asm statement.
424 (define_asm_attributes
425   [(set_attr "length" "128")
426    (set_attr "type" "multi")])
427 \f
428 ;; Scheduling descriptions
429
430 (include "pentium.md")
431 (include "ppro.md")
432 (include "k6.md")
433 (include "athlon.md")
434
435 \f
436 ;; Operand and operator predicates
437
438 (include "predicates.md")
439
440 \f
441 ;; Compare instructions.
442
443 ;; All compare insns have expanders that save the operands away without
444 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
445 ;; after the cmp) will actually emit the cmpM.
446
447 (define_expand "cmpdi"
448   [(set (reg:CC FLAGS_REG)
449         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
450                     (match_operand:DI 1 "x86_64_general_operand" "")))]
451   ""
452 {
453   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
454     operands[0] = force_reg (DImode, operands[0]);
455   ix86_compare_op0 = operands[0];
456   ix86_compare_op1 = operands[1];
457   DONE;
458 })
459
460 (define_expand "cmpsi"
461   [(set (reg:CC FLAGS_REG)
462         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
463                     (match_operand:SI 1 "general_operand" "")))]
464   ""
465 {
466   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
467     operands[0] = force_reg (SImode, operands[0]);
468   ix86_compare_op0 = operands[0];
469   ix86_compare_op1 = operands[1];
470   DONE;
471 })
472
473 (define_expand "cmphi"
474   [(set (reg:CC FLAGS_REG)
475         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
476                     (match_operand:HI 1 "general_operand" "")))]
477   ""
478 {
479   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
480     operands[0] = force_reg (HImode, operands[0]);
481   ix86_compare_op0 = operands[0];
482   ix86_compare_op1 = operands[1];
483   DONE;
484 })
485
486 (define_expand "cmpqi"
487   [(set (reg:CC FLAGS_REG)
488         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
489                     (match_operand:QI 1 "general_operand" "")))]
490   "TARGET_QIMODE_MATH"
491 {
492   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
493     operands[0] = force_reg (QImode, operands[0]);
494   ix86_compare_op0 = operands[0];
495   ix86_compare_op1 = operands[1];
496   DONE;
497 })
498
499 (define_insn "cmpdi_ccno_1_rex64"
500   [(set (reg 17)
501         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
502                  (match_operand:DI 1 "const0_operand" "n,n")))]
503   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
504   "@
505    test{q}\t{%0, %0|%0, %0}
506    cmp{q}\t{%1, %0|%0, %1}"
507   [(set_attr "type" "test,icmp")
508    (set_attr "length_immediate" "0,1")
509    (set_attr "mode" "DI")])
510
511 (define_insn "*cmpdi_minus_1_rex64"
512   [(set (reg 17)
513         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
514                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
515                  (const_int 0)))]
516   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
517   "cmp{q}\t{%1, %0|%0, %1}"
518   [(set_attr "type" "icmp")
519    (set_attr "mode" "DI")])
520
521 (define_expand "cmpdi_1_rex64"
522   [(set (reg:CC FLAGS_REG)
523         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
524                     (match_operand:DI 1 "general_operand" "")))]
525   "TARGET_64BIT"
526   "")
527
528 (define_insn "cmpdi_1_insn_rex64"
529   [(set (reg 17)
530         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
531                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
532   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
533   "cmp{q}\t{%1, %0|%0, %1}"
534   [(set_attr "type" "icmp")
535    (set_attr "mode" "DI")])
536
537
538 (define_insn "*cmpsi_ccno_1"
539   [(set (reg 17)
540         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
541                  (match_operand:SI 1 "const0_operand" "n,n")))]
542   "ix86_match_ccmode (insn, CCNOmode)"
543   "@
544    test{l}\t{%0, %0|%0, %0}
545    cmp{l}\t{%1, %0|%0, %1}"
546   [(set_attr "type" "test,icmp")
547    (set_attr "length_immediate" "0,1")
548    (set_attr "mode" "SI")])
549
550 (define_insn "*cmpsi_minus_1"
551   [(set (reg 17)
552         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
553                            (match_operand:SI 1 "general_operand" "ri,mr"))
554                  (const_int 0)))]
555   "ix86_match_ccmode (insn, CCGOCmode)"
556   "cmp{l}\t{%1, %0|%0, %1}"
557   [(set_attr "type" "icmp")
558    (set_attr "mode" "SI")])
559
560 (define_expand "cmpsi_1"
561   [(set (reg:CC FLAGS_REG)
562         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
563                     (match_operand:SI 1 "general_operand" "ri,mr")))]
564   ""
565   "")
566
567 (define_insn "*cmpsi_1_insn"
568   [(set (reg 17)
569         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
570                  (match_operand:SI 1 "general_operand" "ri,mr")))]
571   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
572     && ix86_match_ccmode (insn, CCmode)"
573   "cmp{l}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "icmp")
575    (set_attr "mode" "SI")])
576
577 (define_insn "*cmphi_ccno_1"
578   [(set (reg 17)
579         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
580                  (match_operand:HI 1 "const0_operand" "n,n")))]
581   "ix86_match_ccmode (insn, CCNOmode)"
582   "@
583    test{w}\t{%0, %0|%0, %0}
584    cmp{w}\t{%1, %0|%0, %1}"
585   [(set_attr "type" "test,icmp")
586    (set_attr "length_immediate" "0,1")
587    (set_attr "mode" "HI")])
588
589 (define_insn "*cmphi_minus_1"
590   [(set (reg 17)
591         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
592                            (match_operand:HI 1 "general_operand" "ri,mr"))
593                  (const_int 0)))]
594   "ix86_match_ccmode (insn, CCGOCmode)"
595   "cmp{w}\t{%1, %0|%0, %1}"
596   [(set_attr "type" "icmp")
597    (set_attr "mode" "HI")])
598
599 (define_insn "*cmphi_1"
600   [(set (reg 17)
601         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
602                  (match_operand:HI 1 "general_operand" "ri,mr")))]
603   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
604    && ix86_match_ccmode (insn, CCmode)"
605   "cmp{w}\t{%1, %0|%0, %1}"
606   [(set_attr "type" "icmp")
607    (set_attr "mode" "HI")])
608
609 (define_insn "*cmpqi_ccno_1"
610   [(set (reg 17)
611         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
612                  (match_operand:QI 1 "const0_operand" "n,n")))]
613   "ix86_match_ccmode (insn, CCNOmode)"
614   "@
615    test{b}\t{%0, %0|%0, %0}
616    cmp{b}\t{$0, %0|%0, 0}"
617   [(set_attr "type" "test,icmp")
618    (set_attr "length_immediate" "0,1")
619    (set_attr "mode" "QI")])
620
621 (define_insn "*cmpqi_1"
622   [(set (reg 17)
623         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
624                  (match_operand:QI 1 "general_operand" "qi,mq")))]
625   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
626     && ix86_match_ccmode (insn, CCmode)"
627   "cmp{b}\t{%1, %0|%0, %1}"
628   [(set_attr "type" "icmp")
629    (set_attr "mode" "QI")])
630
631 (define_insn "*cmpqi_minus_1"
632   [(set (reg 17)
633         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
634                            (match_operand:QI 1 "general_operand" "qi,mq"))
635                  (const_int 0)))]
636   "ix86_match_ccmode (insn, CCGOCmode)"
637   "cmp{b}\t{%1, %0|%0, %1}"
638   [(set_attr "type" "icmp")
639    (set_attr "mode" "QI")])
640
641 (define_insn "*cmpqi_ext_1"
642   [(set (reg 17)
643         (compare
644           (match_operand:QI 0 "general_operand" "Qm")
645           (subreg:QI
646             (zero_extract:SI
647               (match_operand 1 "ext_register_operand" "Q")
648               (const_int 8)
649               (const_int 8)) 0)))]
650   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
651   "cmp{b}\t{%h1, %0|%0, %h1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1_rex64"
656   [(set (reg 17)
657         (compare
658           (match_operand:QI 0 "register_operand" "Q")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_2"
670   [(set (reg 17)
671         (compare
672           (subreg:QI
673             (zero_extract:SI
674               (match_operand 0 "ext_register_operand" "Q")
675               (const_int 8)
676               (const_int 8)) 0)
677           (match_operand:QI 1 "const0_operand" "n")))]
678   "ix86_match_ccmode (insn, CCNOmode)"
679   "test{b}\t%h0, %h0"
680   [(set_attr "type" "test")
681    (set_attr "length_immediate" "0")
682    (set_attr "mode" "QI")])
683
684 (define_expand "cmpqi_ext_3"
685   [(set (reg:CC FLAGS_REG)
686         (compare:CC
687           (subreg:QI
688             (zero_extract:SI
689               (match_operand 0 "ext_register_operand" "")
690               (const_int 8)
691               (const_int 8)) 0)
692           (match_operand:QI 1 "general_operand" "")))]
693   ""
694   "")
695
696 (define_insn "cmpqi_ext_3_insn"
697   [(set (reg 17)
698         (compare
699           (subreg:QI
700             (zero_extract:SI
701               (match_operand 0 "ext_register_operand" "Q")
702               (const_int 8)
703               (const_int 8)) 0)
704           (match_operand:QI 1 "general_operand" "Qmn")))]
705   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%1, %h0|%h0, %1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "cmpqi_ext_3_insn_rex64"
711   [(set (reg 17)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
719   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "*cmpqi_ext_4"
725   [(set (reg 17)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (subreg:QI
733             (zero_extract:SI
734               (match_operand 1 "ext_register_operand" "Q")
735               (const_int 8)
736               (const_int 8)) 0)))]
737   "ix86_match_ccmode (insn, CCmode)"
738   "cmp{b}\t{%h1, %h0|%h0, %h1}"
739   [(set_attr "type" "icmp")
740    (set_attr "mode" "QI")])
741
742 ;; These implement float point compares.
743 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
744 ;; which would allow mix and match FP modes on the compares.  Which is what
745 ;; the old patterns did, but with many more of them.
746
747 (define_expand "cmpxf"
748   [(set (reg:CC FLAGS_REG)
749         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
750                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
751   "TARGET_80387"
752 {
753   ix86_compare_op0 = operands[0];
754   ix86_compare_op1 = operands[1];
755   DONE;
756 })
757
758 (define_expand "cmpdf"
759   [(set (reg:CC FLAGS_REG)
760         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
761                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
762   "TARGET_80387 || TARGET_SSE2"
763 {
764   ix86_compare_op0 = operands[0];
765   ix86_compare_op1 = operands[1];
766   DONE;
767 })
768
769 (define_expand "cmpsf"
770   [(set (reg:CC FLAGS_REG)
771         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
772                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
773   "TARGET_80387 || TARGET_SSE"
774 {
775   ix86_compare_op0 = operands[0];
776   ix86_compare_op1 = operands[1];
777   DONE;
778 })
779
780 ;; FP compares, step 1:
781 ;; Set the FP condition codes.
782 ;;
783 ;; CCFPmode     compare with exceptions
784 ;; CCFPUmode    compare with no exceptions
785
786 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
787 ;; and that fp moves clobber the condition codes, and that there is
788 ;; currently no way to describe this fact to reg-stack.  So there are
789 ;; no splitters yet for this.
790
791 ;; %%% YIKES!  This scheme does not retain a strong connection between 
792 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
793 ;; work!  Only allow tos/mem with tos in op 0.
794 ;;
795 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
796 ;; things aren't as bad as they sound...
797
798 (define_insn "*cmpfp_0"
799   [(set (match_operand:HI 0 "register_operand" "=a")
800         (unspec:HI
801           [(compare:CCFP (match_operand 1 "register_operand" "f")
802                          (match_operand 2 "const0_operand" "X"))]
803           UNSPEC_FNSTSW))]
804   "TARGET_80387
805    && FLOAT_MODE_P (GET_MODE (operands[1]))
806    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
807 {
808   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
809     return "ftst\;fnstsw\t%0\;fstp\t%y0";
810   else
811     return "ftst\;fnstsw\t%0";
812 }
813   [(set_attr "type" "multi")
814    (set (attr "mode")
815      (cond [(match_operand:SF 1 "" "")
816               (const_string "SF")
817             (match_operand:DF 1 "" "")
818               (const_string "DF")
819            ]
820            (const_string "XF")))])
821
822 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
823 ;; used to manage the reg stack popping would not be preserved.
824
825 (define_insn "*cmpfp_2_sf"
826   [(set (reg:CCFP FPSR_REG)
827         (compare:CCFP
828           (match_operand:SF 0 "register_operand" "f")
829           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
830   "TARGET_80387"
831   "* return output_fp_compare (insn, operands, 0, 0);"
832   [(set_attr "type" "fcmp")
833    (set_attr "mode" "SF")])
834
835 (define_insn "*cmpfp_2_sf_1"
836   [(set (match_operand:HI 0 "register_operand" "=a")
837         (unspec:HI
838           [(compare:CCFP
839              (match_operand:SF 1 "register_operand" "f")
840              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
841           UNSPEC_FNSTSW))]
842   "TARGET_80387"
843   "* return output_fp_compare (insn, operands, 2, 0);"
844   [(set_attr "type" "fcmp")
845    (set_attr "mode" "SF")])
846
847 (define_insn "*cmpfp_2_df"
848   [(set (reg:CCFP FPSR_REG)
849         (compare:CCFP
850           (match_operand:DF 0 "register_operand" "f")
851           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
852   "TARGET_80387"
853   "* return output_fp_compare (insn, operands, 0, 0);"
854   [(set_attr "type" "fcmp")
855    (set_attr "mode" "DF")])
856
857 (define_insn "*cmpfp_2_df_1"
858   [(set (match_operand:HI 0 "register_operand" "=a")
859         (unspec:HI
860           [(compare:CCFP
861              (match_operand:DF 1 "register_operand" "f")
862              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
863           UNSPEC_FNSTSW))]
864   "TARGET_80387"
865   "* return output_fp_compare (insn, operands, 2, 0);"
866   [(set_attr "type" "multi")
867    (set_attr "mode" "DF")])
868
869 (define_insn "*cmpfp_2_xf"
870   [(set (reg:CCFP FPSR_REG)
871         (compare:CCFP
872           (match_operand:XF 0 "register_operand" "f")
873           (match_operand:XF 1 "register_operand" "f")))]
874   "TARGET_80387"
875   "* return output_fp_compare (insn, operands, 0, 0);"
876   [(set_attr "type" "fcmp")
877    (set_attr "mode" "XF")])
878
879 (define_insn "*cmpfp_2_xf_1"
880   [(set (match_operand:HI 0 "register_operand" "=a")
881         (unspec:HI
882           [(compare:CCFP
883              (match_operand:XF 1 "register_operand" "f")
884              (match_operand:XF 2 "register_operand" "f"))]
885           UNSPEC_FNSTSW))]
886   "TARGET_80387"
887   "* return output_fp_compare (insn, operands, 2, 0);"
888   [(set_attr "type" "multi")
889    (set_attr "mode" "XF")])
890
891 (define_insn "*cmpfp_2u"
892   [(set (reg:CCFPU FPSR_REG)
893         (compare:CCFPU
894           (match_operand 0 "register_operand" "f")
895           (match_operand 1 "register_operand" "f")))]
896   "TARGET_80387
897    && FLOAT_MODE_P (GET_MODE (operands[0]))
898    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
899   "* return output_fp_compare (insn, operands, 0, 1);"
900   [(set_attr "type" "fcmp")
901    (set (attr "mode")
902      (cond [(match_operand:SF 1 "" "")
903               (const_string "SF")
904             (match_operand:DF 1 "" "")
905               (const_string "DF")
906            ]
907            (const_string "XF")))])
908
909 (define_insn "*cmpfp_2u_1"
910   [(set (match_operand:HI 0 "register_operand" "=a")
911         (unspec:HI
912           [(compare:CCFPU
913              (match_operand 1 "register_operand" "f")
914              (match_operand 2 "register_operand" "f"))]
915           UNSPEC_FNSTSW))]
916   "TARGET_80387
917    && FLOAT_MODE_P (GET_MODE (operands[1]))
918    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
919   "* return output_fp_compare (insn, operands, 2, 1);"
920   [(set_attr "type" "multi")
921    (set (attr "mode")
922      (cond [(match_operand:SF 1 "" "")
923               (const_string "SF")
924             (match_operand:DF 1 "" "")
925               (const_string "DF")
926            ]
927            (const_string "XF")))])
928
929 ;; Patterns to match the SImode-in-memory ficom instructions.
930 ;;
931 ;; %%% Play games with accepting gp registers, as otherwise we have to
932 ;; force them to memory during rtl generation, which is no good.  We
933 ;; can get rid of this once we teach reload to do memory input reloads 
934 ;; via pushes.
935
936 (define_insn "*ficom_1"
937   [(set (reg:CCFP FPSR_REG)
938         (compare:CCFP
939           (match_operand 0 "register_operand" "f,f")
940           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
941   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
942    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
943   "#")
944
945 ;; Split the not-really-implemented gp register case into a
946 ;; push-op-pop sequence.
947 ;;
948 ;; %%% This is most efficient, but am I gonna get in trouble
949 ;; for separating cc0_setter and cc0_user?
950
951 (define_split
952   [(set (reg:CCFP FPSR_REG)
953         (compare:CCFP
954           (match_operand:SF 0 "register_operand" "")
955           (float (match_operand:SI 1 "register_operand" ""))))]
956   "0 && TARGET_80387 && reload_completed"
957   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 1))
958    (set (reg:CCFP FPSR_REG) (compare:CCFP (match_dup 0) (match_dup 2)))
959    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
960               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
961   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
962    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
963
964 ;; FP compares, step 2
965 ;; Move the fpsw to ax.
966
967 (define_insn "x86_fnstsw_1"
968   [(set (match_operand:HI 0 "register_operand" "=a")
969         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
970   "TARGET_80387"
971   "fnstsw\t%0"
972   [(set_attr "length" "2")
973    (set_attr "mode" "SI")
974    (set_attr "unit" "i387")])
975
976 ;; FP compares, step 3
977 ;; Get ax into flags, general case.
978
979 (define_insn "x86_sahf_1"
980   [(set (reg:CC FLAGS_REG)
981         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
982   "!TARGET_64BIT"
983   "sahf"
984   [(set_attr "length" "1")
985    (set_attr "athlon_decode" "vector")
986    (set_attr "mode" "SI")])
987
988 ;; Pentium Pro can do steps 1 through 3 in one go.
989
990 (define_insn "*cmpfp_i"
991   [(set (reg:CCFP FLAGS_REG)
992         (compare:CCFP (match_operand 0 "register_operand" "f")
993                       (match_operand 1 "register_operand" "f")))]
994   "TARGET_80387 && TARGET_CMOVE
995    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
996    && FLOAT_MODE_P (GET_MODE (operands[0]))
997    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
998   "* return output_fp_compare (insn, operands, 1, 0);"
999   [(set_attr "type" "fcmp")
1000    (set (attr "mode")
1001      (cond [(match_operand:SF 1 "" "")
1002               (const_string "SF")
1003             (match_operand:DF 1 "" "")
1004               (const_string "DF")
1005            ]
1006            (const_string "XF")))
1007    (set_attr "athlon_decode" "vector")])
1008
1009 (define_insn "*cmpfp_i_sse"
1010   [(set (reg:CCFP FLAGS_REG)
1011         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1012                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1013   "TARGET_80387
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1016   "* return output_fp_compare (insn, operands, 1, 0);"
1017   [(set_attr "type" "fcmp,ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")])
1023
1024 (define_insn "*cmpfp_i_sse_only"
1025   [(set (reg:CCFP FLAGS_REG)
1026         (compare:CCFP (match_operand 0 "register_operand" "x")
1027                       (match_operand 1 "nonimmediate_operand" "xm")))]
1028   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1029    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1030   "* return output_fp_compare (insn, operands, 1, 0);"
1031   [(set_attr "type" "ssecomi")
1032    (set (attr "mode")
1033      (if_then_else (match_operand:SF 1 "" "")
1034         (const_string "SF")
1035         (const_string "DF")))
1036    (set_attr "athlon_decode" "vector")])
1037
1038 (define_insn "*cmpfp_iu"
1039   [(set (reg:CCFPU FLAGS_REG)
1040         (compare:CCFPU (match_operand 0 "register_operand" "f")
1041                        (match_operand 1 "register_operand" "f")))]
1042   "TARGET_80387 && TARGET_CMOVE
1043    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1044    && FLOAT_MODE_P (GET_MODE (operands[0]))
1045    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1046   "* return output_fp_compare (insn, operands, 1, 1);"
1047   [(set_attr "type" "fcmp")
1048    (set (attr "mode")
1049      (cond [(match_operand:SF 1 "" "")
1050               (const_string "SF")
1051             (match_operand:DF 1 "" "")
1052               (const_string "DF")
1053            ]
1054            (const_string "XF")))
1055    (set_attr "athlon_decode" "vector")])
1056
1057 (define_insn "*cmpfp_iu_sse"
1058   [(set (reg:CCFPU FLAGS_REG)
1059         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1060                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1061   "TARGET_80387
1062    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1063    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1064   "* return output_fp_compare (insn, operands, 1, 1);"
1065   [(set_attr "type" "fcmp,ssecomi")
1066    (set (attr "mode")
1067      (if_then_else (match_operand:SF 1 "" "")
1068         (const_string "SF")
1069         (const_string "DF")))
1070    (set_attr "athlon_decode" "vector")])
1071
1072 (define_insn "*cmpfp_iu_sse_only"
1073   [(set (reg:CCFPU FLAGS_REG)
1074         (compare:CCFPU (match_operand 0 "register_operand" "x")
1075                        (match_operand 1 "nonimmediate_operand" "xm")))]
1076   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1077    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1078   "* return output_fp_compare (insn, operands, 1, 1);"
1079   [(set_attr "type" "ssecomi")
1080    (set (attr "mode")
1081      (if_then_else (match_operand:SF 1 "" "")
1082         (const_string "SF")
1083         (const_string "DF")))
1084    (set_attr "athlon_decode" "vector")])
1085 \f
1086 ;; Move instructions.
1087
1088 ;; General case of fullword move.
1089
1090 (define_expand "movsi"
1091   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1092         (match_operand:SI 1 "general_operand" ""))]
1093   ""
1094   "ix86_expand_move (SImode, operands); DONE;")
1095
1096 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1097 ;; general_operand.
1098 ;;
1099 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1100 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1101 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1102 ;; targets without our curiosities, and it is just as easy to represent
1103 ;; this differently.
1104
1105 (define_insn "*pushsi2"
1106   [(set (match_operand:SI 0 "push_operand" "=<")
1107         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1108   "!TARGET_64BIT"
1109   "push{l}\t%1"
1110   [(set_attr "type" "push")
1111    (set_attr "mode" "SI")])
1112
1113 ;; For 64BIT abi we always round up to 8 bytes.
1114 (define_insn "*pushsi2_rex64"
1115   [(set (match_operand:SI 0 "push_operand" "=X")
1116         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1117   "TARGET_64BIT"
1118   "push{q}\t%q1"
1119   [(set_attr "type" "push")
1120    (set_attr "mode" "SI")])
1121
1122 (define_insn "*pushsi2_prologue"
1123   [(set (match_operand:SI 0 "push_operand" "=<")
1124         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1125    (clobber (mem:BLK (scratch)))]
1126   "!TARGET_64BIT"
1127   "push{l}\t%1"
1128   [(set_attr "type" "push")
1129    (set_attr "mode" "SI")])
1130
1131 (define_insn "*popsi1_epilogue"
1132   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1133         (mem:SI (reg:SI SP_REG)))
1134    (set (reg:SI SP_REG)
1135         (plus:SI (reg:SI SP_REG) (const_int 4)))
1136    (clobber (mem:BLK (scratch)))]
1137   "!TARGET_64BIT"
1138   "pop{l}\t%0"
1139   [(set_attr "type" "pop")
1140    (set_attr "mode" "SI")])
1141
1142 (define_insn "popsi1"
1143   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144         (mem:SI (reg:SI SP_REG)))
1145    (set (reg:SI SP_REG)
1146         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1147   "!TARGET_64BIT"
1148   "pop{l}\t%0"
1149   [(set_attr "type" "pop")
1150    (set_attr "mode" "SI")])
1151
1152 (define_insn "*movsi_xor"
1153   [(set (match_operand:SI 0 "register_operand" "=r")
1154         (match_operand:SI 1 "const0_operand" "i"))
1155    (clobber (reg:CC FLAGS_REG))]
1156   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1157   "xor{l}\t{%0, %0|%0, %0}"
1158   [(set_attr "type" "alu1")
1159    (set_attr "mode" "SI")
1160    (set_attr "length_immediate" "0")])
1161  
1162 (define_insn "*movsi_or"
1163   [(set (match_operand:SI 0 "register_operand" "=r")
1164         (match_operand:SI 1 "immediate_operand" "i"))
1165    (clobber (reg:CC FLAGS_REG))]
1166   "reload_completed
1167    && operands[1] == constm1_rtx
1168    && (TARGET_PENTIUM || optimize_size)"
1169 {
1170   operands[1] = constm1_rtx;
1171   return "or{l}\t{%1, %0|%0, %1}";
1172 }
1173   [(set_attr "type" "alu1")
1174    (set_attr "mode" "SI")
1175    (set_attr "length_immediate" "1")])
1176
1177 (define_insn "*movsi_1"
1178   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1179         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1180   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1181    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1182 {
1183   switch (get_attr_type (insn))
1184     {
1185     case TYPE_SSEMOV:
1186       if (get_attr_mode (insn) == MODE_TI)
1187         return "movdqa\t{%1, %0|%0, %1}";
1188       return "movd\t{%1, %0|%0, %1}";
1189
1190     case TYPE_MMXMOV:
1191       if (get_attr_mode (insn) == MODE_DI)
1192         return "movq\t{%1, %0|%0, %1}";
1193       return "movd\t{%1, %0|%0, %1}";
1194
1195     case TYPE_LEA:
1196       return "lea{l}\t{%1, %0|%0, %1}";
1197
1198     default:
1199       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1200         abort();
1201       return "mov{l}\t{%1, %0|%0, %1}";
1202     }
1203 }
1204   [(set (attr "type")
1205      (cond [(eq_attr "alternative" "2,3,4")
1206               (const_string "mmxmov")
1207             (eq_attr "alternative" "5,6,7")
1208               (const_string "ssemov")
1209             (and (ne (symbol_ref "flag_pic") (const_int 0))
1210                  (match_operand:SI 1 "symbolic_operand" ""))
1211               (const_string "lea")
1212            ]
1213            (const_string "imov")))
1214    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1215
1216 (define_insn "*movsi_1_nointernunit"
1217   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1218         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1219   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1220    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1221 {
1222   switch (get_attr_type (insn))
1223     {
1224     case TYPE_SSEMOV:
1225       if (get_attr_mode (insn) == MODE_TI)
1226         return "movdqa\t{%1, %0|%0, %1}";
1227       return "movd\t{%1, %0|%0, %1}";
1228
1229     case TYPE_MMXMOV:
1230       if (get_attr_mode (insn) == MODE_DI)
1231         return "movq\t{%1, %0|%0, %1}";
1232       return "movd\t{%1, %0|%0, %1}";
1233
1234     case TYPE_LEA:
1235       return "lea{l}\t{%1, %0|%0, %1}";
1236
1237     default:
1238       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1239         abort();
1240       return "mov{l}\t{%1, %0|%0, %1}";
1241     }
1242 }
1243   [(set (attr "type")
1244      (cond [(eq_attr "alternative" "2,3,4")
1245               (const_string "mmxmov")
1246             (eq_attr "alternative" "5,6,7")
1247               (const_string "ssemov")
1248             (and (ne (symbol_ref "flag_pic") (const_int 0))
1249                  (match_operand:SI 1 "symbolic_operand" ""))
1250               (const_string "lea")
1251            ]
1252            (const_string "imov")))
1253    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1254
1255 ;; Stores and loads of ax to arbitrary constant address.
1256 ;; We fake an second form of instruction to force reload to load address
1257 ;; into register when rax is not available
1258 (define_insn "*movabssi_1_rex64"
1259   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1260         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1261   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1262   "@
1263    movabs{l}\t{%1, %P0|%P0, %1}
1264    mov{l}\t{%1, %a0|%a0, %1}"
1265   [(set_attr "type" "imov")
1266    (set_attr "modrm" "0,*")
1267    (set_attr "length_address" "8,0")
1268    (set_attr "length_immediate" "0,*")
1269    (set_attr "memory" "store")
1270    (set_attr "mode" "SI")])
1271
1272 (define_insn "*movabssi_2_rex64"
1273   [(set (match_operand:SI 0 "register_operand" "=a,r")
1274         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1275   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1276   "@
1277    movabs{l}\t{%P1, %0|%0, %P1}
1278    mov{l}\t{%a1, %0|%0, %a1}"
1279   [(set_attr "type" "imov")
1280    (set_attr "modrm" "0,*")
1281    (set_attr "length_address" "8,0")
1282    (set_attr "length_immediate" "0")
1283    (set_attr "memory" "load")
1284    (set_attr "mode" "SI")])
1285
1286 (define_insn "*swapsi"
1287   [(set (match_operand:SI 0 "register_operand" "+r")
1288         (match_operand:SI 1 "register_operand" "+r"))
1289    (set (match_dup 1)
1290         (match_dup 0))]
1291   ""
1292   "xchg{l}\t%1, %0"
1293   [(set_attr "type" "imov")
1294    (set_attr "pent_pair" "np")
1295    (set_attr "athlon_decode" "vector")
1296    (set_attr "mode" "SI")
1297    (set_attr "modrm" "0")])
1298
1299 (define_expand "movhi"
1300   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1301         (match_operand:HI 1 "general_operand" ""))]
1302   ""
1303   "ix86_expand_move (HImode, operands); DONE;")
1304
1305 (define_insn "*pushhi2"
1306   [(set (match_operand:HI 0 "push_operand" "=<,<")
1307         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1308   "!TARGET_64BIT"
1309   "@
1310    push{w}\t{|WORD PTR }%1
1311    push{w}\t%1"
1312   [(set_attr "type" "push")
1313    (set_attr "mode" "HI")])
1314
1315 ;; For 64BIT abi we always round up to 8 bytes.
1316 (define_insn "*pushhi2_rex64"
1317   [(set (match_operand:HI 0 "push_operand" "=X")
1318         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1319   "TARGET_64BIT"
1320   "push{q}\t%q1"
1321   [(set_attr "type" "push")
1322    (set_attr "mode" "QI")])
1323
1324 (define_insn "*movhi_1"
1325   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1326         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1327   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1328 {
1329   switch (get_attr_type (insn))
1330     {
1331     case TYPE_IMOVX:
1332       /* movzwl is faster than movw on p2 due to partial word stalls,
1333          though not as fast as an aligned movl.  */
1334       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1335     default:
1336       if (get_attr_mode (insn) == MODE_SI)
1337         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1338       else
1339         return "mov{w}\t{%1, %0|%0, %1}";
1340     }
1341 }
1342   [(set (attr "type")
1343      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1344               (const_string "imov")
1345             (and (eq_attr "alternative" "0")
1346                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1347                           (const_int 0))
1348                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1349                           (const_int 0))))
1350               (const_string "imov")
1351             (and (eq_attr "alternative" "1,2")
1352                  (match_operand:HI 1 "aligned_operand" ""))
1353               (const_string "imov")
1354             (and (ne (symbol_ref "TARGET_MOVX")
1355                      (const_int 0))
1356                  (eq_attr "alternative" "0,2"))
1357               (const_string "imovx")
1358            ]
1359            (const_string "imov")))
1360     (set (attr "mode")
1361       (cond [(eq_attr "type" "imovx")
1362                (const_string "SI")
1363              (and (eq_attr "alternative" "1,2")
1364                   (match_operand:HI 1 "aligned_operand" ""))
1365                (const_string "SI")
1366              (and (eq_attr "alternative" "0")
1367                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1368                            (const_int 0))
1369                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1370                            (const_int 0))))
1371                (const_string "SI")
1372             ]
1373             (const_string "HI")))])
1374
1375 ;; Stores and loads of ax to arbitrary constant address.
1376 ;; We fake an second form of instruction to force reload to load address
1377 ;; into register when rax is not available
1378 (define_insn "*movabshi_1_rex64"
1379   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1380         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1381   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1382   "@
1383    movabs{w}\t{%1, %P0|%P0, %1}
1384    mov{w}\t{%1, %a0|%a0, %1}"
1385   [(set_attr "type" "imov")
1386    (set_attr "modrm" "0,*")
1387    (set_attr "length_address" "8,0")
1388    (set_attr "length_immediate" "0,*")
1389    (set_attr "memory" "store")
1390    (set_attr "mode" "HI")])
1391
1392 (define_insn "*movabshi_2_rex64"
1393   [(set (match_operand:HI 0 "register_operand" "=a,r")
1394         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1395   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1396   "@
1397    movabs{w}\t{%P1, %0|%0, %P1}
1398    mov{w}\t{%a1, %0|%0, %a1}"
1399   [(set_attr "type" "imov")
1400    (set_attr "modrm" "0,*")
1401    (set_attr "length_address" "8,0")
1402    (set_attr "length_immediate" "0")
1403    (set_attr "memory" "load")
1404    (set_attr "mode" "HI")])
1405
1406 (define_insn "*swaphi_1"
1407   [(set (match_operand:HI 0 "register_operand" "+r")
1408         (match_operand:HI 1 "register_operand" "+r"))
1409    (set (match_dup 1)
1410         (match_dup 0))]
1411   "TARGET_PARTIAL_REG_STALL"
1412   "xchg{w}\t%1, %0"
1413   [(set_attr "type" "imov")
1414    (set_attr "pent_pair" "np")
1415    (set_attr "mode" "HI")
1416    (set_attr "modrm" "0")])
1417
1418 (define_insn "*swaphi_2"
1419   [(set (match_operand:HI 0 "register_operand" "+r")
1420         (match_operand:HI 1 "register_operand" "+r"))
1421    (set (match_dup 1)
1422         (match_dup 0))]
1423   "! TARGET_PARTIAL_REG_STALL"
1424   "xchg{l}\t%k1, %k0"
1425   [(set_attr "type" "imov")
1426    (set_attr "pent_pair" "np")
1427    (set_attr "mode" "SI")
1428    (set_attr "modrm" "0")])
1429
1430 (define_expand "movstricthi"
1431   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1432         (match_operand:HI 1 "general_operand" ""))]
1433   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1434 {
1435   /* Don't generate memory->memory moves, go through a register */
1436   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1437     operands[1] = force_reg (HImode, operands[1]);
1438 })
1439
1440 (define_insn "*movstricthi_1"
1441   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1442         (match_operand:HI 1 "general_operand" "rn,m"))]
1443   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1444    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1445   "mov{w}\t{%1, %0|%0, %1}"
1446   [(set_attr "type" "imov")
1447    (set_attr "mode" "HI")])
1448
1449 (define_insn "*movstricthi_xor"
1450   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1451         (match_operand:HI 1 "const0_operand" "i"))
1452    (clobber (reg:CC FLAGS_REG))]
1453   "reload_completed
1454    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1455   "xor{w}\t{%0, %0|%0, %0}"
1456   [(set_attr "type" "alu1")
1457    (set_attr "mode" "HI")
1458    (set_attr "length_immediate" "0")])
1459
1460 (define_expand "movqi"
1461   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1462         (match_operand:QI 1 "general_operand" ""))]
1463   ""
1464   "ix86_expand_move (QImode, operands); DONE;")
1465
1466 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1467 ;; "push a byte".  But actually we use pushw, which has the effect
1468 ;; of rounding the amount pushed up to a halfword.
1469
1470 (define_insn "*pushqi2"
1471   [(set (match_operand:QI 0 "push_operand" "=X,X")
1472         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1473   "!TARGET_64BIT"
1474   "@
1475    push{w}\t{|word ptr }%1
1476    push{w}\t%w1"
1477   [(set_attr "type" "push")
1478    (set_attr "mode" "HI")])
1479
1480 ;; For 64BIT abi we always round up to 8 bytes.
1481 (define_insn "*pushqi2_rex64"
1482   [(set (match_operand:QI 0 "push_operand" "=X")
1483         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1484   "TARGET_64BIT"
1485   "push{q}\t%q1"
1486   [(set_attr "type" "push")
1487    (set_attr "mode" "QI")])
1488
1489 ;; Situation is quite tricky about when to choose full sized (SImode) move
1490 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1491 ;; partial register dependency machines (such as AMD Athlon), where QImode
1492 ;; moves issue extra dependency and for partial register stalls machines
1493 ;; that don't use QImode patterns (and QImode move cause stall on the next
1494 ;; instruction).
1495 ;;
1496 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1497 ;; register stall machines with, where we use QImode instructions, since
1498 ;; partial register stall can be caused there.  Then we use movzx.
1499 (define_insn "*movqi_1"
1500   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1501         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1502   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1503 {
1504   switch (get_attr_type (insn))
1505     {
1506     case TYPE_IMOVX:
1507       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1508         abort ();
1509       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1510     default:
1511       if (get_attr_mode (insn) == MODE_SI)
1512         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1513       else
1514         return "mov{b}\t{%1, %0|%0, %1}";
1515     }
1516 }
1517   [(set (attr "type")
1518      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1519               (const_string "imov")
1520             (and (eq_attr "alternative" "3")
1521                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1522                           (const_int 0))
1523                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1524                           (const_int 0))))
1525               (const_string "imov")
1526             (eq_attr "alternative" "3,5")
1527               (const_string "imovx")
1528             (and (ne (symbol_ref "TARGET_MOVX")
1529                      (const_int 0))
1530                  (eq_attr "alternative" "2"))
1531               (const_string "imovx")
1532            ]
1533            (const_string "imov")))
1534    (set (attr "mode")
1535       (cond [(eq_attr "alternative" "3,4,5")
1536                (const_string "SI")
1537              (eq_attr "alternative" "6")
1538                (const_string "QI")
1539              (eq_attr "type" "imovx")
1540                (const_string "SI")
1541              (and (eq_attr "type" "imov")
1542                   (and (eq_attr "alternative" "0,1,2")
1543                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1544                            (const_int 0))))
1545                (const_string "SI")
1546              ;; Avoid partial register stalls when not using QImode arithmetic
1547              (and (eq_attr "type" "imov")
1548                   (and (eq_attr "alternative" "0,1,2")
1549                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1550                                 (const_int 0))
1551                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1552                                 (const_int 0)))))
1553                (const_string "SI")
1554            ]
1555            (const_string "QI")))])
1556
1557 (define_expand "reload_outqi"
1558   [(parallel [(match_operand:QI 0 "" "=m")
1559               (match_operand:QI 1 "register_operand" "r")
1560               (match_operand:QI 2 "register_operand" "=&q")])]
1561   ""
1562 {
1563   rtx op0, op1, op2;
1564   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1565
1566   if (reg_overlap_mentioned_p (op2, op0))
1567     abort ();
1568   if (! q_regs_operand (op1, QImode))
1569     {
1570       emit_insn (gen_movqi (op2, op1));
1571       op1 = op2;
1572     }
1573   emit_insn (gen_movqi (op0, op1));
1574   DONE;
1575 })
1576
1577 (define_insn "*swapqi"
1578   [(set (match_operand:QI 0 "register_operand" "+r")
1579         (match_operand:QI 1 "register_operand" "+r"))
1580    (set (match_dup 1)
1581         (match_dup 0))]
1582   ""
1583   "xchg{b}\t%1, %0"
1584   [(set_attr "type" "imov")
1585    (set_attr "pent_pair" "np")
1586    (set_attr "mode" "QI")
1587    (set_attr "modrm" "0")])
1588
1589 (define_expand "movstrictqi"
1590   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1591         (match_operand:QI 1 "general_operand" ""))]
1592   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1593 {
1594   /* Don't generate memory->memory moves, go through a register.  */
1595   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1596     operands[1] = force_reg (QImode, operands[1]);
1597 })
1598
1599 (define_insn "*movstrictqi_1"
1600   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1601         (match_operand:QI 1 "general_operand" "*qn,m"))]
1602   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1603    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1604   "mov{b}\t{%1, %0|%0, %1}"
1605   [(set_attr "type" "imov")
1606    (set_attr "mode" "QI")])
1607
1608 (define_insn "*movstrictqi_xor"
1609   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1610         (match_operand:QI 1 "const0_operand" "i"))
1611    (clobber (reg:CC FLAGS_REG))]
1612   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1613   "xor{b}\t{%0, %0|%0, %0}"
1614   [(set_attr "type" "alu1")
1615    (set_attr "mode" "QI")
1616    (set_attr "length_immediate" "0")])
1617
1618 (define_insn "*movsi_extv_1"
1619   [(set (match_operand:SI 0 "register_operand" "=R")
1620         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1621                          (const_int 8)
1622                          (const_int 8)))]
1623   ""
1624   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1625   [(set_attr "type" "imovx")
1626    (set_attr "mode" "SI")])
1627
1628 (define_insn "*movhi_extv_1"
1629   [(set (match_operand:HI 0 "register_operand" "=R")
1630         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1631                          (const_int 8)
1632                          (const_int 8)))]
1633   ""
1634   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1635   [(set_attr "type" "imovx")
1636    (set_attr "mode" "SI")])
1637
1638 (define_insn "*movqi_extv_1"
1639   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1640         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1641                          (const_int 8)
1642                          (const_int 8)))]
1643   "!TARGET_64BIT"
1644 {
1645   switch (get_attr_type (insn))
1646     {
1647     case TYPE_IMOVX:
1648       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1649     default:
1650       return "mov{b}\t{%h1, %0|%0, %h1}";
1651     }
1652 }
1653   [(set (attr "type")
1654      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1655                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1656                              (ne (symbol_ref "TARGET_MOVX")
1657                                  (const_int 0))))
1658         (const_string "imovx")
1659         (const_string "imov")))
1660    (set (attr "mode")
1661      (if_then_else (eq_attr "type" "imovx")
1662         (const_string "SI")
1663         (const_string "QI")))])
1664
1665 (define_insn "*movqi_extv_1_rex64"
1666   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1667         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1668                          (const_int 8)
1669                          (const_int 8)))]
1670   "TARGET_64BIT"
1671 {
1672   switch (get_attr_type (insn))
1673     {
1674     case TYPE_IMOVX:
1675       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1676     default:
1677       return "mov{b}\t{%h1, %0|%0, %h1}";
1678     }
1679 }
1680   [(set (attr "type")
1681      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1682                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1683                              (ne (symbol_ref "TARGET_MOVX")
1684                                  (const_int 0))))
1685         (const_string "imovx")
1686         (const_string "imov")))
1687    (set (attr "mode")
1688      (if_then_else (eq_attr "type" "imovx")
1689         (const_string "SI")
1690         (const_string "QI")))])
1691
1692 ;; Stores and loads of ax to arbitrary constant address.
1693 ;; We fake an second form of instruction to force reload to load address
1694 ;; into register when rax is not available
1695 (define_insn "*movabsqi_1_rex64"
1696   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1697         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1698   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1699   "@
1700    movabs{b}\t{%1, %P0|%P0, %1}
1701    mov{b}\t{%1, %a0|%a0, %1}"
1702   [(set_attr "type" "imov")
1703    (set_attr "modrm" "0,*")
1704    (set_attr "length_address" "8,0")
1705    (set_attr "length_immediate" "0,*")
1706    (set_attr "memory" "store")
1707    (set_attr "mode" "QI")])
1708
1709 (define_insn "*movabsqi_2_rex64"
1710   [(set (match_operand:QI 0 "register_operand" "=a,r")
1711         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1712   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1713   "@
1714    movabs{b}\t{%P1, %0|%0, %P1}
1715    mov{b}\t{%a1, %0|%0, %a1}"
1716   [(set_attr "type" "imov")
1717    (set_attr "modrm" "0,*")
1718    (set_attr "length_address" "8,0")
1719    (set_attr "length_immediate" "0")
1720    (set_attr "memory" "load")
1721    (set_attr "mode" "QI")])
1722
1723 (define_insn "*movsi_extzv_1"
1724   [(set (match_operand:SI 0 "register_operand" "=R")
1725         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1726                          (const_int 8)
1727                          (const_int 8)))]
1728   ""
1729   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1730   [(set_attr "type" "imovx")
1731    (set_attr "mode" "SI")])
1732
1733 (define_insn "*movqi_extzv_2"
1734   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1735         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1736                                     (const_int 8)
1737                                     (const_int 8)) 0))]
1738   "!TARGET_64BIT"
1739 {
1740   switch (get_attr_type (insn))
1741     {
1742     case TYPE_IMOVX:
1743       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1744     default:
1745       return "mov{b}\t{%h1, %0|%0, %h1}";
1746     }
1747 }
1748   [(set (attr "type")
1749      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1750                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1751                              (ne (symbol_ref "TARGET_MOVX")
1752                                  (const_int 0))))
1753         (const_string "imovx")
1754         (const_string "imov")))
1755    (set (attr "mode")
1756      (if_then_else (eq_attr "type" "imovx")
1757         (const_string "SI")
1758         (const_string "QI")))])
1759
1760 (define_insn "*movqi_extzv_2_rex64"
1761   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1762         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1763                                     (const_int 8)
1764                                     (const_int 8)) 0))]
1765   "TARGET_64BIT"
1766 {
1767   switch (get_attr_type (insn))
1768     {
1769     case TYPE_IMOVX:
1770       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1771     default:
1772       return "mov{b}\t{%h1, %0|%0, %h1}";
1773     }
1774 }
1775   [(set (attr "type")
1776      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1777                         (ne (symbol_ref "TARGET_MOVX")
1778                             (const_int 0)))
1779         (const_string "imovx")
1780         (const_string "imov")))
1781    (set (attr "mode")
1782      (if_then_else (eq_attr "type" "imovx")
1783         (const_string "SI")
1784         (const_string "QI")))])
1785
1786 (define_insn "movsi_insv_1"
1787   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1788                          (const_int 8)
1789                          (const_int 8))
1790         (match_operand:SI 1 "general_operand" "Qmn"))]
1791   "!TARGET_64BIT"
1792   "mov{b}\t{%b1, %h0|%h0, %b1}"
1793   [(set_attr "type" "imov")
1794    (set_attr "mode" "QI")])
1795
1796 (define_insn "movdi_insv_1_rex64"
1797   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1798                          (const_int 8)
1799                          (const_int 8))
1800         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1801   "TARGET_64BIT"
1802   "mov{b}\t{%b1, %h0|%h0, %b1}"
1803   [(set_attr "type" "imov")
1804    (set_attr "mode" "QI")])
1805
1806 (define_insn "*movqi_insv_2"
1807   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1808                          (const_int 8)
1809                          (const_int 8))
1810         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1811                      (const_int 8)))]
1812   ""
1813   "mov{b}\t{%h1, %h0|%h0, %h1}"
1814   [(set_attr "type" "imov")
1815    (set_attr "mode" "QI")])
1816
1817 (define_expand "movdi"
1818   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1819         (match_operand:DI 1 "general_operand" ""))]
1820   ""
1821   "ix86_expand_move (DImode, operands); DONE;")
1822
1823 (define_insn "*pushdi"
1824   [(set (match_operand:DI 0 "push_operand" "=<")
1825         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1826   "!TARGET_64BIT"
1827   "#")
1828
1829 (define_insn "pushdi2_rex64"
1830   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1831         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1832   "TARGET_64BIT"
1833   "@
1834    push{q}\t%1
1835    #"
1836   [(set_attr "type" "push,multi")
1837    (set_attr "mode" "DI")])
1838
1839 ;; Convert impossible pushes of immediate to existing instructions.
1840 ;; First try to get scratch register and go through it.  In case this
1841 ;; fails, push sign extended lower part first and then overwrite
1842 ;; upper part by 32bit move.
1843 (define_peephole2
1844   [(match_scratch:DI 2 "r")
1845    (set (match_operand:DI 0 "push_operand" "")
1846         (match_operand:DI 1 "immediate_operand" ""))]
1847   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1848    && !x86_64_immediate_operand (operands[1], DImode)"
1849   [(set (match_dup 2) (match_dup 1))
1850    (set (match_dup 0) (match_dup 2))]
1851   "")
1852
1853 ;; We need to define this as both peepholer and splitter for case
1854 ;; peephole2 pass is not run.
1855 (define_peephole2
1856   [(set (match_operand:DI 0 "push_operand" "")
1857         (match_operand:DI 1 "immediate_operand" ""))]
1858   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1859    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1860   [(set (match_dup 0) (match_dup 1))
1861    (set (match_dup 2) (match_dup 3))]
1862   "split_di (operands + 1, 1, operands + 2, operands + 3);
1863    operands[1] = gen_lowpart (DImode, operands[2]);
1864    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1865                                                     GEN_INT (4)));
1866   ")
1867
1868 (define_split
1869   [(set (match_operand:DI 0 "push_operand" "")
1870         (match_operand:DI 1 "immediate_operand" ""))]
1871   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1872    && !symbolic_operand (operands[1], DImode)
1873    && !x86_64_immediate_operand (operands[1], DImode)"
1874   [(set (match_dup 0) (match_dup 1))
1875    (set (match_dup 2) (match_dup 3))]
1876   "split_di (operands + 1, 1, operands + 2, operands + 3);
1877    operands[1] = gen_lowpart (DImode, operands[2]);
1878    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1879                                                     GEN_INT (4)));
1880   ")
1881
1882 (define_insn "*pushdi2_prologue_rex64"
1883   [(set (match_operand:DI 0 "push_operand" "=<")
1884         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1885    (clobber (mem:BLK (scratch)))]
1886   "TARGET_64BIT"
1887   "push{q}\t%1"
1888   [(set_attr "type" "push")
1889    (set_attr "mode" "DI")])
1890
1891 (define_insn "*popdi1_epilogue_rex64"
1892   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1893         (mem:DI (reg:DI SP_REG)))
1894    (set (reg:DI SP_REG)
1895         (plus:DI (reg:DI SP_REG) (const_int 8)))
1896    (clobber (mem:BLK (scratch)))]
1897   "TARGET_64BIT"
1898   "pop{q}\t%0"
1899   [(set_attr "type" "pop")
1900    (set_attr "mode" "DI")])
1901
1902 (define_insn "popdi1"
1903   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1904         (mem:DI (reg:DI SP_REG)))
1905    (set (reg:DI SP_REG)
1906         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1907   "TARGET_64BIT"
1908   "pop{q}\t%0"
1909   [(set_attr "type" "pop")
1910    (set_attr "mode" "DI")])
1911
1912 (define_insn "*movdi_xor_rex64"
1913   [(set (match_operand:DI 0 "register_operand" "=r")
1914         (match_operand:DI 1 "const0_operand" "i"))
1915    (clobber (reg:CC FLAGS_REG))]
1916   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1917    && reload_completed"
1918   "xor{l}\t{%k0, %k0|%k0, %k0}"
1919   [(set_attr "type" "alu1")
1920    (set_attr "mode" "SI")
1921    (set_attr "length_immediate" "0")])
1922
1923 (define_insn "*movdi_or_rex64"
1924   [(set (match_operand:DI 0 "register_operand" "=r")
1925         (match_operand:DI 1 "const_int_operand" "i"))
1926    (clobber (reg:CC FLAGS_REG))]
1927   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1928    && reload_completed
1929    && operands[1] == constm1_rtx"
1930 {
1931   operands[1] = constm1_rtx;
1932   return "or{q}\t{%1, %0|%0, %1}";
1933 }
1934   [(set_attr "type" "alu1")
1935    (set_attr "mode" "DI")
1936    (set_attr "length_immediate" "1")])
1937
1938 (define_insn "*movdi_2"
1939   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1940         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1941   "!TARGET_64BIT
1942    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1943   "@
1944    #
1945    #
1946    movq\t{%1, %0|%0, %1}
1947    movq\t{%1, %0|%0, %1}
1948    movq\t{%1, %0|%0, %1}
1949    movdqa\t{%1, %0|%0, %1}
1950    movq\t{%1, %0|%0, %1}"
1951   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1952    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1953
1954 (define_split
1955   [(set (match_operand:DI 0 "push_operand" "")
1956         (match_operand:DI 1 "general_operand" ""))]
1957   "!TARGET_64BIT && reload_completed
1958    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1959   [(const_int 0)]
1960   "ix86_split_long_move (operands); DONE;")
1961
1962 ;; %%% This multiword shite has got to go.
1963 (define_split
1964   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1965         (match_operand:DI 1 "general_operand" ""))]
1966   "!TARGET_64BIT && reload_completed
1967    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1968    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1969   [(const_int 0)]
1970   "ix86_split_long_move (operands); DONE;")
1971
1972 (define_insn "*movdi_1_rex64"
1973   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1974         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1975   "TARGET_64BIT
1976    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1977    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1978 {
1979   switch (get_attr_type (insn))
1980     {
1981     case TYPE_SSECVT:
1982       if (which_alternative == 11)
1983         return "movq2dq\t{%1, %0|%0, %1}";
1984       else
1985         return "movdq2q\t{%1, %0|%0, %1}";
1986     case TYPE_SSEMOV:
1987       if (get_attr_mode (insn) == MODE_TI)
1988           return "movdqa\t{%1, %0|%0, %1}";
1989       /* FALLTHRU */
1990     case TYPE_MMXMOV:
1991       /* Moves from and into integer register is done using movd opcode with
1992          REX prefix.  */
1993       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1994           return "movd\t{%1, %0|%0, %1}";
1995       return "movq\t{%1, %0|%0, %1}";
1996     case TYPE_MULTI:
1997       return "#";
1998     case TYPE_LEA:
1999       return "lea{q}\t{%a1, %0|%0, %a1}";
2000     default:
2001       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2002         abort ();
2003       if (get_attr_mode (insn) == MODE_SI)
2004         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2005       else if (which_alternative == 2)
2006         return "movabs{q}\t{%1, %0|%0, %1}";
2007       else
2008         return "mov{q}\t{%1, %0|%0, %1}";
2009     }
2010 }
2011   [(set (attr "type")
2012      (cond [(eq_attr "alternative" "5,6,7")
2013               (const_string "mmxmov")
2014             (eq_attr "alternative" "8,9,10")
2015               (const_string "ssemov")
2016             (eq_attr "alternative" "11,12")
2017               (const_string "ssecvt")
2018             (eq_attr "alternative" "4")
2019               (const_string "multi")
2020             (and (ne (symbol_ref "flag_pic") (const_int 0))
2021                  (match_operand:DI 1 "symbolic_operand" ""))
2022               (const_string "lea")
2023            ]
2024            (const_string "imov")))
2025    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
2026    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2027    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2028
2029 (define_insn "*movdi_1_rex64_nointerunit"
2030   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2031         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2032   "TARGET_64BIT
2033    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2034    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2035 {
2036   switch (get_attr_type (insn))
2037     {
2038     case TYPE_SSEMOV:
2039       if (get_attr_mode (insn) == MODE_TI)
2040           return "movdqa\t{%1, %0|%0, %1}";
2041       /* FALLTHRU */
2042     case TYPE_MMXMOV:
2043       return "movq\t{%1, %0|%0, %1}";
2044     case TYPE_MULTI:
2045       return "#";
2046     case TYPE_LEA:
2047       return "lea{q}\t{%a1, %0|%0, %a1}";
2048     default:
2049       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2050         abort ();
2051       if (get_attr_mode (insn) == MODE_SI)
2052         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2053       else if (which_alternative == 2)
2054         return "movabs{q}\t{%1, %0|%0, %1}";
2055       else
2056         return "mov{q}\t{%1, %0|%0, %1}";
2057     }
2058 }
2059   [(set (attr "type")
2060      (cond [(eq_attr "alternative" "5,6,7")
2061               (const_string "mmxmov")
2062             (eq_attr "alternative" "8,9,10")
2063               (const_string "ssemov")
2064             (eq_attr "alternative" "4")
2065               (const_string "multi")
2066             (and (ne (symbol_ref "flag_pic") (const_int 0))
2067                  (match_operand:DI 1 "symbolic_operand" ""))
2068               (const_string "lea")
2069            ]
2070            (const_string "imov")))
2071    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2072    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2073    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2074
2075 ;; Stores and loads of ax to arbitrary constant address.
2076 ;; We fake an second form of instruction to force reload to load address
2077 ;; into register when rax is not available
2078 (define_insn "*movabsdi_1_rex64"
2079   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2080         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2081   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2082   "@
2083    movabs{q}\t{%1, %P0|%P0, %1}
2084    mov{q}\t{%1, %a0|%a0, %1}"
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" "store")
2090    (set_attr "mode" "DI")])
2091
2092 (define_insn "*movabsdi_2_rex64"
2093   [(set (match_operand:DI 0 "register_operand" "=a,r")
2094         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2095   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2096   "@
2097    movabs{q}\t{%P1, %0|%0, %P1}
2098    mov{q}\t{%a1, %0|%0, %a1}"
2099   [(set_attr "type" "imov")
2100    (set_attr "modrm" "0,*")
2101    (set_attr "length_address" "8,0")
2102    (set_attr "length_immediate" "0")
2103    (set_attr "memory" "load")
2104    (set_attr "mode" "DI")])
2105
2106 ;; Convert impossible stores of immediate to existing instructions.
2107 ;; First try to get scratch register and go through it.  In case this
2108 ;; fails, move by 32bit parts.
2109 (define_peephole2
2110   [(match_scratch:DI 2 "r")
2111    (set (match_operand:DI 0 "memory_operand" "")
2112         (match_operand:DI 1 "immediate_operand" ""))]
2113   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2114    && !x86_64_immediate_operand (operands[1], DImode)"
2115   [(set (match_dup 2) (match_dup 1))
2116    (set (match_dup 0) (match_dup 2))]
2117   "")
2118
2119 ;; We need to define this as both peepholer and splitter for case
2120 ;; peephole2 pass is not run.
2121 (define_peephole2
2122   [(set (match_operand:DI 0 "memory_operand" "")
2123         (match_operand:DI 1 "immediate_operand" ""))]
2124   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2125    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2126   [(set (match_dup 2) (match_dup 3))
2127    (set (match_dup 4) (match_dup 5))]
2128   "split_di (operands, 2, operands + 2, operands + 4);")
2129
2130 (define_split
2131   [(set (match_operand:DI 0 "memory_operand" "")
2132         (match_operand:DI 1 "immediate_operand" ""))]
2133   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2134    && !symbolic_operand (operands[1], DImode)
2135    && !x86_64_immediate_operand (operands[1], DImode)"
2136   [(set (match_dup 2) (match_dup 3))
2137    (set (match_dup 4) (match_dup 5))]
2138   "split_di (operands, 2, operands + 2, operands + 4);")
2139
2140 (define_insn "*swapdi_rex64"
2141   [(set (match_operand:DI 0 "register_operand" "+r")
2142         (match_operand:DI 1 "register_operand" "+r"))
2143    (set (match_dup 1)
2144         (match_dup 0))]
2145   "TARGET_64BIT"
2146   "xchg{q}\t%1, %0"
2147   [(set_attr "type" "imov")
2148    (set_attr "pent_pair" "np")
2149    (set_attr "athlon_decode" "vector")
2150    (set_attr "mode" "DI")
2151    (set_attr "modrm" "0")])
2152
2153   
2154 (define_expand "movsf"
2155   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2156         (match_operand:SF 1 "general_operand" ""))]
2157   ""
2158   "ix86_expand_move (SFmode, operands); DONE;")
2159
2160 (define_insn "*pushsf"
2161   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2162         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2163   "!TARGET_64BIT"
2164 {
2165   switch (which_alternative)
2166     {
2167     case 1:
2168       return "push{l}\t%1";
2169
2170     default:
2171       /* This insn should be already split before reg-stack.  */
2172       abort ();
2173     }
2174 }
2175   [(set_attr "type" "multi,push,multi")
2176    (set_attr "mode" "SF,SI,SF")])
2177
2178 (define_insn "*pushsf_rex64"
2179   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2180         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2181   "TARGET_64BIT"
2182 {
2183   switch (which_alternative)
2184     {
2185     case 1:
2186       return "push{q}\t%q1";
2187
2188     default:
2189       /* This insn should be already split before reg-stack.  */
2190       abort ();
2191     }
2192 }
2193   [(set_attr "type" "multi,push,multi")
2194    (set_attr "mode" "SF,DI,SF")])
2195
2196 (define_split
2197   [(set (match_operand:SF 0 "push_operand" "")
2198         (match_operand:SF 1 "memory_operand" ""))]
2199   "reload_completed
2200    && GET_CODE (operands[1]) == MEM
2201    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2202    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2203   [(set (match_dup 0)
2204         (match_dup 1))]
2205   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2206
2207
2208 ;; %%% Kill this when call knows how to work this out.
2209 (define_split
2210   [(set (match_operand:SF 0 "push_operand" "")
2211         (match_operand:SF 1 "any_fp_register_operand" ""))]
2212   "!TARGET_64BIT"
2213   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2214    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2215
2216 (define_split
2217   [(set (match_operand:SF 0 "push_operand" "")
2218         (match_operand:SF 1 "any_fp_register_operand" ""))]
2219   "TARGET_64BIT"
2220   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2221    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2222
2223 (define_insn "*movsf_1"
2224   [(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")
2225         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2226   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2227    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2228    && (reload_in_progress || reload_completed
2229        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2230        || GET_CODE (operands[1]) != CONST_DOUBLE
2231        || memory_operand (operands[0], SFmode))" 
2232 {
2233   switch (which_alternative)
2234     {
2235     case 0:
2236       return output_387_reg_move (insn, operands);
2237
2238     case 1:
2239       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2240         return "fstp%z0\t%y0";
2241       else
2242         return "fst%z0\t%y0";
2243
2244     case 2:
2245       return standard_80387_constant_opcode (operands[1]);
2246
2247     case 3:
2248     case 4:
2249       return "mov{l}\t{%1, %0|%0, %1}";
2250     case 5:
2251       if (get_attr_mode (insn) == MODE_TI)
2252         return "pxor\t%0, %0";
2253       else
2254         return "xorps\t%0, %0";
2255     case 6:
2256       if (get_attr_mode (insn) == MODE_V4SF)
2257         return "movaps\t{%1, %0|%0, %1}";
2258       else
2259         return "movss\t{%1, %0|%0, %1}";
2260     case 7:
2261     case 8:
2262       return "movss\t{%1, %0|%0, %1}";
2263
2264     case 9:
2265     case 10:
2266       return "movd\t{%1, %0|%0, %1}";
2267
2268     case 11:
2269       return "movq\t{%1, %0|%0, %1}";
2270
2271     default:
2272       abort();
2273     }
2274 }
2275   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2276    (set (attr "mode")
2277         (cond [(eq_attr "alternative" "3,4,9,10")
2278                  (const_string "SI")
2279                (eq_attr "alternative" "5")
2280                  (if_then_else
2281                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2282                                  (const_int 0))
2283                              (ne (symbol_ref "TARGET_SSE2")
2284                                  (const_int 0)))
2285                         (eq (symbol_ref "optimize_size")
2286                             (const_int 0)))
2287                    (const_string "TI")
2288                    (const_string "V4SF"))
2289                /* For architectures resolving dependencies on
2290                   whole SSE registers use APS move to break dependency
2291                   chains, otherwise use short move to avoid extra work. 
2292
2293                   Do the same for architectures resolving dependencies on
2294                   the parts.  While in DF mode it is better to always handle
2295                   just register parts, the SF mode is different due to lack
2296                   of instructions to load just part of the register.  It is
2297                   better to maintain the whole registers in single format
2298                   to avoid problems on using packed logical operations.  */
2299                (eq_attr "alternative" "6")
2300                  (if_then_else
2301                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2302                             (const_int 0))
2303                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2304                             (const_int 0)))
2305                    (const_string "V4SF")
2306                    (const_string "SF"))
2307                (eq_attr "alternative" "11")
2308                  (const_string "DI")]
2309                (const_string "SF")))])
2310
2311 (define_insn "*movsf_1_nointerunit"
2312   [(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")
2313         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2314   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2315    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2316    && (reload_in_progress || reload_completed
2317        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2318        || GET_CODE (operands[1]) != CONST_DOUBLE
2319        || memory_operand (operands[0], SFmode))" 
2320 {
2321   switch (which_alternative)
2322     {
2323     case 0:
2324       return output_387_reg_move (insn, operands);
2325
2326     case 1:
2327       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2328         return "fstp%z0\t%y0";
2329       else
2330         return "fst%z0\t%y0";
2331
2332     case 2:
2333       return standard_80387_constant_opcode (operands[1]);
2334
2335     case 3:
2336     case 4:
2337       return "mov{l}\t{%1, %0|%0, %1}";
2338     case 5:
2339       if (get_attr_mode (insn) == MODE_TI)
2340         return "pxor\t%0, %0";
2341       else
2342         return "xorps\t%0, %0";
2343     case 6:
2344       if (get_attr_mode (insn) == MODE_V4SF)
2345         return "movaps\t{%1, %0|%0, %1}";
2346       else
2347         return "movss\t{%1, %0|%0, %1}";
2348     case 7:
2349     case 8:
2350       return "movss\t{%1, %0|%0, %1}";
2351
2352     case 9:
2353     case 10:
2354       return "movd\t{%1, %0|%0, %1}";
2355
2356     case 11:
2357       return "movq\t{%1, %0|%0, %1}";
2358
2359     default:
2360       abort();
2361     }
2362 }
2363   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2364    (set (attr "mode")
2365         (cond [(eq_attr "alternative" "3,4,9,10")
2366                  (const_string "SI")
2367                (eq_attr "alternative" "5")
2368                  (if_then_else
2369                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2370                                  (const_int 0))
2371                              (ne (symbol_ref "TARGET_SSE2")
2372                                  (const_int 0)))
2373                         (eq (symbol_ref "optimize_size")
2374                             (const_int 0)))
2375                    (const_string "TI")
2376                    (const_string "V4SF"))
2377                /* For architectures resolving dependencies on
2378                   whole SSE registers use APS move to break dependency
2379                   chains, otherwise use short move to avoid extra work. 
2380
2381                   Do the same for architectures resolving dependencies on
2382                   the parts.  While in DF mode it is better to always handle
2383                   just register parts, the SF mode is different due to lack
2384                   of instructions to load just part of the register.  It is
2385                   better to maintain the whole registers in single format
2386                   to avoid problems on using packed logical operations.  */
2387                (eq_attr "alternative" "6")
2388                  (if_then_else
2389                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2390                             (const_int 0))
2391                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2392                             (const_int 0)))
2393                    (const_string "V4SF")
2394                    (const_string "SF"))
2395                (eq_attr "alternative" "11")
2396                  (const_string "DI")]
2397                (const_string "SF")))])
2398
2399 (define_insn "*swapsf"
2400   [(set (match_operand:SF 0 "register_operand" "+f")
2401         (match_operand:SF 1 "register_operand" "+f"))
2402    (set (match_dup 1)
2403         (match_dup 0))]
2404   "reload_completed || !TARGET_SSE"
2405 {
2406   if (STACK_TOP_P (operands[0]))
2407     return "fxch\t%1";
2408   else
2409     return "fxch\t%0";
2410 }
2411   [(set_attr "type" "fxch")
2412    (set_attr "mode" "SF")])
2413
2414 (define_expand "movdf"
2415   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2416         (match_operand:DF 1 "general_operand" ""))]
2417   ""
2418   "ix86_expand_move (DFmode, operands); DONE;")
2419
2420 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2421 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2422 ;; On the average, pushdf using integers can be still shorter.  Allow this
2423 ;; pattern for optimize_size too.
2424
2425 (define_insn "*pushdf_nointeger"
2426   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2427         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2428   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2429 {
2430   /* This insn should be already split before reg-stack.  */
2431   abort ();
2432 }
2433   [(set_attr "type" "multi")
2434    (set_attr "mode" "DF,SI,SI,DF")])
2435
2436 (define_insn "*pushdf_integer"
2437   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2438         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2439   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2440 {
2441   /* This insn should be already split before reg-stack.  */
2442   abort ();
2443 }
2444   [(set_attr "type" "multi")
2445    (set_attr "mode" "DF,SI,DF")])
2446
2447 ;; %%% Kill this when call knows how to work this out.
2448 (define_split
2449   [(set (match_operand:DF 0 "push_operand" "")
2450         (match_operand:DF 1 "any_fp_register_operand" ""))]
2451   "!TARGET_64BIT && reload_completed"
2452   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2453    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2454   "")
2455
2456 (define_split
2457   [(set (match_operand:DF 0 "push_operand" "")
2458         (match_operand:DF 1 "any_fp_register_operand" ""))]
2459   "TARGET_64BIT && reload_completed"
2460   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2461    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2462   "")
2463
2464 (define_split
2465   [(set (match_operand:DF 0 "push_operand" "")
2466         (match_operand:DF 1 "general_operand" ""))]
2467   "reload_completed"
2468   [(const_int 0)]
2469   "ix86_split_long_move (operands); DONE;")
2470
2471 ;; Moving is usually shorter when only FP registers are used. This separate
2472 ;; movdf pattern avoids the use of integer registers for FP operations
2473 ;; when optimizing for size.
2474
2475 (define_insn "*movdf_nointeger"
2476   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2477         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2478   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2479    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2480    && (reload_in_progress || reload_completed
2481        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2482        || GET_CODE (operands[1]) != CONST_DOUBLE
2483        || memory_operand (operands[0], DFmode))" 
2484 {
2485   switch (which_alternative)
2486     {
2487     case 0:
2488       return output_387_reg_move (insn, operands);
2489
2490     case 1:
2491       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2492         return "fstp%z0\t%y0";
2493       else
2494         return "fst%z0\t%y0";
2495
2496     case 2:
2497       return standard_80387_constant_opcode (operands[1]);
2498
2499     case 3:
2500     case 4:
2501       return "#";
2502     case 5:
2503       switch (get_attr_mode (insn))
2504         {
2505         case MODE_V4SF:
2506           return "xorps\t%0, %0";
2507         case MODE_V2DF:
2508           return "xorpd\t%0, %0";
2509         case MODE_TI:
2510           return "pxor\t%0, %0";
2511         default:
2512           abort ();
2513         }
2514     case 6:
2515       switch (get_attr_mode (insn))
2516         {
2517         case MODE_V4SF:
2518           return "movaps\t{%1, %0|%0, %1}";
2519         case MODE_V2DF:
2520           return "movapd\t{%1, %0|%0, %1}";
2521         case MODE_DF:
2522           return "movsd\t{%1, %0|%0, %1}";
2523         default:
2524           abort ();
2525         }
2526     case 7:
2527       if (get_attr_mode (insn) == MODE_V2DF)
2528         return "movlpd\t{%1, %0|%0, %1}";
2529       else
2530         return "movsd\t{%1, %0|%0, %1}";
2531     case 8:
2532       return "movsd\t{%1, %0|%0, %1}";
2533
2534     default:
2535       abort();
2536     }
2537 }
2538   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2539    (set (attr "mode")
2540         (cond [(eq_attr "alternative" "3,4")
2541                  (const_string "SI")
2542                /* xorps is one byte shorter.  */
2543                (eq_attr "alternative" "5")
2544                  (cond [(ne (symbol_ref "optimize_size")
2545                             (const_int 0))
2546                           (const_string "V4SF")
2547                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2548                             (const_int 0))
2549                           (const_string "TI")]
2550                        (const_string "V2DF"))
2551                /* For architectures resolving dependencies on
2552                   whole SSE registers use APD move to break dependency
2553                   chains, otherwise use short move to avoid extra work.
2554
2555                   movaps encodes one byte shorter.  */
2556                (eq_attr "alternative" "6")
2557                  (cond
2558                   [(ne (symbol_ref "optimize_size")
2559                        (const_int 0))
2560                      (const_string "V4SF")
2561                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2562                        (const_int 0))
2563                      (const_string "V2DF")]
2564                    (const_string "DF"))
2565                /* For architectures resolving dependencies on register
2566                   parts we may avoid extra work to zero out upper part
2567                   of register.  */
2568                (eq_attr "alternative" "7")
2569                  (if_then_else
2570                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2571                        (const_int 0))
2572                    (const_string "V2DF")
2573                    (const_string "DF"))]
2574                (const_string "DF")))])
2575
2576 (define_insn "*movdf_integer"
2577   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2578         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2579   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2580    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2581    && (reload_in_progress || reload_completed
2582        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2583        || GET_CODE (operands[1]) != CONST_DOUBLE
2584        || memory_operand (operands[0], DFmode))" 
2585 {
2586   switch (which_alternative)
2587     {
2588     case 0:
2589       return output_387_reg_move (insn, operands);
2590
2591     case 1:
2592       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2593         return "fstp%z0\t%y0";
2594       else
2595         return "fst%z0\t%y0";
2596
2597     case 2:
2598       return standard_80387_constant_opcode (operands[1]);
2599
2600     case 3:
2601     case 4:
2602       return "#";
2603
2604     case 5:
2605       switch (get_attr_mode (insn))
2606         {
2607         case MODE_V4SF:
2608           return "xorps\t%0, %0";
2609         case MODE_V2DF:
2610           return "xorpd\t%0, %0";
2611         case MODE_TI:
2612           return "pxor\t%0, %0";
2613         default:
2614           abort ();
2615         }
2616     case 6:
2617       switch (get_attr_mode (insn))
2618         {
2619         case MODE_V4SF:
2620           return "movaps\t{%1, %0|%0, %1}";
2621         case MODE_V2DF:
2622           return "movapd\t{%1, %0|%0, %1}";
2623         case MODE_DF:
2624           return "movsd\t{%1, %0|%0, %1}";
2625         default:
2626           abort ();
2627         }
2628     case 7:
2629       if (get_attr_mode (insn) == MODE_V2DF)
2630         return "movlpd\t{%1, %0|%0, %1}";
2631       else
2632         return "movsd\t{%1, %0|%0, %1}";
2633     case 8:
2634       return "movsd\t{%1, %0|%0, %1}";
2635
2636     default:
2637       abort();
2638     }
2639 }
2640   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2641    (set (attr "mode")
2642         (cond [(eq_attr "alternative" "3,4")
2643                  (const_string "SI")
2644                /* xorps is one byte shorter.  */
2645                (eq_attr "alternative" "5")
2646                  (cond [(ne (symbol_ref "optimize_size")
2647                             (const_int 0))
2648                           (const_string "V4SF")
2649                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2650                             (const_int 0))
2651                           (const_string "TI")]
2652                        (const_string "V2DF"))
2653                /* For architectures resolving dependencies on
2654                   whole SSE registers use APD move to break dependency
2655                   chains, otherwise use short move to avoid extra work.  
2656
2657                   movaps encodes one byte shorter.  */
2658                (eq_attr "alternative" "6")
2659                  (cond
2660                   [(ne (symbol_ref "optimize_size")
2661                        (const_int 0))
2662                      (const_string "V4SF")
2663                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2664                        (const_int 0))
2665                      (const_string "V2DF")]
2666                    (const_string "DF"))
2667                /* For architectures resolving dependencies on register
2668                   parts we may avoid extra work to zero out upper part
2669                   of register.  */
2670                (eq_attr "alternative" "7")
2671                  (if_then_else
2672                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2673                        (const_int 0))
2674                    (const_string "V2DF")
2675                    (const_string "DF"))]
2676                (const_string "DF")))])
2677
2678 (define_split
2679   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2680         (match_operand:DF 1 "general_operand" ""))]
2681   "reload_completed
2682    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2683    && ! (ANY_FP_REG_P (operands[0]) || 
2684          (GET_CODE (operands[0]) == SUBREG
2685           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2686    && ! (ANY_FP_REG_P (operands[1]) || 
2687          (GET_CODE (operands[1]) == SUBREG
2688           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2689   [(const_int 0)]
2690   "ix86_split_long_move (operands); DONE;")
2691
2692 (define_insn "*swapdf"
2693   [(set (match_operand:DF 0 "register_operand" "+f")
2694         (match_operand:DF 1 "register_operand" "+f"))
2695    (set (match_dup 1)
2696         (match_dup 0))]
2697   "reload_completed || !TARGET_SSE2"
2698 {
2699   if (STACK_TOP_P (operands[0]))
2700     return "fxch\t%1";
2701   else
2702     return "fxch\t%0";
2703 }
2704   [(set_attr "type" "fxch")
2705    (set_attr "mode" "DF")])
2706
2707 (define_expand "movxf"
2708   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2709         (match_operand:XF 1 "general_operand" ""))]
2710   ""
2711   "ix86_expand_move (XFmode, operands); DONE;")
2712
2713 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2714 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2715 ;; Pushing using integer instructions is longer except for constants
2716 ;; and direct memory references.
2717 ;; (assuming that any given constant is pushed only once, but this ought to be
2718 ;;  handled elsewhere).
2719
2720 (define_insn "*pushxf_nointeger"
2721   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2722         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2723   "optimize_size"
2724 {
2725   /* This insn should be already split before reg-stack.  */
2726   abort ();
2727 }
2728   [(set_attr "type" "multi")
2729    (set_attr "mode" "XF,SI,SI")])
2730
2731 (define_insn "*pushxf_integer"
2732   [(set (match_operand:XF 0 "push_operand" "=<,<")
2733         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2734   "!optimize_size"
2735 {
2736   /* This insn should be already split before reg-stack.  */
2737   abort ();
2738 }
2739   [(set_attr "type" "multi")
2740    (set_attr "mode" "XF,SI")])
2741
2742 (define_split
2743   [(set (match_operand 0 "push_operand" "")
2744         (match_operand 1 "general_operand" ""))]
2745   "reload_completed
2746    && (GET_MODE (operands[0]) == XFmode
2747        || GET_MODE (operands[0]) == DFmode)
2748    && !ANY_FP_REG_P (operands[1])"
2749   [(const_int 0)]
2750   "ix86_split_long_move (operands); DONE;")
2751
2752 (define_split
2753   [(set (match_operand:XF 0 "push_operand" "")
2754         (match_operand:XF 1 "any_fp_register_operand" ""))]
2755   "!TARGET_64BIT"
2756   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2757    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2758   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2759
2760 (define_split
2761   [(set (match_operand:XF 0 "push_operand" "")
2762         (match_operand:XF 1 "any_fp_register_operand" ""))]
2763   "TARGET_64BIT"
2764   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2765    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2766   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767
2768 ;; Do not use integer registers when optimizing for size
2769 (define_insn "*movxf_nointeger"
2770   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2771         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2772   "optimize_size
2773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2774    && (reload_in_progress || reload_completed
2775        || GET_CODE (operands[1]) != CONST_DOUBLE
2776        || memory_operand (operands[0], XFmode))" 
2777 {
2778   switch (which_alternative)
2779     {
2780     case 0:
2781       return output_387_reg_move (insn, operands);
2782
2783     case 1:
2784       /* There is no non-popping store to memory for XFmode.  So if
2785          we need one, follow the store with a load.  */
2786       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2787         return "fstp%z0\t%y0\;fld%z0\t%y0";
2788       else
2789         return "fstp%z0\t%y0";
2790
2791     case 2:
2792       return standard_80387_constant_opcode (operands[1]);
2793
2794     case 3: case 4:
2795       return "#";
2796     }
2797   abort();
2798 }
2799   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2800    (set_attr "mode" "XF,XF,XF,SI,SI")])
2801
2802 (define_insn "*movxf_integer"
2803   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2804         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2805   "!optimize_size
2806    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2807    && (reload_in_progress || reload_completed
2808        || GET_CODE (operands[1]) != CONST_DOUBLE
2809        || memory_operand (operands[0], XFmode))" 
2810 {
2811   switch (which_alternative)
2812     {
2813     case 0:
2814       return output_387_reg_move (insn, operands);
2815
2816     case 1:
2817       /* There is no non-popping store to memory for XFmode.  So if
2818          we need one, follow the store with a load.  */
2819       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2820         return "fstp%z0\t%y0\;fld%z0\t%y0";
2821       else
2822         return "fstp%z0\t%y0";
2823
2824     case 2:
2825       return standard_80387_constant_opcode (operands[1]);
2826
2827     case 3: case 4:
2828       return "#";
2829     }
2830   abort();
2831 }
2832   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2833    (set_attr "mode" "XF,XF,XF,SI,SI")])
2834
2835 (define_split
2836   [(set (match_operand 0 "nonimmediate_operand" "")
2837         (match_operand 1 "general_operand" ""))]
2838   "reload_completed
2839    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2840    && GET_MODE (operands[0]) == XFmode
2841    && ! (ANY_FP_REG_P (operands[0]) || 
2842          (GET_CODE (operands[0]) == SUBREG
2843           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2844    && ! (ANY_FP_REG_P (operands[1]) || 
2845          (GET_CODE (operands[1]) == SUBREG
2846           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2847   [(const_int 0)]
2848   "ix86_split_long_move (operands); DONE;")
2849
2850 (define_split
2851   [(set (match_operand 0 "register_operand" "")
2852         (match_operand 1 "memory_operand" ""))]
2853   "reload_completed
2854    && GET_CODE (operands[1]) == MEM
2855    && (GET_MODE (operands[0]) == XFmode
2856        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2857    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2858    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2859   [(set (match_dup 0) (match_dup 1))]
2860 {
2861   rtx c = get_pool_constant (XEXP (operands[1], 0));
2862   rtx r = operands[0];
2863
2864   if (GET_CODE (r) == SUBREG)
2865     r = SUBREG_REG (r);
2866
2867   if (SSE_REG_P (r))
2868     {
2869       if (!standard_sse_constant_p (c))
2870         FAIL;
2871     }
2872   else if (FP_REG_P (r))
2873     {
2874       if (!standard_80387_constant_p (c))
2875         FAIL;
2876     }
2877   else if (MMX_REG_P (r))
2878     FAIL;
2879
2880   operands[1] = c;
2881 })
2882
2883 (define_insn "swapxf"
2884   [(set (match_operand:XF 0 "register_operand" "+f")
2885         (match_operand:XF 1 "register_operand" "+f"))
2886    (set (match_dup 1)
2887         (match_dup 0))]
2888   ""
2889 {
2890   if (STACK_TOP_P (operands[0]))
2891     return "fxch\t%1";
2892   else
2893     return "fxch\t%0";
2894 }
2895   [(set_attr "type" "fxch")
2896    (set_attr "mode" "XF")])
2897 \f
2898 ;; Zero extension instructions
2899
2900 (define_expand "zero_extendhisi2"
2901   [(set (match_operand:SI 0 "register_operand" "")
2902      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2903   ""
2904 {
2905   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2906     {
2907       operands[1] = force_reg (HImode, operands[1]);
2908       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2909       DONE;
2910     }
2911 })
2912
2913 (define_insn "zero_extendhisi2_and"
2914   [(set (match_operand:SI 0 "register_operand" "=r")
2915      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2916    (clobber (reg:CC FLAGS_REG))]
2917   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2918   "#"
2919   [(set_attr "type" "alu1")
2920    (set_attr "mode" "SI")])
2921
2922 (define_split
2923   [(set (match_operand:SI 0 "register_operand" "")
2924         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2925    (clobber (reg:CC FLAGS_REG))]
2926   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2927   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2928               (clobber (reg:CC FLAGS_REG))])]
2929   "")
2930
2931 (define_insn "*zero_extendhisi2_movzwl"
2932   [(set (match_operand:SI 0 "register_operand" "=r")
2933      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2934   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2935   "movz{wl|x}\t{%1, %0|%0, %1}"
2936   [(set_attr "type" "imovx")
2937    (set_attr "mode" "SI")])
2938
2939 (define_expand "zero_extendqihi2"
2940   [(parallel
2941     [(set (match_operand:HI 0 "register_operand" "")
2942        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2943      (clobber (reg:CC FLAGS_REG))])]
2944   ""
2945   "")
2946
2947 (define_insn "*zero_extendqihi2_and"
2948   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2949      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2950    (clobber (reg:CC FLAGS_REG))]
2951   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2952   "#"
2953   [(set_attr "type" "alu1")
2954    (set_attr "mode" "HI")])
2955
2956 (define_insn "*zero_extendqihi2_movzbw_and"
2957   [(set (match_operand:HI 0 "register_operand" "=r,r")
2958      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2959    (clobber (reg:CC FLAGS_REG))]
2960   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2961   "#"
2962   [(set_attr "type" "imovx,alu1")
2963    (set_attr "mode" "HI")])
2964
2965 (define_insn "*zero_extendqihi2_movzbw"
2966   [(set (match_operand:HI 0 "register_operand" "=r")
2967      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2968   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2969   "movz{bw|x}\t{%1, %0|%0, %1}"
2970   [(set_attr "type" "imovx")
2971    (set_attr "mode" "HI")])
2972
2973 ;; For the movzbw case strip only the clobber
2974 (define_split
2975   [(set (match_operand:HI 0 "register_operand" "")
2976         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2977    (clobber (reg:CC FLAGS_REG))]
2978   "reload_completed 
2979    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2980    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2981   [(set (match_operand:HI 0 "register_operand" "")
2982         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2983
2984 ;; When source and destination does not overlap, clear destination
2985 ;; first and then do the movb
2986 (define_split
2987   [(set (match_operand:HI 0 "register_operand" "")
2988         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2989    (clobber (reg:CC FLAGS_REG))]
2990   "reload_completed
2991    && ANY_QI_REG_P (operands[0])
2992    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2993    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2994   [(set (match_dup 0) (const_int 0))
2995    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2996   "operands[2] = gen_lowpart (QImode, operands[0]);")
2997
2998 ;; Rest is handled by single and.
2999 (define_split
3000   [(set (match_operand:HI 0 "register_operand" "")
3001         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3002    (clobber (reg:CC FLAGS_REG))]
3003   "reload_completed
3004    && true_regnum (operands[0]) == true_regnum (operands[1])"
3005   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3006               (clobber (reg:CC FLAGS_REG))])]
3007   "")
3008
3009 (define_expand "zero_extendqisi2"
3010   [(parallel
3011     [(set (match_operand:SI 0 "register_operand" "")
3012        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3013      (clobber (reg:CC FLAGS_REG))])]
3014   ""
3015   "")
3016
3017 (define_insn "*zero_extendqisi2_and"
3018   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3019      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022   "#"
3023   [(set_attr "type" "alu1")
3024    (set_attr "mode" "SI")])
3025
3026 (define_insn "*zero_extendqisi2_movzbw_and"
3027   [(set (match_operand:SI 0 "register_operand" "=r,r")
3028      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029    (clobber (reg:CC FLAGS_REG))]
3030   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031   "#"
3032   [(set_attr "type" "imovx,alu1")
3033    (set_attr "mode" "SI")])
3034
3035 (define_insn "*zero_extendqisi2_movzbw"
3036   [(set (match_operand:SI 0 "register_operand" "=r")
3037      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039   "movz{bl|x}\t{%1, %0|%0, %1}"
3040   [(set_attr "type" "imovx")
3041    (set_attr "mode" "SI")])
3042
3043 ;; For the movzbl case strip only the clobber
3044 (define_split
3045   [(set (match_operand:SI 0 "register_operand" "")
3046         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3047    (clobber (reg:CC FLAGS_REG))]
3048   "reload_completed 
3049    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051   [(set (match_dup 0)
3052         (zero_extend:SI (match_dup 1)))])
3053
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3056 (define_split
3057   [(set (match_operand:SI 0 "register_operand" "")
3058         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3059    (clobber (reg:CC FLAGS_REG))]
3060   "reload_completed
3061    && ANY_QI_REG_P (operands[0])
3062    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3063    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065   [(set (match_dup 0) (const_int 0))
3066    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067   "operands[2] = gen_lowpart (QImode, operands[0]);")
3068
3069 ;; Rest is handled by single and.
3070 (define_split
3071   [(set (match_operand:SI 0 "register_operand" "")
3072         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3073    (clobber (reg:CC FLAGS_REG))]
3074   "reload_completed
3075    && true_regnum (operands[0]) == true_regnum (operands[1])"
3076   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3077               (clobber (reg:CC FLAGS_REG))])]
3078   "")
3079
3080 ;; %%% Kill me once multi-word ops are sane.
3081 (define_expand "zero_extendsidi2"
3082   [(set (match_operand:DI 0 "register_operand" "=r")
3083      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3084   ""
3085   "if (!TARGET_64BIT)
3086      {
3087        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3088        DONE;
3089      }
3090   ")
3091
3092 (define_insn "zero_extendsidi2_32"
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,m,m")))
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_32_1"
3107   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3108         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3109    (clobber (reg:CC FLAGS_REG))]
3110   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3111   "@
3112    #
3113    #
3114    #
3115    movd\t{%1, %0|%0, %1}
3116    movd\t{%1, %0|%0, %1}"
3117   [(set_attr "mode" "SI,SI,SI,DI,TI")
3118    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3119
3120 (define_insn "zero_extendsidi2_rex64"
3121   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3122      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3123   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3124   "@
3125    mov\t{%k1, %k0|%k0, %k1}
3126    #
3127    movd\t{%1, %0|%0, %1}
3128    movd\t{%1, %0|%0, %1}"
3129   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3130    (set_attr "mode" "SI,DI,DI,TI")])
3131
3132 (define_insn "*zero_extendsidi2_rex64_1"
3133   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3134      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3135   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3136   "@
3137    mov\t{%k1, %k0|%k0, %k1}
3138    #
3139    movd\t{%1, %0|%0, %1}
3140    movd\t{%1, %0|%0, %1}"
3141   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3142    (set_attr "mode" "SI,DI,SI,SI")])
3143
3144 (define_split
3145   [(set (match_operand:DI 0 "memory_operand" "")
3146      (zero_extend:DI (match_dup 0)))]
3147   "TARGET_64BIT"
3148   [(set (match_dup 4) (const_int 0))]
3149   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3150
3151 (define_split 
3152   [(set (match_operand:DI 0 "register_operand" "")
3153         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3154    (clobber (reg:CC FLAGS_REG))]
3155   "!TARGET_64BIT && reload_completed
3156    && true_regnum (operands[0]) == true_regnum (operands[1])"
3157   [(set (match_dup 4) (const_int 0))]
3158   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3159
3160 (define_split 
3161   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3162         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3163    (clobber (reg:CC FLAGS_REG))]
3164   "!TARGET_64BIT && reload_completed
3165    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3166   [(set (match_dup 3) (match_dup 1))
3167    (set (match_dup 4) (const_int 0))]
3168   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3169
3170 (define_insn "zero_extendhidi2"
3171   [(set (match_operand:DI 0 "register_operand" "=r,r")
3172      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3173   "TARGET_64BIT"
3174   "@
3175    movz{wl|x}\t{%1, %k0|%k0, %1}
3176    movz{wq|x}\t{%1, %0|%0, %1}"
3177   [(set_attr "type" "imovx")
3178    (set_attr "mode" "SI,DI")])
3179
3180 (define_insn "zero_extendqidi2"
3181   [(set (match_operand:DI 0 "register_operand" "=r,r")
3182      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3183   "TARGET_64BIT"
3184   "@
3185    movz{bl|x}\t{%1, %k0|%k0, %1}
3186    movz{bq|x}\t{%1, %0|%0, %1}"
3187   [(set_attr "type" "imovx")
3188    (set_attr "mode" "SI,DI")])
3189 \f
3190 ;; Sign extension instructions
3191
3192 (define_expand "extendsidi2"
3193   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3194                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3195               (clobber (reg:CC FLAGS_REG))
3196               (clobber (match_scratch:SI 2 ""))])]
3197   ""
3198 {
3199   if (TARGET_64BIT)
3200     {
3201       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3202       DONE;
3203     }
3204 })
3205
3206 (define_insn "*extendsidi2_1"
3207   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3208         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3209    (clobber (reg:CC FLAGS_REG))
3210    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3211   "!TARGET_64BIT"
3212   "#")
3213
3214 (define_insn "extendsidi2_rex64"
3215   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3216         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3217   "TARGET_64BIT"
3218   "@
3219    {cltq|cdqe}
3220    movs{lq|x}\t{%1,%0|%0, %1}"
3221   [(set_attr "type" "imovx")
3222    (set_attr "mode" "DI")
3223    (set_attr "prefix_0f" "0")
3224    (set_attr "modrm" "0,1")])
3225
3226 (define_insn "extendhidi2"
3227   [(set (match_operand:DI 0 "register_operand" "=r")
3228         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3229   "TARGET_64BIT"
3230   "movs{wq|x}\t{%1,%0|%0, %1}"
3231   [(set_attr "type" "imovx")
3232    (set_attr "mode" "DI")])
3233
3234 (define_insn "extendqidi2"
3235   [(set (match_operand:DI 0 "register_operand" "=r")
3236         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3237   "TARGET_64BIT"
3238   "movs{bq|x}\t{%1,%0|%0, %1}"
3239    [(set_attr "type" "imovx")
3240     (set_attr "mode" "DI")])
3241
3242 ;; Extend to memory case when source register does die.
3243 (define_split 
3244   [(set (match_operand:DI 0 "memory_operand" "")
3245         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3246    (clobber (reg:CC FLAGS_REG))
3247    (clobber (match_operand:SI 2 "register_operand" ""))]
3248   "(reload_completed
3249     && dead_or_set_p (insn, operands[1])
3250     && !reg_mentioned_p (operands[1], operands[0]))"
3251   [(set (match_dup 3) (match_dup 1))
3252    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3253               (clobber (reg:CC FLAGS_REG))])
3254    (set (match_dup 4) (match_dup 1))]
3255   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3256
3257 ;; Extend to memory case when source register does not die.
3258 (define_split 
3259   [(set (match_operand:DI 0 "memory_operand" "")
3260         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3261    (clobber (reg:CC FLAGS_REG))
3262    (clobber (match_operand:SI 2 "register_operand" ""))]
3263   "reload_completed"
3264   [(const_int 0)]
3265 {
3266   split_di (&operands[0], 1, &operands[3], &operands[4]);
3267
3268   emit_move_insn (operands[3], operands[1]);
3269
3270   /* Generate a cltd if possible and doing so it profitable.  */
3271   if (true_regnum (operands[1]) == 0
3272       && true_regnum (operands[2]) == 1
3273       && (optimize_size || TARGET_USE_CLTD))
3274     {
3275       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3276     }
3277   else
3278     {
3279       emit_move_insn (operands[2], operands[1]);
3280       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3281     }
3282   emit_move_insn (operands[4], operands[2]);
3283   DONE;
3284 })
3285
3286 ;; Extend to register case.  Optimize case where source and destination
3287 ;; registers match and cases where we can use cltd.
3288 (define_split 
3289   [(set (match_operand:DI 0 "register_operand" "")
3290         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3291    (clobber (reg:CC FLAGS_REG))
3292    (clobber (match_scratch:SI 2 ""))]
3293   "reload_completed"
3294   [(const_int 0)]
3295 {
3296   split_di (&operands[0], 1, &operands[3], &operands[4]);
3297
3298   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3299     emit_move_insn (operands[3], operands[1]);
3300
3301   /* Generate a cltd if possible and doing so it profitable.  */
3302   if (true_regnum (operands[3]) == 0
3303       && (optimize_size || TARGET_USE_CLTD))
3304     {
3305       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3306       DONE;
3307     }
3308
3309   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3310     emit_move_insn (operands[4], operands[1]);
3311
3312   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3313   DONE;
3314 })
3315
3316 (define_insn "extendhisi2"
3317   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3318         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3319   ""
3320 {
3321   switch (get_attr_prefix_0f (insn))
3322     {
3323     case 0:
3324       return "{cwtl|cwde}";
3325     default:
3326       return "movs{wl|x}\t{%1,%0|%0, %1}";
3327     }
3328 }
3329   [(set_attr "type" "imovx")
3330    (set_attr "mode" "SI")
3331    (set (attr "prefix_0f")
3332      ;; movsx is short decodable while cwtl is vector decoded.
3333      (if_then_else (and (eq_attr "cpu" "!k6")
3334                         (eq_attr "alternative" "0"))
3335         (const_string "0")
3336         (const_string "1")))
3337    (set (attr "modrm")
3338      (if_then_else (eq_attr "prefix_0f" "0")
3339         (const_string "0")
3340         (const_string "1")))])
3341
3342 (define_insn "*extendhisi2_zext"
3343   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3344         (zero_extend:DI
3345           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3346   "TARGET_64BIT"
3347 {
3348   switch (get_attr_prefix_0f (insn))
3349     {
3350     case 0:
3351       return "{cwtl|cwde}";
3352     default:
3353       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3354     }
3355 }
3356   [(set_attr "type" "imovx")
3357    (set_attr "mode" "SI")
3358    (set (attr "prefix_0f")
3359      ;; movsx is short decodable while cwtl is vector decoded.
3360      (if_then_else (and (eq_attr "cpu" "!k6")
3361                         (eq_attr "alternative" "0"))
3362         (const_string "0")
3363         (const_string "1")))
3364    (set (attr "modrm")
3365      (if_then_else (eq_attr "prefix_0f" "0")
3366         (const_string "0")
3367         (const_string "1")))])
3368
3369 (define_insn "extendqihi2"
3370   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3371         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3372   ""
3373 {
3374   switch (get_attr_prefix_0f (insn))
3375     {
3376     case 0:
3377       return "{cbtw|cbw}";
3378     default:
3379       return "movs{bw|x}\t{%1,%0|%0, %1}";
3380     }
3381 }
3382   [(set_attr "type" "imovx")
3383    (set_attr "mode" "HI")
3384    (set (attr "prefix_0f")
3385      ;; movsx is short decodable while cwtl is vector decoded.
3386      (if_then_else (and (eq_attr "cpu" "!k6")
3387                         (eq_attr "alternative" "0"))
3388         (const_string "0")
3389         (const_string "1")))
3390    (set (attr "modrm")
3391      (if_then_else (eq_attr "prefix_0f" "0")
3392         (const_string "0")
3393         (const_string "1")))])
3394
3395 (define_insn "extendqisi2"
3396   [(set (match_operand:SI 0 "register_operand" "=r")
3397         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3398   ""
3399   "movs{bl|x}\t{%1,%0|%0, %1}"
3400    [(set_attr "type" "imovx")
3401     (set_attr "mode" "SI")])
3402
3403 (define_insn "*extendqisi2_zext"
3404   [(set (match_operand:DI 0 "register_operand" "=r")
3405         (zero_extend:DI
3406           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3407   "TARGET_64BIT"
3408   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3409    [(set_attr "type" "imovx")
3410     (set_attr "mode" "SI")])
3411 \f
3412 ;; Conversions between float and double.
3413
3414 ;; These are all no-ops in the model used for the 80387.  So just
3415 ;; emit moves.
3416
3417 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3418 (define_insn "*dummy_extendsfdf2"
3419   [(set (match_operand:DF 0 "push_operand" "=<")
3420         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3421   "0"
3422   "#")
3423
3424 (define_split
3425   [(set (match_operand:DF 0 "push_operand" "")
3426         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3427   "!TARGET_64BIT"
3428   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3429    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3430
3431 (define_split
3432   [(set (match_operand:DF 0 "push_operand" "")
3433         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3434   "TARGET_64BIT"
3435   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3436    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3437
3438 (define_insn "*dummy_extendsfxf2"
3439   [(set (match_operand:XF 0 "push_operand" "=<")
3440         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3441   "0"
3442   "#")
3443
3444 (define_split
3445   [(set (match_operand:XF 0 "push_operand" "")
3446         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3447   ""
3448   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3449    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3450   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3451
3452 (define_split
3453   [(set (match_operand:XF 0 "push_operand" "")
3454         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3455   "TARGET_64BIT"
3456   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3457    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3458   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3459
3460 (define_split
3461   [(set (match_operand:XF 0 "push_operand" "")
3462         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3463   ""
3464   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3465    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3466   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3467
3468 (define_split
3469   [(set (match_operand:XF 0 "push_operand" "")
3470         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3471   "TARGET_64BIT"
3472   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3473    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3474   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3475
3476 (define_expand "extendsfdf2"
3477   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3478         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3479   "TARGET_80387 || TARGET_SSE2"
3480 {
3481   /* ??? Needed for compress_float_constant since all fp constants
3482      are LEGITIMATE_CONSTANT_P.  */
3483   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3484     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3485   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3486     operands[1] = force_reg (SFmode, operands[1]);
3487 })
3488
3489 (define_insn "*extendsfdf2_1"
3490   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3491         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3492   "(TARGET_80387 || TARGET_SSE2)
3493    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3494 {
3495   switch (which_alternative)
3496     {
3497     case 0:
3498       return output_387_reg_move (insn, operands);
3499
3500     case 1:
3501       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3502         return "fstp%z0\t%y0";
3503       else
3504         return "fst%z0\t%y0";
3505
3506     case 2:
3507       return "cvtss2sd\t{%1, %0|%0, %1}";
3508
3509     default:
3510       abort ();
3511     }
3512 }
3513   [(set_attr "type" "fmov,fmov,ssecvt")
3514    (set_attr "mode" "SF,XF,DF")])
3515
3516 (define_insn "*extendsfdf2_1_sse_only"
3517   [(set (match_operand:DF 0 "register_operand" "=Y")
3518         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3519   "!TARGET_80387 && TARGET_SSE2
3520    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3521   "cvtss2sd\t{%1, %0|%0, %1}"
3522   [(set_attr "type" "ssecvt")
3523    (set_attr "mode" "DF")])
3524
3525 (define_expand "extendsfxf2"
3526   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3527         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3528   "TARGET_80387"
3529 {
3530   /* ??? Needed for compress_float_constant since all fp constants
3531      are LEGITIMATE_CONSTANT_P.  */
3532   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3533     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3534   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3535     operands[1] = force_reg (SFmode, operands[1]);
3536 })
3537
3538 (define_insn "*extendsfxf2_1"
3539   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3540         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3541   "TARGET_80387
3542    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3543 {
3544   switch (which_alternative)
3545     {
3546     case 0:
3547       return output_387_reg_move (insn, operands);
3548
3549     case 1:
3550       /* There is no non-popping store to memory for XFmode.  So if
3551          we need one, follow the store with a load.  */
3552       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3554       else
3555         return "fstp%z0\t%y0";
3556
3557     default:
3558       abort ();
3559     }
3560 }
3561   [(set_attr "type" "fmov")
3562    (set_attr "mode" "SF,XF")])
3563
3564 (define_expand "extenddfxf2"
3565   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3566         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3567   "TARGET_80387"
3568 {
3569   /* ??? Needed for compress_float_constant since all fp constants
3570      are LEGITIMATE_CONSTANT_P.  */
3571   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3572     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3573   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3574     operands[1] = force_reg (DFmode, operands[1]);
3575 })
3576
3577 (define_insn "*extenddfxf2_1"
3578   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3579         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3580   "TARGET_80387
3581    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3582 {
3583   switch (which_alternative)
3584     {
3585     case 0:
3586       return output_387_reg_move (insn, operands);
3587
3588     case 1:
3589       /* There is no non-popping store to memory for XFmode.  So if
3590          we need one, follow the store with a load.  */
3591       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3592         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3593       else
3594         return "fstp%z0\t%y0";
3595
3596     default:
3597       abort ();
3598     }
3599 }
3600   [(set_attr "type" "fmov")
3601    (set_attr "mode" "DF,XF")])
3602
3603 ;; %%% This seems bad bad news.
3604 ;; This cannot output into an f-reg because there is no way to be sure
3605 ;; of truncating in that case.  Otherwise this is just like a simple move
3606 ;; insn.  So we pretend we can output to a reg in order to get better
3607 ;; register preferencing, but we really use a stack slot.
3608
3609 (define_expand "truncdfsf2"
3610   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3611                    (float_truncate:SF
3612                     (match_operand:DF 1 "register_operand" "")))
3613               (clobber (match_dup 2))])]
3614   "TARGET_80387 || TARGET_SSE2"
3615   "
3616    if (!TARGET_80387)
3617      {
3618         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3619         DONE;
3620      }
3621    else if (flag_unsafe_math_optimizations)
3622      {
3623         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3624         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3625         if (reg != operands[0])
3626           emit_move_insn (operands[0], reg);
3627         DONE;
3628      }
3629    else
3630      operands[2] = assign_386_stack_local (SFmode, 0);
3631 ")
3632
3633 (define_insn "truncdfsf2_noop"
3634   [(set (match_operand:SF 0 "register_operand" "=f")
3635         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3636   "TARGET_80387 && flag_unsafe_math_optimizations"
3637 {
3638   return output_387_reg_move (insn, operands);
3639 }
3640   [(set_attr "type" "fmov")
3641    (set_attr "mode" "SF")])
3642
3643 (define_insn "*truncdfsf2_1"
3644   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3645         (float_truncate:SF
3646          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3647    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3648   "TARGET_80387 && !TARGET_SSE2"
3649 {
3650   switch (which_alternative)
3651     {
3652     case 0:
3653       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3654         return "fstp%z0\t%y0";
3655       else
3656         return "fst%z0\t%y0";
3657     default:
3658       abort ();
3659     }
3660 }
3661   [(set_attr "type" "fmov,multi,multi,multi")
3662    (set_attr "mode" "SF,SF,SF,SF")])
3663
3664 (define_insn "*truncdfsf2_1_sse"
3665   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3666         (float_truncate:SF
3667          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3668    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3669   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3670 {
3671   switch (which_alternative)
3672     {
3673     case 0:
3674       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3675         return "fstp%z0\t%y0";
3676       else
3677         return "fst%z0\t%y0";
3678     case 4:
3679       return "#";
3680     default:
3681       abort ();
3682     }
3683 }
3684   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3685    (set_attr "mode" "SF,SF,SF,SF,DF")])
3686
3687 (define_insn "*truncdfsf2_1_sse_nooverlap"
3688   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3689         (float_truncate:SF
3690          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3691    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3692   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3693 {
3694   switch (which_alternative)
3695     {
3696     case 0:
3697       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3698         return "fstp%z0\t%y0";
3699       else
3700         return "fst%z0\t%y0";
3701     case 4:
3702       return "#";
3703     default:
3704       abort ();
3705     }
3706 }
3707   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3708    (set_attr "mode" "SF,SF,SF,SF,DF")])
3709
3710 (define_insn "*truncdfsf2_2"
3711   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3712         (float_truncate:SF
3713          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3714   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3715    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3716 {
3717   switch (which_alternative)
3718     {
3719     case 0:
3720     case 1:
3721       return "cvtsd2ss\t{%1, %0|%0, %1}";
3722     case 2:
3723       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3724         return "fstp%z0\t%y0";
3725       else
3726         return "fst%z0\t%y0";
3727     default:
3728       abort ();
3729     }
3730 }
3731   [(set_attr "type" "ssecvt,ssecvt,fmov")
3732    (set_attr "athlon_decode" "vector,double,*")
3733    (set_attr "mode" "SF,SF,SF")])
3734
3735 (define_insn "*truncdfsf2_2_nooverlap"
3736   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3737         (float_truncate:SF
3738          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3739   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3740    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3741 {
3742   switch (which_alternative)
3743     {
3744     case 0:
3745       return "#";
3746     case 1:
3747       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3748         return "fstp%z0\t%y0";
3749       else
3750         return "fst%z0\t%y0";
3751     default:
3752       abort ();
3753     }
3754 }
3755   [(set_attr "type" "ssecvt,fmov")
3756    (set_attr "mode" "DF,SF")])
3757
3758 (define_insn "*truncdfsf2_3"
3759   [(set (match_operand:SF 0 "memory_operand" "=m")
3760         (float_truncate:SF
3761          (match_operand:DF 1 "register_operand" "f")))]
3762   "TARGET_80387"
3763 {
3764   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3765     return "fstp%z0\t%y0";
3766   else
3767     return "fst%z0\t%y0";
3768 }
3769   [(set_attr "type" "fmov")
3770    (set_attr "mode" "SF")])
3771
3772 (define_insn "truncdfsf2_sse_only"
3773   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3774         (float_truncate:SF
3775          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3776   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3777   "cvtsd2ss\t{%1, %0|%0, %1}"
3778   [(set_attr "type" "ssecvt")
3779    (set_attr "athlon_decode" "vector,double")
3780    (set_attr "mode" "SF")])
3781
3782 (define_insn "*truncdfsf2_sse_only_nooverlap"
3783   [(set (match_operand:SF 0 "register_operand" "=&Y")
3784         (float_truncate:SF
3785          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3786   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3787   "#"
3788   [(set_attr "type" "ssecvt")
3789    (set_attr "mode" "DF")])
3790
3791 (define_split
3792   [(set (match_operand:SF 0 "memory_operand" "")
3793         (float_truncate:SF
3794          (match_operand:DF 1 "register_operand" "")))
3795    (clobber (match_operand:SF 2 "memory_operand" ""))]
3796   "TARGET_80387"
3797   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3798   "")
3799
3800 ; Avoid possible reformatting penalty on the destination by first
3801 ; zeroing it out
3802 (define_split
3803   [(set (match_operand:SF 0 "register_operand" "")
3804         (float_truncate:SF
3805          (match_operand:DF 1 "nonimmediate_operand" "")))
3806    (clobber (match_operand 2 "" ""))]
3807   "TARGET_80387 && reload_completed
3808    && SSE_REG_P (operands[0])
3809    && !STACK_REG_P (operands[1])"
3810   [(const_int 0)]
3811 {
3812   rtx src, dest;
3813   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3814     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3815   else
3816     {
3817       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3818       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3819       /* simplify_gen_subreg refuses to widen memory references.  */
3820       if (GET_CODE (src) == SUBREG)
3821         alter_subreg (&src);
3822       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3823         abort ();
3824       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3825       emit_insn (gen_cvtsd2ss (dest, dest, src));
3826     }
3827   DONE;
3828 })
3829
3830 (define_split
3831   [(set (match_operand:SF 0 "register_operand" "")
3832         (float_truncate:SF
3833          (match_operand:DF 1 "nonimmediate_operand" "")))]
3834   "TARGET_80387 && reload_completed
3835    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3836   [(const_int 0)]
3837 {
3838   rtx src, dest;
3839   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3840   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3841   /* simplify_gen_subreg refuses to widen memory references.  */
3842   if (GET_CODE (src) == SUBREG)
3843     alter_subreg (&src);
3844   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3845     abort ();
3846   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3847   emit_insn (gen_cvtsd2ss (dest, dest, src));
3848   DONE;
3849 })
3850
3851 (define_split
3852   [(set (match_operand:SF 0 "register_operand" "")
3853         (float_truncate:SF
3854          (match_operand:DF 1 "fp_register_operand" "")))
3855    (clobber (match_operand:SF 2 "memory_operand" ""))]
3856   "TARGET_80387 && reload_completed"
3857   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3858    (set (match_dup 0) (match_dup 2))]
3859   "")
3860
3861 (define_expand "truncxfsf2"
3862   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3863                    (float_truncate:SF
3864                     (match_operand:XF 1 "register_operand" "")))
3865               (clobber (match_dup 2))])]
3866   "TARGET_80387"
3867   "
3868   if (flag_unsafe_math_optimizations)
3869     {
3870       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3871       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3872       if (reg != operands[0])
3873         emit_move_insn (operands[0], reg);
3874       DONE;
3875     }
3876   else
3877     operands[2] = assign_386_stack_local (SFmode, 0);
3878   ")
3879
3880 (define_insn "truncxfsf2_noop"
3881   [(set (match_operand:SF 0 "register_operand" "=f")
3882         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3883   "TARGET_80387 && flag_unsafe_math_optimizations"
3884 {
3885   return output_387_reg_move (insn, operands);
3886 }
3887   [(set_attr "type" "fmov")
3888    (set_attr "mode" "SF")])
3889
3890 (define_insn "*truncxfsf2_1"
3891   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3892         (float_truncate:SF
3893          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3894    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3895   "TARGET_80387"
3896 {
3897   switch (which_alternative)
3898     {
3899     case 0:
3900       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3901         return "fstp%z0\t%y0";
3902       else
3903         return "fst%z0\t%y0";
3904     default:
3905       abort();
3906     }
3907 }
3908   [(set_attr "type" "fmov,multi,multi,multi")
3909    (set_attr "mode" "SF")])
3910
3911 (define_insn "*truncxfsf2_2"
3912   [(set (match_operand:SF 0 "memory_operand" "=m")
3913         (float_truncate:SF
3914          (match_operand:XF 1 "register_operand" "f")))]
3915   "TARGET_80387"
3916 {
3917   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3918     return "fstp%z0\t%y0";
3919   else
3920     return "fst%z0\t%y0";
3921 }
3922   [(set_attr "type" "fmov")
3923    (set_attr "mode" "SF")])
3924
3925 (define_split
3926   [(set (match_operand:SF 0 "memory_operand" "")
3927         (float_truncate:SF
3928          (match_operand:XF 1 "register_operand" "")))
3929    (clobber (match_operand:SF 2 "memory_operand" ""))]
3930   "TARGET_80387"
3931   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3932   "")
3933
3934 (define_split
3935   [(set (match_operand:SF 0 "register_operand" "")
3936         (float_truncate:SF
3937          (match_operand:XF 1 "register_operand" "")))
3938    (clobber (match_operand:SF 2 "memory_operand" ""))]
3939   "TARGET_80387 && reload_completed"
3940   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3941    (set (match_dup 0) (match_dup 2))]
3942   "")
3943
3944 (define_expand "truncxfdf2"
3945   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3946                    (float_truncate:DF
3947                     (match_operand:XF 1 "register_operand" "")))
3948               (clobber (match_dup 2))])]
3949   "TARGET_80387"
3950   "
3951   if (flag_unsafe_math_optimizations)
3952     {
3953       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3954       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3955       if (reg != operands[0])
3956         emit_move_insn (operands[0], reg);
3957       DONE;
3958     }
3959   else
3960     operands[2] = assign_386_stack_local (DFmode, 0);
3961   ")
3962
3963 (define_insn "truncxfdf2_noop"
3964   [(set (match_operand:DF 0 "register_operand" "=f")
3965         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3966   "TARGET_80387 && flag_unsafe_math_optimizations"
3967 {
3968   return output_387_reg_move (insn, operands);
3969 }
3970   [(set_attr "type" "fmov")
3971    (set_attr "mode" "DF")])
3972
3973 (define_insn "*truncxfdf2_1"
3974   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3975         (float_truncate:DF
3976          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3977    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3978   "TARGET_80387"
3979 {
3980   switch (which_alternative)
3981     {
3982     case 0:
3983       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3984         return "fstp%z0\t%y0";
3985       else
3986         return "fst%z0\t%y0";
3987     default:
3988       abort();
3989     }
3990   abort ();
3991 }
3992   [(set_attr "type" "fmov,multi,multi,multi")
3993    (set_attr "mode" "DF")])
3994
3995 (define_insn "*truncxfdf2_2"
3996   [(set (match_operand:DF 0 "memory_operand" "=m")
3997         (float_truncate:DF
3998           (match_operand:XF 1 "register_operand" "f")))]
3999   "TARGET_80387"
4000 {
4001   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4002     return "fstp%z0\t%y0";
4003   else
4004     return "fst%z0\t%y0";
4005 }
4006   [(set_attr "type" "fmov")
4007    (set_attr "mode" "DF")])
4008
4009 (define_split
4010   [(set (match_operand:DF 0 "memory_operand" "")
4011         (float_truncate:DF
4012          (match_operand:XF 1 "register_operand" "")))
4013    (clobber (match_operand:DF 2 "memory_operand" ""))]
4014   "TARGET_80387"
4015   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4016   "")
4017
4018 (define_split
4019   [(set (match_operand:DF 0 "register_operand" "")
4020         (float_truncate:DF
4021          (match_operand:XF 1 "register_operand" "")))
4022    (clobber (match_operand:DF 2 "memory_operand" ""))]
4023   "TARGET_80387 && reload_completed"
4024   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4025    (set (match_dup 0) (match_dup 2))]
4026   "")
4027
4028 \f
4029 ;; %%% Break up all these bad boys.
4030
4031 ;; Signed conversion to DImode.
4032
4033 (define_expand "fix_truncxfdi2"
4034   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4035                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4036               (clobber (reg:CC FLAGS_REG))])]
4037   "TARGET_80387"
4038   "")
4039
4040 (define_expand "fix_truncdfdi2"
4041   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4042                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4043               (clobber (reg:CC FLAGS_REG))])]
4044   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4045 {
4046   if (TARGET_64BIT && TARGET_SSE2)
4047    {
4048      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4049      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4050      if (out != operands[0])
4051         emit_move_insn (operands[0], out);
4052      DONE;
4053    }
4054 })
4055
4056 (define_expand "fix_truncsfdi2"
4057   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4058                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4059               (clobber (reg:CC FLAGS_REG))])] 
4060   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4061 {
4062   if (TARGET_SSE && TARGET_64BIT)
4063    {
4064      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4065      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4066      if (out != operands[0])
4067         emit_move_insn (operands[0], out);
4068      DONE;
4069    }
4070 })
4071
4072 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4073 ;; of the machinery.
4074 (define_insn_and_split "*fix_truncdi_1"
4075   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4076         (fix:DI (match_operand 1 "register_operand" "f,f")))
4077    (clobber (reg:CC FLAGS_REG))]
4078   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4079    && !reload_completed && !reload_in_progress
4080    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4081   "#"
4082   "&& 1"
4083   [(const_int 0)]
4084 {
4085   ix86_optimize_mode_switching = 1;
4086   operands[2] = assign_386_stack_local (HImode, 1);
4087   operands[3] = assign_386_stack_local (HImode, 2);
4088   if (memory_operand (operands[0], VOIDmode))
4089     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4090                                        operands[2], operands[3]));
4091   else
4092     {
4093       operands[4] = assign_386_stack_local (DImode, 0);
4094       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4095                                            operands[2], operands[3],
4096                                            operands[4]));
4097     }
4098   DONE;
4099 }
4100   [(set_attr "type" "fistp")
4101    (set_attr "mode" "DI")])
4102
4103 (define_insn "fix_truncdi_nomemory"
4104   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4105         (fix:DI (match_operand 1 "register_operand" "f,f")))
4106    (use (match_operand:HI 2 "memory_operand" "m,m"))
4107    (use (match_operand:HI 3 "memory_operand" "m,m"))
4108    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4109    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4110   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4111    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4112   "#"
4113   [(set_attr "type" "fistp")
4114    (set_attr "mode" "DI")])
4115
4116 (define_insn "fix_truncdi_memory"
4117   [(set (match_operand:DI 0 "memory_operand" "=m")
4118         (fix:DI (match_operand 1 "register_operand" "f")))
4119    (use (match_operand:HI 2 "memory_operand" "m"))
4120    (use (match_operand:HI 3 "memory_operand" "m"))
4121    (clobber (match_scratch:DF 4 "=&1f"))]
4122   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4123    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4124   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4125   [(set_attr "type" "fistp")
4126    (set_attr "mode" "DI")])
4127
4128 (define_split 
4129   [(set (match_operand:DI 0 "register_operand" "")
4130         (fix:DI (match_operand 1 "register_operand" "")))
4131    (use (match_operand:HI 2 "memory_operand" ""))
4132    (use (match_operand:HI 3 "memory_operand" ""))
4133    (clobber (match_operand:DI 4 "memory_operand" ""))
4134    (clobber (match_scratch 5 ""))]
4135   "reload_completed"
4136   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4137               (use (match_dup 2))
4138               (use (match_dup 3))
4139               (clobber (match_dup 5))])
4140    (set (match_dup 0) (match_dup 4))]
4141   "")
4142
4143 (define_split 
4144   [(set (match_operand:DI 0 "memory_operand" "")
4145         (fix:DI (match_operand 1 "register_operand" "")))
4146    (use (match_operand:HI 2 "memory_operand" ""))
4147    (use (match_operand:HI 3 "memory_operand" ""))
4148    (clobber (match_operand:DI 4 "memory_operand" ""))
4149    (clobber (match_scratch 5 ""))]
4150   "reload_completed"
4151   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4152               (use (match_dup 2))
4153               (use (match_dup 3))
4154               (clobber (match_dup 5))])]
4155   "")
4156
4157 ;; When SSE available, it is always faster to use it!
4158 (define_insn "fix_truncsfdi_sse"
4159   [(set (match_operand:DI 0 "register_operand" "=r,r")
4160         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4161   "TARGET_64BIT && TARGET_SSE"
4162   "cvttss2si{q}\t{%1, %0|%0, %1}"
4163   [(set_attr "type" "sseicvt")
4164    (set_attr "mode" "SF")
4165    (set_attr "athlon_decode" "double,vector")])
4166
4167 ;; Avoid vector decoded form of the instruction.
4168 (define_peephole2
4169   [(match_scratch:SF 2 "x")
4170    (set (match_operand:DI 0 "register_operand" "")
4171         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4172   "TARGET_K8 && !optimize_size"
4173   [(set (match_dup 2) (match_dup 1))
4174    (set (match_dup 0) (fix:DI (match_dup 2)))]
4175   "")
4176
4177 (define_insn "fix_truncdfdi_sse"
4178   [(set (match_operand:DI 0 "register_operand" "=r,r")
4179         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4180   "TARGET_64BIT && TARGET_SSE2"
4181   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4182   [(set_attr "type" "sseicvt,sseicvt")
4183    (set_attr "mode" "DF")
4184    (set_attr "athlon_decode" "double,vector")])
4185
4186 ;; Avoid vector decoded form of the instruction.
4187 (define_peephole2
4188   [(match_scratch:DF 2 "Y")
4189    (set (match_operand:DI 0 "register_operand" "")
4190         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4191   "TARGET_K8 && !optimize_size"
4192   [(set (match_dup 2) (match_dup 1))
4193    (set (match_dup 0) (fix:DI (match_dup 2)))]
4194   "")
4195
4196 ;; Signed conversion to SImode.
4197
4198 (define_expand "fix_truncxfsi2"
4199   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4200                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4201               (clobber (reg:CC FLAGS_REG))])]
4202   "TARGET_80387"
4203   "")
4204
4205 (define_expand "fix_truncdfsi2"
4206   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4207                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4208               (clobber (reg:CC FLAGS_REG))])]
4209   "TARGET_80387 || TARGET_SSE2"
4210 {
4211   if (TARGET_SSE2)
4212    {
4213      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4214      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4215      if (out != operands[0])
4216         emit_move_insn (operands[0], out);
4217      DONE;
4218    }
4219 })
4220
4221 (define_expand "fix_truncsfsi2"
4222   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4223                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4224               (clobber (reg:CC FLAGS_REG))])] 
4225   "TARGET_80387 || TARGET_SSE"
4226 {
4227   if (TARGET_SSE)
4228    {
4229      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4230      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4231      if (out != operands[0])
4232         emit_move_insn (operands[0], out);
4233      DONE;
4234    }
4235 })
4236
4237 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4238 ;; of the machinery.
4239 (define_insn_and_split "*fix_truncsi_1"
4240   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4241         (fix:SI (match_operand 1 "register_operand" "f,f")))
4242    (clobber (reg:CC FLAGS_REG))]
4243   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4244    && !reload_completed && !reload_in_progress
4245    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4246   "#"
4247   "&& 1"
4248   [(const_int 0)]
4249 {
4250   ix86_optimize_mode_switching = 1;
4251   operands[2] = assign_386_stack_local (HImode, 1);
4252   operands[3] = assign_386_stack_local (HImode, 2);
4253   if (memory_operand (operands[0], VOIDmode))
4254     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4255                                        operands[2], operands[3]));
4256   else
4257     {
4258       operands[4] = assign_386_stack_local (SImode, 0);
4259       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4260                                            operands[2], operands[3],
4261                                            operands[4]));
4262     }
4263   DONE;
4264 }
4265   [(set_attr "type" "fistp")
4266    (set_attr "mode" "SI")])
4267
4268 (define_insn "fix_truncsi_nomemory"
4269   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4270         (fix:SI (match_operand 1 "register_operand" "f,f")))
4271    (use (match_operand:HI 2 "memory_operand" "m,m"))
4272    (use (match_operand:HI 3 "memory_operand" "m,m"))
4273    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4274   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4275    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4276   "#"
4277   [(set_attr "type" "fistp")
4278    (set_attr "mode" "SI")])
4279
4280 (define_insn "fix_truncsi_memory"
4281   [(set (match_operand:SI 0 "memory_operand" "=m")
4282         (fix:SI (match_operand 1 "register_operand" "f")))
4283    (use (match_operand:HI 2 "memory_operand" "m"))
4284    (use (match_operand:HI 3 "memory_operand" "m"))]
4285   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4286    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4287   "* return output_fix_trunc (insn, operands);"
4288   [(set_attr "type" "fistp")
4289    (set_attr "mode" "SI")])
4290
4291 ;; When SSE available, it is always faster to use it!
4292 (define_insn "fix_truncsfsi_sse"
4293   [(set (match_operand:SI 0 "register_operand" "=r,r")
4294         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4295   "TARGET_SSE"
4296   "cvttss2si\t{%1, %0|%0, %1}"
4297   [(set_attr "type" "sseicvt")
4298    (set_attr "mode" "DF")
4299    (set_attr "athlon_decode" "double,vector")])
4300
4301 ;; Avoid vector decoded form of the instruction.
4302 (define_peephole2
4303   [(match_scratch:SF 2 "x")
4304    (set (match_operand:SI 0 "register_operand" "")
4305         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4306   "TARGET_K8 && !optimize_size"
4307   [(set (match_dup 2) (match_dup 1))
4308    (set (match_dup 0) (fix:SI (match_dup 2)))]
4309   "")
4310
4311 (define_insn "fix_truncdfsi_sse"
4312   [(set (match_operand:SI 0 "register_operand" "=r,r")
4313         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4314   "TARGET_SSE2"
4315   "cvttsd2si\t{%1, %0|%0, %1}"
4316   [(set_attr "type" "sseicvt")
4317    (set_attr "mode" "DF")
4318    (set_attr "athlon_decode" "double,vector")])
4319
4320 ;; Avoid vector decoded form of the instruction.
4321 (define_peephole2
4322   [(match_scratch:DF 2 "Y")
4323    (set (match_operand:SI 0 "register_operand" "")
4324         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4325   "TARGET_K8 && !optimize_size"
4326   [(set (match_dup 2) (match_dup 1))
4327    (set (match_dup 0) (fix:SI (match_dup 2)))]
4328   "")
4329
4330 (define_split 
4331   [(set (match_operand:SI 0 "register_operand" "")
4332         (fix:SI (match_operand 1 "register_operand" "")))
4333    (use (match_operand:HI 2 "memory_operand" ""))
4334    (use (match_operand:HI 3 "memory_operand" ""))
4335    (clobber (match_operand:SI 4 "memory_operand" ""))]
4336   "reload_completed"
4337   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4338               (use (match_dup 2))
4339               (use (match_dup 3))])
4340    (set (match_dup 0) (match_dup 4))]
4341   "")
4342
4343 (define_split 
4344   [(set (match_operand:SI 0 "memory_operand" "")
4345         (fix:SI (match_operand 1 "register_operand" "")))
4346    (use (match_operand:HI 2 "memory_operand" ""))
4347    (use (match_operand:HI 3 "memory_operand" ""))
4348    (clobber (match_operand:SI 4 "memory_operand" ""))]
4349   "reload_completed"
4350   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4351               (use (match_dup 2))
4352               (use (match_dup 3))])]
4353   "")
4354
4355 ;; Signed conversion to HImode.
4356
4357 (define_expand "fix_truncxfhi2"
4358   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4359                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4360               (clobber (reg:CC FLAGS_REG))])] 
4361   "TARGET_80387"
4362   "")
4363
4364 (define_expand "fix_truncdfhi2"
4365   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4366                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4367               (clobber (reg:CC FLAGS_REG))])]
4368   "TARGET_80387 && !TARGET_SSE2"
4369   "")
4370
4371 (define_expand "fix_truncsfhi2"
4372   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4373                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4374                (clobber (reg:CC FLAGS_REG))])]
4375   "TARGET_80387 && !TARGET_SSE"
4376   "")
4377
4378 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4379 ;; of the machinery.
4380 (define_insn_and_split "*fix_trunchi_1"
4381   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4382         (fix:HI (match_operand 1 "register_operand" "f,f")))
4383    (clobber (reg:CC FLAGS_REG))]
4384   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4385    && !reload_completed && !reload_in_progress
4386    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4387   "#"
4388   ""
4389   [(const_int 0)]
4390 {
4391   ix86_optimize_mode_switching = 1;
4392   operands[2] = assign_386_stack_local (HImode, 1);
4393   operands[3] = assign_386_stack_local (HImode, 2);
4394   if (memory_operand (operands[0], VOIDmode))
4395     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4396                                        operands[2], operands[3]));
4397   else
4398     {
4399       operands[4] = assign_386_stack_local (HImode, 0);
4400       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4401                                            operands[2], operands[3],
4402                                            operands[4]));
4403     }
4404   DONE;
4405 }
4406   [(set_attr "type" "fistp")
4407    (set_attr "mode" "HI")])
4408
4409 (define_insn "fix_trunchi_nomemory"
4410   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4411         (fix:HI (match_operand 1 "register_operand" "f,f")))
4412    (use (match_operand:HI 2 "memory_operand" "m,m"))
4413    (use (match_operand:HI 3 "memory_operand" "m,m"))
4414    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4415   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4416    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4417   "#"
4418   [(set_attr "type" "fistp")
4419    (set_attr "mode" "HI")])
4420
4421 (define_insn "fix_trunchi_memory"
4422   [(set (match_operand:HI 0 "memory_operand" "=m")
4423         (fix:HI (match_operand 1 "register_operand" "f")))
4424    (use (match_operand:HI 2 "memory_operand" "m"))
4425    (use (match_operand:HI 3 "memory_operand" "m"))]
4426   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4427    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4428   "* return output_fix_trunc (insn, operands);"
4429   [(set_attr "type" "fistp")
4430    (set_attr "mode" "HI")])
4431
4432 (define_split 
4433   [(set (match_operand:HI 0 "memory_operand" "")
4434         (fix:HI (match_operand 1 "register_operand" "")))
4435    (use (match_operand:HI 2 "memory_operand" ""))
4436    (use (match_operand:HI 3 "memory_operand" ""))
4437    (clobber (match_operand:HI 4 "memory_operand" ""))]
4438   "reload_completed"
4439   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4440               (use (match_dup 2))
4441               (use (match_dup 3))])]
4442   "")
4443
4444 (define_split 
4445   [(set (match_operand:HI 0 "register_operand" "")
4446         (fix:HI (match_operand 1 "register_operand" "")))
4447    (use (match_operand:HI 2 "memory_operand" ""))
4448    (use (match_operand:HI 3 "memory_operand" ""))
4449    (clobber (match_operand:HI 4 "memory_operand" ""))]
4450   "reload_completed"
4451   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4452               (use (match_dup 2))
4453               (use (match_dup 3))
4454               (clobber (match_dup 4))])
4455    (set (match_dup 0) (match_dup 4))]
4456   "")
4457
4458 ;; %% Not used yet.
4459 (define_insn "x86_fnstcw_1"
4460   [(set (match_operand:HI 0 "memory_operand" "=m")
4461         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4462   "TARGET_80387"
4463   "fnstcw\t%0"
4464   [(set_attr "length" "2")
4465    (set_attr "mode" "HI")
4466    (set_attr "unit" "i387")])
4467
4468 (define_insn "x86_fldcw_1"
4469   [(set (reg:HI FPSR_REG)
4470         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4471   "TARGET_80387"
4472   "fldcw\t%0"
4473   [(set_attr "length" "2")
4474    (set_attr "mode" "HI")
4475    (set_attr "unit" "i387")
4476    (set_attr "athlon_decode" "vector")])
4477 \f
4478 ;; Conversion between fixed point and floating point.
4479
4480 ;; Even though we only accept memory inputs, the backend _really_
4481 ;; wants to be able to do this between registers.
4482
4483 (define_expand "floathisf2"
4484   [(set (match_operand:SF 0 "register_operand" "")
4485         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4486   "TARGET_SSE || TARGET_80387"
4487 {
4488   if (TARGET_SSE && TARGET_SSE_MATH)
4489     {
4490       emit_insn (gen_floatsisf2 (operands[0],
4491                                  convert_to_mode (SImode, operands[1], 0)));
4492       DONE;
4493     }
4494 })
4495
4496 (define_insn "*floathisf2_1"
4497   [(set (match_operand:SF 0 "register_operand" "=f,f")
4498         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4499   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4500   "@
4501    fild%z1\t%1
4502    #"
4503   [(set_attr "type" "fmov,multi")
4504    (set_attr "mode" "SF")
4505    (set_attr "fp_int_src" "true")])
4506
4507 (define_expand "floatsisf2"
4508   [(set (match_operand:SF 0 "register_operand" "")
4509         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4510   "TARGET_SSE || TARGET_80387"
4511   "")
4512
4513 (define_insn "*floatsisf2_i387"
4514   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4515         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4516   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4517   "@
4518    fild%z1\t%1
4519    #
4520    cvtsi2ss\t{%1, %0|%0, %1}
4521    cvtsi2ss\t{%1, %0|%0, %1}"
4522   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4523    (set_attr "mode" "SF")
4524    (set_attr "athlon_decode" "*,*,vector,double")
4525    (set_attr "fp_int_src" "true")])
4526
4527 (define_insn "*floatsisf2_sse"
4528   [(set (match_operand:SF 0 "register_operand" "=x,x")
4529         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4530   "TARGET_SSE"
4531   "cvtsi2ss\t{%1, %0|%0, %1}"
4532   [(set_attr "type" "sseicvt")
4533    (set_attr "mode" "SF")
4534    (set_attr "athlon_decode" "vector,double")
4535    (set_attr "fp_int_src" "true")])
4536
4537 ; Avoid possible reformatting penalty on the destination by first
4538 ; zeroing it out
4539 (define_split
4540   [(set (match_operand:SF 0 "register_operand" "")
4541         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4542   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4543    && SSE_REG_P (operands[0])"
4544   [(const_int 0)]
4545 {
4546   rtx dest;
4547   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4548   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4549   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4550   DONE;
4551 })
4552
4553 (define_expand "floatdisf2"
4554   [(set (match_operand:SF 0 "register_operand" "")
4555         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4556   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4557   "")
4558
4559 (define_insn "*floatdisf2_i387_only"
4560   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4561         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4562   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4563   "@
4564    fild%z1\t%1
4565    #"
4566   [(set_attr "type" "fmov,multi")
4567    (set_attr "mode" "SF")
4568    (set_attr "fp_int_src" "true")])
4569
4570 (define_insn "*floatdisf2_i387"
4571   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4572         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4573   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4574   "@
4575    fild%z1\t%1
4576    #
4577    cvtsi2ss{q}\t{%1, %0|%0, %1}
4578    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4579   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4580    (set_attr "mode" "SF")
4581    (set_attr "athlon_decode" "*,*,vector,double")
4582    (set_attr "fp_int_src" "true")])
4583
4584 (define_insn "*floatdisf2_sse"
4585   [(set (match_operand:SF 0 "register_operand" "=x,x")
4586         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4587   "TARGET_64BIT && TARGET_SSE"
4588   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4589   [(set_attr "type" "sseicvt")
4590    (set_attr "mode" "SF")
4591    (set_attr "athlon_decode" "vector,double")
4592    (set_attr "fp_int_src" "true")])
4593
4594 ; Avoid possible reformatting penalty on the destination by first
4595 ; zeroing it out
4596 (define_split
4597   [(set (match_operand:SF 0 "register_operand" "")
4598         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4599   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4600    && SSE_REG_P (operands[0])"
4601   [(const_int 0)]
4602 {
4603   rtx dest;
4604   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4605   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4606   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4607   DONE;
4608 })
4609
4610 (define_expand "floathidf2"
4611   [(set (match_operand:DF 0 "register_operand" "")
4612         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4613   "TARGET_SSE2 || TARGET_80387"
4614 {
4615   if (TARGET_SSE && TARGET_SSE_MATH)
4616     {
4617       emit_insn (gen_floatsidf2 (operands[0],
4618                                  convert_to_mode (SImode, operands[1], 0)));
4619       DONE;
4620     }
4621 })
4622
4623 (define_insn "*floathidf2_1"
4624   [(set (match_operand:DF 0 "register_operand" "=f,f")
4625         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4626   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4627   "@
4628    fild%z1\t%1
4629    #"
4630   [(set_attr "type" "fmov,multi")
4631    (set_attr "mode" "DF")
4632    (set_attr "fp_int_src" "true")])
4633
4634 (define_expand "floatsidf2"
4635   [(set (match_operand:DF 0 "register_operand" "")
4636         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4637   "TARGET_80387 || TARGET_SSE2"
4638   "")
4639
4640 (define_insn "*floatsidf2_i387"
4641   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4642         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4643   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4644   "@
4645    fild%z1\t%1
4646    #
4647    cvtsi2sd\t{%1, %0|%0, %1}
4648    cvtsi2sd\t{%1, %0|%0, %1}"
4649   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4650    (set_attr "mode" "DF")
4651    (set_attr "athlon_decode" "*,*,double,direct")
4652    (set_attr "fp_int_src" "true")])
4653
4654 (define_insn "*floatsidf2_sse"
4655   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4656         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4657   "TARGET_SSE2"
4658   "cvtsi2sd\t{%1, %0|%0, %1}"
4659   [(set_attr "type" "sseicvt")
4660    (set_attr "mode" "DF")
4661    (set_attr "athlon_decode" "double,direct")
4662    (set_attr "fp_int_src" "true")])
4663
4664 (define_expand "floatdidf2"
4665   [(set (match_operand:DF 0 "register_operand" "")
4666         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4667   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4668   "")
4669
4670 (define_insn "*floatdidf2_i387_only"
4671   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4672         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4673   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4674   "@
4675    fild%z1\t%1
4676    #"
4677   [(set_attr "type" "fmov,multi")
4678    (set_attr "mode" "DF")
4679    (set_attr "fp_int_src" "true")])
4680
4681 (define_insn "*floatdidf2_i387"
4682   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4683         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4684   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4685   "@
4686    fild%z1\t%1
4687    #
4688    cvtsi2sd{q}\t{%1, %0|%0, %1}
4689    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4690   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4691    (set_attr "mode" "DF")
4692    (set_attr "athlon_decode" "*,*,double,direct")
4693    (set_attr "fp_int_src" "true")])
4694
4695 (define_insn "*floatdidf2_sse"
4696   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4697         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4698   "TARGET_SSE2"
4699   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4700   [(set_attr "type" "sseicvt")
4701    (set_attr "mode" "DF")
4702    (set_attr "athlon_decode" "double,direct")
4703    (set_attr "fp_int_src" "true")])
4704
4705 (define_insn "floathixf2"
4706   [(set (match_operand:XF 0 "register_operand" "=f,f")
4707         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4708   "TARGET_80387"
4709   "@
4710    fild%z1\t%1
4711    #"
4712   [(set_attr "type" "fmov,multi")
4713    (set_attr "mode" "XF")
4714    (set_attr "fp_int_src" "true")])
4715
4716 (define_insn "floatsixf2"
4717   [(set (match_operand:XF 0 "register_operand" "=f,f")
4718         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4719   "TARGET_80387"
4720   "@
4721    fild%z1\t%1
4722    #"
4723   [(set_attr "type" "fmov,multi")
4724    (set_attr "mode" "XF")
4725    (set_attr "fp_int_src" "true")])
4726
4727 (define_insn "floatdixf2"
4728   [(set (match_operand:XF 0 "register_operand" "=f,f")
4729         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4730   "TARGET_80387"
4731   "@
4732    fild%z1\t%1
4733    #"
4734   [(set_attr "type" "fmov,multi")
4735    (set_attr "mode" "XF")
4736    (set_attr "fp_int_src" "true")])
4737
4738 ;; %%% Kill these when reload knows how to do it.
4739 (define_split
4740   [(set (match_operand 0 "fp_register_operand" "")
4741         (float (match_operand 1 "register_operand" "")))]
4742   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4743   [(const_int 0)]
4744 {
4745   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4746   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4747   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4748   ix86_free_from_memory (GET_MODE (operands[1]));
4749   DONE;
4750 })
4751
4752 (define_expand "floatunssisf2"
4753   [(use (match_operand:SF 0 "register_operand" ""))
4754    (use (match_operand:SI 1 "register_operand" ""))]
4755   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4756   "x86_emit_floatuns (operands); DONE;")
4757
4758 (define_expand "floatunsdisf2"
4759   [(use (match_operand:SF 0 "register_operand" ""))
4760    (use (match_operand:DI 1 "register_operand" ""))]
4761   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4762   "x86_emit_floatuns (operands); DONE;")
4763
4764 (define_expand "floatunsdidf2"
4765   [(use (match_operand:DF 0 "register_operand" ""))
4766    (use (match_operand:DI 1 "register_operand" ""))]
4767   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4768   "x86_emit_floatuns (operands); DONE;")
4769 \f
4770 ;; SSE extract/set expanders
4771
4772 (define_expand "vec_setv2df"
4773   [(match_operand:V2DF 0 "register_operand" "")
4774    (match_operand:DF 1 "register_operand" "")
4775    (match_operand 2 "const_int_operand" "")]
4776   "TARGET_SSE2"
4777 {
4778   switch (INTVAL (operands[2]))
4779     {
4780     case 0:
4781       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4782                                  simplify_gen_subreg (V2DFmode, operands[1],
4783                                                       DFmode, 0)));
4784       break;
4785     case 1:
4786       {
4787         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4788
4789         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4790       }
4791       break;
4792     default:
4793       abort ();
4794     }
4795   DONE;
4796 })
4797
4798 (define_expand "vec_extractv2df"
4799   [(match_operand:DF 0 "register_operand" "")
4800    (match_operand:V2DF 1 "register_operand" "")
4801    (match_operand 2 "const_int_operand" "")]
4802   "TARGET_SSE2"
4803 {
4804   switch (INTVAL (operands[2]))
4805     {
4806     case 0:
4807       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4808       break;
4809     case 1:
4810       {
4811         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4812
4813         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4814       }
4815       break;
4816     default:
4817       abort ();
4818     }
4819   DONE;
4820 })
4821
4822 (define_expand "vec_initv2df"
4823   [(match_operand:V2DF 0 "register_operand" "")
4824    (match_operand 1 "" "")]
4825   "TARGET_SSE2"
4826 {
4827   ix86_expand_vector_init (operands[0], operands[1]);
4828   DONE;
4829 })
4830
4831 (define_expand "vec_setv4sf"
4832   [(match_operand:V4SF 0 "register_operand" "")
4833    (match_operand:SF 1 "register_operand" "")
4834    (match_operand 2 "const_int_operand" "")]
4835   "TARGET_SSE"
4836 {
4837   switch (INTVAL (operands[2]))
4838     {
4839     case 0:
4840       emit_insn (gen_sse_movss (operands[0], operands[0],
4841                                 simplify_gen_subreg (V4SFmode, operands[1],
4842                                                      SFmode, 0)));
4843       break;
4844     case 1:
4845       {
4846         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4847         rtx tmp = gen_reg_rtx (V4SFmode);
4848  
4849         emit_move_insn (tmp, operands[0]);
4850         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4851         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4852         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4853                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4854       }
4855       break;
4856     case 2:
4857       {
4858         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4859         rtx tmp = gen_reg_rtx (V4SFmode);
4860
4861         emit_move_insn (tmp, operands[0]);
4862         emit_insn (gen_sse_movss (tmp, tmp, op1));
4863         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4864                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4865       }
4866       break;
4867     case 3:
4868       {
4869         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4870         rtx tmp = gen_reg_rtx (V4SFmode);
4871
4872         emit_move_insn (tmp, operands[0]);
4873         emit_insn (gen_sse_movss (tmp, tmp, op1));
4874         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4875                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4876       }
4877       break;
4878     default:
4879       abort ();
4880     }
4881   DONE;
4882 })
4883
4884 (define_expand "vec_extractv4sf"
4885   [(match_operand:SF 0 "register_operand" "")
4886    (match_operand:V4SF 1 "register_operand" "")
4887    (match_operand 2 "const_int_operand" "")]
4888   "TARGET_SSE"
4889 {
4890   switch (INTVAL (operands[2]))
4891     {
4892     case 0:
4893       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4894       break;
4895     case 1:
4896       {
4897         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4898         rtx tmp = gen_reg_rtx (V4SFmode);
4899  
4900         emit_move_insn (tmp, operands[1]);
4901         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4902                                    const1_rtx));
4903       }
4904       break;
4905     case 2:
4906       {
4907         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4908         rtx tmp = gen_reg_rtx (V4SFmode);
4909  
4910         emit_move_insn (tmp, operands[1]);
4911         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4912       }
4913       break;
4914     case 3:
4915       {
4916         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4917         rtx tmp = gen_reg_rtx (V4SFmode);
4918  
4919         emit_move_insn (tmp, operands[1]);
4920         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4921                                    GEN_INT (3)));
4922       }
4923       break;
4924     default:
4925       abort ();
4926     }
4927   DONE;
4928 })
4929
4930 (define_expand "vec_initv4sf"
4931   [(match_operand:V4SF 0 "register_operand" "")
4932    (match_operand 1 "" "")]
4933   "TARGET_SSE"
4934 {
4935   ix86_expand_vector_init (operands[0], operands[1]);
4936   DONE;
4937 })
4938 \f
4939 ;; Add instructions
4940
4941 ;; %%% splits for addsidi3
4942 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4943 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4944 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4945
4946 (define_expand "adddi3"
4947   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4948         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4949                  (match_operand:DI 2 "x86_64_general_operand" "")))
4950    (clobber (reg:CC FLAGS_REG))]
4951   ""
4952   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4953
4954 (define_insn "*adddi3_1"
4955   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4956         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4957                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4958    (clobber (reg:CC FLAGS_REG))]
4959   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4960   "#")
4961
4962 (define_split
4963   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4964         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4965                  (match_operand:DI 2 "general_operand" "")))
4966    (clobber (reg:CC FLAGS_REG))]
4967   "!TARGET_64BIT && reload_completed"
4968   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4969                                           UNSPEC_ADD_CARRY))
4970               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4971    (parallel [(set (match_dup 3)
4972                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4973                                      (match_dup 4))
4974                             (match_dup 5)))
4975               (clobber (reg:CC FLAGS_REG))])]
4976   "split_di (operands+0, 1, operands+0, operands+3);
4977    split_di (operands+1, 1, operands+1, operands+4);
4978    split_di (operands+2, 1, operands+2, operands+5);")
4979
4980 (define_insn "adddi3_carry_rex64"
4981   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4982           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4983                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4984                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4985    (clobber (reg:CC FLAGS_REG))]
4986   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4987   "adc{q}\t{%2, %0|%0, %2}"
4988   [(set_attr "type" "alu")
4989    (set_attr "pent_pair" "pu")
4990    (set_attr "mode" "DI")])
4991
4992 (define_insn "*adddi3_cc_rex64"
4993   [(set (reg:CC FLAGS_REG)
4994         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4995                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4996                    UNSPEC_ADD_CARRY))
4997    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4998         (plus:DI (match_dup 1) (match_dup 2)))]
4999   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5000   "add{q}\t{%2, %0|%0, %2}"
5001   [(set_attr "type" "alu")
5002    (set_attr "mode" "DI")])
5003
5004 (define_insn "addqi3_carry"
5005   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5006           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5007                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5008                    (match_operand:QI 2 "general_operand" "qi,qm")))
5009    (clobber (reg:CC FLAGS_REG))]
5010   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5011   "adc{b}\t{%2, %0|%0, %2}"
5012   [(set_attr "type" "alu")
5013    (set_attr "pent_pair" "pu")
5014    (set_attr "mode" "QI")])
5015
5016 (define_insn "addhi3_carry"
5017   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5018           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5019                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5020                    (match_operand:HI 2 "general_operand" "ri,rm")))
5021    (clobber (reg:CC FLAGS_REG))]
5022   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5023   "adc{w}\t{%2, %0|%0, %2}"
5024   [(set_attr "type" "alu")
5025    (set_attr "pent_pair" "pu")
5026    (set_attr "mode" "HI")])
5027
5028 (define_insn "addsi3_carry"
5029   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5030           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5031                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5032                    (match_operand:SI 2 "general_operand" "ri,rm")))
5033    (clobber (reg:CC FLAGS_REG))]
5034   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5035   "adc{l}\t{%2, %0|%0, %2}"
5036   [(set_attr "type" "alu")
5037    (set_attr "pent_pair" "pu")
5038    (set_attr "mode" "SI")])
5039
5040 (define_insn "*addsi3_carry_zext"
5041   [(set (match_operand:DI 0 "register_operand" "=r")
5042           (zero_extend:DI 
5043             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5044                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5045                      (match_operand:SI 2 "general_operand" "rim"))))
5046    (clobber (reg:CC FLAGS_REG))]
5047   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5048   "adc{l}\t{%2, %k0|%k0, %2}"
5049   [(set_attr "type" "alu")
5050    (set_attr "pent_pair" "pu")
5051    (set_attr "mode" "SI")])
5052
5053 (define_insn "*addsi3_cc"
5054   [(set (reg:CC FLAGS_REG)
5055         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5056                     (match_operand:SI 2 "general_operand" "ri,rm")]
5057                    UNSPEC_ADD_CARRY))
5058    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5059         (plus:SI (match_dup 1) (match_dup 2)))]
5060   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5061   "add{l}\t{%2, %0|%0, %2}"
5062   [(set_attr "type" "alu")
5063    (set_attr "mode" "SI")])
5064
5065 (define_insn "addqi3_cc"
5066   [(set (reg:CC FLAGS_REG)
5067         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5068                     (match_operand:QI 2 "general_operand" "qi,qm")]
5069                    UNSPEC_ADD_CARRY))
5070    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5071         (plus:QI (match_dup 1) (match_dup 2)))]
5072   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5073   "add{b}\t{%2, %0|%0, %2}"
5074   [(set_attr "type" "alu")
5075    (set_attr "mode" "QI")])
5076
5077 (define_expand "addsi3"
5078   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5079                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5080                             (match_operand:SI 2 "general_operand" "")))
5081               (clobber (reg:CC FLAGS_REG))])]
5082   ""
5083   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5084
5085 (define_insn "*lea_1"
5086   [(set (match_operand:SI 0 "register_operand" "=r")
5087         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5088   "!TARGET_64BIT"
5089   "lea{l}\t{%a1, %0|%0, %a1}"
5090   [(set_attr "type" "lea")
5091    (set_attr "mode" "SI")])
5092
5093 (define_insn "*lea_1_rex64"
5094   [(set (match_operand:SI 0 "register_operand" "=r")
5095         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5096   "TARGET_64BIT"
5097   "lea{l}\t{%a1, %0|%0, %a1}"
5098   [(set_attr "type" "lea")
5099    (set_attr "mode" "SI")])
5100
5101 (define_insn "*lea_1_zext"
5102   [(set (match_operand:DI 0 "register_operand" "=r")
5103         (zero_extend:DI
5104          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5105   "TARGET_64BIT"
5106   "lea{l}\t{%a1, %k0|%k0, %a1}"
5107   [(set_attr "type" "lea")
5108    (set_attr "mode" "SI")])
5109
5110 (define_insn "*lea_2_rex64"
5111   [(set (match_operand:DI 0 "register_operand" "=r")
5112         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5113   "TARGET_64BIT"
5114   "lea{q}\t{%a1, %0|%0, %a1}"
5115   [(set_attr "type" "lea")
5116    (set_attr "mode" "DI")])
5117
5118 ;; The lea patterns for non-Pmodes needs to be matched by several
5119 ;; insns converted to real lea by splitters.
5120
5121 (define_insn_and_split "*lea_general_1"
5122   [(set (match_operand 0 "register_operand" "=r")
5123         (plus (plus (match_operand 1 "index_register_operand" "r")
5124                     (match_operand 2 "register_operand" "r"))
5125               (match_operand 3 "immediate_operand" "i")))]
5126   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5127     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5128    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5129    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5130    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5131    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5132        || GET_MODE (operands[3]) == VOIDmode)"
5133   "#"
5134   "&& reload_completed"
5135   [(const_int 0)]
5136 {
5137   rtx pat;
5138   operands[0] = gen_lowpart (SImode, operands[0]);
5139   operands[1] = gen_lowpart (Pmode, operands[1]);
5140   operands[2] = gen_lowpart (Pmode, operands[2]);
5141   operands[3] = gen_lowpart (Pmode, operands[3]);
5142   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5143                       operands[3]);
5144   if (Pmode != SImode)
5145     pat = gen_rtx_SUBREG (SImode, pat, 0);
5146   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5147   DONE;
5148 }
5149   [(set_attr "type" "lea")
5150    (set_attr "mode" "SI")])
5151
5152 (define_insn_and_split "*lea_general_1_zext"
5153   [(set (match_operand:DI 0 "register_operand" "=r")
5154         (zero_extend:DI
5155           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5156                             (match_operand:SI 2 "register_operand" "r"))
5157                    (match_operand:SI 3 "immediate_operand" "i"))))]
5158   "TARGET_64BIT"
5159   "#"
5160   "&& reload_completed"
5161   [(set (match_dup 0)
5162         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5163                                                      (match_dup 2))
5164                                             (match_dup 3)) 0)))]
5165 {
5166   operands[1] = gen_lowpart (Pmode, operands[1]);
5167   operands[2] = gen_lowpart (Pmode, operands[2]);
5168   operands[3] = gen_lowpart (Pmode, operands[3]);
5169 }
5170   [(set_attr "type" "lea")
5171    (set_attr "mode" "SI")])
5172
5173 (define_insn_and_split "*lea_general_2"
5174   [(set (match_operand 0 "register_operand" "=r")
5175         (plus (mult (match_operand 1 "index_register_operand" "r")
5176                     (match_operand 2 "const248_operand" "i"))
5177               (match_operand 3 "nonmemory_operand" "ri")))]
5178   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5179     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5180    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5181    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5182    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5183        || GET_MODE (operands[3]) == VOIDmode)"
5184   "#"
5185   "&& reload_completed"
5186   [(const_int 0)]
5187 {
5188   rtx pat;
5189   operands[0] = gen_lowpart (SImode, operands[0]);
5190   operands[1] = gen_lowpart (Pmode, operands[1]);
5191   operands[3] = gen_lowpart (Pmode, operands[3]);
5192   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5193                       operands[3]);
5194   if (Pmode != SImode)
5195     pat = gen_rtx_SUBREG (SImode, pat, 0);
5196   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5197   DONE;
5198 }
5199   [(set_attr "type" "lea")
5200    (set_attr "mode" "SI")])
5201
5202 (define_insn_and_split "*lea_general_2_zext"
5203   [(set (match_operand:DI 0 "register_operand" "=r")
5204         (zero_extend:DI
5205           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5206                             (match_operand:SI 2 "const248_operand" "n"))
5207                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5208   "TARGET_64BIT"
5209   "#"
5210   "&& reload_completed"
5211   [(set (match_dup 0)
5212         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5213                                                      (match_dup 2))
5214                                             (match_dup 3)) 0)))]
5215 {
5216   operands[1] = gen_lowpart (Pmode, operands[1]);
5217   operands[3] = gen_lowpart (Pmode, operands[3]);
5218 }
5219   [(set_attr "type" "lea")
5220    (set_attr "mode" "SI")])
5221
5222 (define_insn_and_split "*lea_general_3"
5223   [(set (match_operand 0 "register_operand" "=r")
5224         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5225                           (match_operand 2 "const248_operand" "i"))
5226                     (match_operand 3 "register_operand" "r"))
5227               (match_operand 4 "immediate_operand" "i")))]
5228   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5229     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5230    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5231    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5232    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5233   "#"
5234   "&& reload_completed"
5235   [(const_int 0)]
5236 {
5237   rtx pat;
5238   operands[0] = gen_lowpart (SImode, operands[0]);
5239   operands[1] = gen_lowpart (Pmode, operands[1]);
5240   operands[3] = gen_lowpart (Pmode, operands[3]);
5241   operands[4] = gen_lowpart (Pmode, operands[4]);
5242   pat = gen_rtx_PLUS (Pmode,
5243                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5244                                                          operands[2]),
5245                                     operands[3]),
5246                       operands[4]);
5247   if (Pmode != SImode)
5248     pat = gen_rtx_SUBREG (SImode, pat, 0);
5249   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5250   DONE;
5251 }
5252   [(set_attr "type" "lea")
5253    (set_attr "mode" "SI")])
5254
5255 (define_insn_and_split "*lea_general_3_zext"
5256   [(set (match_operand:DI 0 "register_operand" "=r")
5257         (zero_extend:DI
5258           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5259                                      (match_operand:SI 2 "const248_operand" "n"))
5260                             (match_operand:SI 3 "register_operand" "r"))
5261                    (match_operand:SI 4 "immediate_operand" "i"))))]
5262   "TARGET_64BIT"
5263   "#"
5264   "&& reload_completed"
5265   [(set (match_dup 0)
5266         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5267                                                               (match_dup 2))
5268                                                      (match_dup 3))
5269                                             (match_dup 4)) 0)))]
5270 {
5271   operands[1] = gen_lowpart (Pmode, operands[1]);
5272   operands[3] = gen_lowpart (Pmode, operands[3]);
5273   operands[4] = gen_lowpart (Pmode, operands[4]);
5274 }
5275   [(set_attr "type" "lea")
5276    (set_attr "mode" "SI")])
5277
5278 (define_insn "*adddi_1_rex64"
5279   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5280         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5281                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5282    (clobber (reg:CC FLAGS_REG))]
5283   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5284 {
5285   switch (get_attr_type (insn))
5286     {
5287     case TYPE_LEA:
5288       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5289       return "lea{q}\t{%a2, %0|%0, %a2}";
5290
5291     case TYPE_INCDEC:
5292       if (! rtx_equal_p (operands[0], operands[1]))
5293         abort ();
5294       if (operands[2] == const1_rtx)
5295         return "inc{q}\t%0";
5296       else if (operands[2] == constm1_rtx)
5297         return "dec{q}\t%0";
5298       else
5299         abort ();
5300
5301     default:
5302       if (! rtx_equal_p (operands[0], operands[1]))
5303         abort ();
5304
5305       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5306          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5307       if (GET_CODE (operands[2]) == CONST_INT
5308           /* Avoid overflows.  */
5309           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5310           && (INTVAL (operands[2]) == 128
5311               || (INTVAL (operands[2]) < 0
5312                   && INTVAL (operands[2]) != -128)))
5313         {
5314           operands[2] = GEN_INT (-INTVAL (operands[2]));
5315           return "sub{q}\t{%2, %0|%0, %2}";
5316         }
5317       return "add{q}\t{%2, %0|%0, %2}";
5318     }
5319 }
5320   [(set (attr "type")
5321      (cond [(eq_attr "alternative" "2")
5322               (const_string "lea")
5323             ; Current assemblers are broken and do not allow @GOTOFF in
5324             ; ought but a memory context.
5325             (match_operand:DI 2 "pic_symbolic_operand" "")
5326               (const_string "lea")
5327             (match_operand:DI 2 "incdec_operand" "")
5328               (const_string "incdec")
5329            ]
5330            (const_string "alu")))
5331    (set_attr "mode" "DI")])
5332
5333 ;; Convert lea to the lea pattern to avoid flags dependency.
5334 (define_split
5335   [(set (match_operand:DI 0 "register_operand" "")
5336         (plus:DI (match_operand:DI 1 "register_operand" "")
5337                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5338    (clobber (reg:CC FLAGS_REG))]
5339   "TARGET_64BIT && reload_completed
5340    && true_regnum (operands[0]) != true_regnum (operands[1])"
5341   [(set (match_dup 0)
5342         (plus:DI (match_dup 1)
5343                  (match_dup 2)))]
5344   "")
5345
5346 (define_insn "*adddi_2_rex64"
5347   [(set (reg 17)
5348         (compare
5349           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5350                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5351           (const_int 0)))                       
5352    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5353         (plus:DI (match_dup 1) (match_dup 2)))]
5354   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5355    && ix86_binary_operator_ok (PLUS, DImode, operands)
5356    /* Current assemblers are broken and do not allow @GOTOFF in
5357       ought but a memory context.  */
5358    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5359 {
5360   switch (get_attr_type (insn))
5361     {
5362     case TYPE_INCDEC:
5363       if (! rtx_equal_p (operands[0], operands[1]))
5364         abort ();
5365       if (operands[2] == const1_rtx)
5366         return "inc{q}\t%0";
5367       else if (operands[2] == constm1_rtx)
5368         return "dec{q}\t%0";
5369       else
5370         abort ();
5371
5372     default:
5373       if (! rtx_equal_p (operands[0], operands[1]))
5374         abort ();
5375       /* ???? We ought to handle there the 32bit case too
5376          - do we need new constraint?  */
5377       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5378          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5379       if (GET_CODE (operands[2]) == CONST_INT
5380           /* Avoid overflows.  */
5381           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5382           && (INTVAL (operands[2]) == 128
5383               || (INTVAL (operands[2]) < 0
5384                   && INTVAL (operands[2]) != -128)))
5385         {
5386           operands[2] = GEN_INT (-INTVAL (operands[2]));
5387           return "sub{q}\t{%2, %0|%0, %2}";
5388         }
5389       return "add{q}\t{%2, %0|%0, %2}";
5390     }
5391 }
5392   [(set (attr "type")
5393      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5394         (const_string "incdec")
5395         (const_string "alu")))
5396    (set_attr "mode" "DI")])
5397
5398 (define_insn "*adddi_3_rex64"
5399   [(set (reg 17)
5400         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5401                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5402    (clobber (match_scratch:DI 0 "=r"))]
5403   "TARGET_64BIT
5404    && ix86_match_ccmode (insn, CCZmode)
5405    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5406    /* Current assemblers are broken and do not allow @GOTOFF in
5407       ought but a memory context.  */
5408    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5409 {
5410   switch (get_attr_type (insn))
5411     {
5412     case TYPE_INCDEC:
5413       if (! rtx_equal_p (operands[0], operands[1]))
5414         abort ();
5415       if (operands[2] == const1_rtx)
5416         return "inc{q}\t%0";
5417       else if (operands[2] == constm1_rtx)
5418         return "dec{q}\t%0";
5419       else
5420         abort ();
5421
5422     default:
5423       if (! rtx_equal_p (operands[0], operands[1]))
5424         abort ();
5425       /* ???? We ought to handle there the 32bit case too
5426          - do we need new constraint?  */
5427       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5428          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5429       if (GET_CODE (operands[2]) == CONST_INT
5430           /* Avoid overflows.  */
5431           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5432           && (INTVAL (operands[2]) == 128
5433               || (INTVAL (operands[2]) < 0
5434                   && INTVAL (operands[2]) != -128)))
5435         {
5436           operands[2] = GEN_INT (-INTVAL (operands[2]));
5437           return "sub{q}\t{%2, %0|%0, %2}";
5438         }
5439       return "add{q}\t{%2, %0|%0, %2}";
5440     }
5441 }
5442   [(set (attr "type")
5443      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5444         (const_string "incdec")
5445         (const_string "alu")))
5446    (set_attr "mode" "DI")])
5447
5448 ; For comparisons against 1, -1 and 128, we may generate better code
5449 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5450 ; is matched then.  We can't accept general immediate, because for
5451 ; case of overflows,  the result is messed up.
5452 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5453 ; when negated.
5454 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5455 ; only for comparisons not depending on it.
5456 (define_insn "*adddi_4_rex64"
5457   [(set (reg 17)
5458         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5459                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5460    (clobber (match_scratch:DI 0 "=rm"))]
5461   "TARGET_64BIT
5462    &&  ix86_match_ccmode (insn, CCGCmode)"
5463 {
5464   switch (get_attr_type (insn))
5465     {
5466     case TYPE_INCDEC:
5467       if (operands[2] == constm1_rtx)
5468         return "inc{q}\t%0";
5469       else if (operands[2] == const1_rtx)
5470         return "dec{q}\t%0";
5471       else
5472         abort();
5473
5474     default:
5475       if (! rtx_equal_p (operands[0], operands[1]))
5476         abort ();
5477       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5478          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5479       if ((INTVAL (operands[2]) == -128
5480            || (INTVAL (operands[2]) > 0
5481                && INTVAL (operands[2]) != 128))
5482           /* Avoid overflows.  */
5483           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5484         return "sub{q}\t{%2, %0|%0, %2}";
5485       operands[2] = GEN_INT (-INTVAL (operands[2]));
5486       return "add{q}\t{%2, %0|%0, %2}";
5487     }
5488 }
5489   [(set (attr "type")
5490      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5491         (const_string "incdec")
5492         (const_string "alu")))
5493    (set_attr "mode" "DI")])
5494
5495 (define_insn "*adddi_5_rex64"
5496   [(set (reg 17)
5497         (compare
5498           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5499                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5500           (const_int 0)))                       
5501    (clobber (match_scratch:DI 0 "=r"))]
5502   "TARGET_64BIT
5503    && ix86_match_ccmode (insn, CCGOCmode)
5504    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5505    /* Current assemblers are broken and do not allow @GOTOFF in
5506       ought but a memory context.  */
5507    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5508 {
5509   switch (get_attr_type (insn))
5510     {
5511     case TYPE_INCDEC:
5512       if (! rtx_equal_p (operands[0], operands[1]))
5513         abort ();
5514       if (operands[2] == const1_rtx)
5515         return "inc{q}\t%0";
5516       else if (operands[2] == constm1_rtx)
5517         return "dec{q}\t%0";
5518       else
5519         abort();
5520
5521     default:
5522       if (! rtx_equal_p (operands[0], operands[1]))
5523         abort ();
5524       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5525          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5526       if (GET_CODE (operands[2]) == CONST_INT
5527           /* Avoid overflows.  */
5528           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5529           && (INTVAL (operands[2]) == 128
5530               || (INTVAL (operands[2]) < 0
5531                   && INTVAL (operands[2]) != -128)))
5532         {
5533           operands[2] = GEN_INT (-INTVAL (operands[2]));
5534           return "sub{q}\t{%2, %0|%0, %2}";
5535         }
5536       return "add{q}\t{%2, %0|%0, %2}";
5537     }
5538 }
5539   [(set (attr "type")
5540      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5541         (const_string "incdec")
5542         (const_string "alu")))
5543    (set_attr "mode" "DI")])
5544
5545
5546 (define_insn "*addsi_1"
5547   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5548         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5549                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5550    (clobber (reg:CC FLAGS_REG))]
5551   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5552 {
5553   switch (get_attr_type (insn))
5554     {
5555     case TYPE_LEA:
5556       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5557       return "lea{l}\t{%a2, %0|%0, %a2}";
5558
5559     case TYPE_INCDEC:
5560       if (! rtx_equal_p (operands[0], operands[1]))
5561         abort ();
5562       if (operands[2] == const1_rtx)
5563         return "inc{l}\t%0";
5564       else if (operands[2] == constm1_rtx)
5565         return "dec{l}\t%0";
5566       else
5567         abort();
5568
5569     default:
5570       if (! rtx_equal_p (operands[0], operands[1]))
5571         abort ();
5572
5573       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5574          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5575       if (GET_CODE (operands[2]) == CONST_INT
5576           && (INTVAL (operands[2]) == 128
5577               || (INTVAL (operands[2]) < 0
5578                   && INTVAL (operands[2]) != -128)))
5579         {
5580           operands[2] = GEN_INT (-INTVAL (operands[2]));
5581           return "sub{l}\t{%2, %0|%0, %2}";
5582         }
5583       return "add{l}\t{%2, %0|%0, %2}";
5584     }
5585 }
5586   [(set (attr "type")
5587      (cond [(eq_attr "alternative" "2")
5588               (const_string "lea")
5589             ; Current assemblers are broken and do not allow @GOTOFF in
5590             ; ought but a memory context.
5591             (match_operand:SI 2 "pic_symbolic_operand" "")
5592               (const_string "lea")
5593             (match_operand:SI 2 "incdec_operand" "")
5594               (const_string "incdec")
5595            ]
5596            (const_string "alu")))
5597    (set_attr "mode" "SI")])
5598
5599 ;; Convert lea to the lea pattern to avoid flags dependency.
5600 (define_split
5601   [(set (match_operand 0 "register_operand" "")
5602         (plus (match_operand 1 "register_operand" "")
5603               (match_operand 2 "nonmemory_operand" "")))
5604    (clobber (reg:CC FLAGS_REG))]
5605   "reload_completed
5606    && true_regnum (operands[0]) != true_regnum (operands[1])"
5607   [(const_int 0)]
5608 {
5609   rtx pat;
5610   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5611      may confuse gen_lowpart.  */
5612   if (GET_MODE (operands[0]) != Pmode)
5613     {
5614       operands[1] = gen_lowpart (Pmode, operands[1]);
5615       operands[2] = gen_lowpart (Pmode, operands[2]);
5616     }
5617   operands[0] = gen_lowpart (SImode, operands[0]);
5618   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5619   if (Pmode != SImode)
5620     pat = gen_rtx_SUBREG (SImode, pat, 0);
5621   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5622   DONE;
5623 })
5624
5625 ;; It may seem that nonimmediate operand is proper one for operand 1.
5626 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5627 ;; we take care in ix86_binary_operator_ok to not allow two memory
5628 ;; operands so proper swapping will be done in reload.  This allow
5629 ;; patterns constructed from addsi_1 to match.
5630 (define_insn "addsi_1_zext"
5631   [(set (match_operand:DI 0 "register_operand" "=r,r")
5632         (zero_extend:DI
5633           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5634                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5635    (clobber (reg:CC FLAGS_REG))]
5636   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5637 {
5638   switch (get_attr_type (insn))
5639     {
5640     case TYPE_LEA:
5641       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5642       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5643
5644     case TYPE_INCDEC:
5645       if (operands[2] == const1_rtx)
5646         return "inc{l}\t%k0";
5647       else if (operands[2] == constm1_rtx)
5648         return "dec{l}\t%k0";
5649       else
5650         abort();
5651
5652     default:
5653       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5654          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5655       if (GET_CODE (operands[2]) == CONST_INT
5656           && (INTVAL (operands[2]) == 128
5657               || (INTVAL (operands[2]) < 0
5658                   && INTVAL (operands[2]) != -128)))
5659         {
5660           operands[2] = GEN_INT (-INTVAL (operands[2]));
5661           return "sub{l}\t{%2, %k0|%k0, %2}";
5662         }
5663       return "add{l}\t{%2, %k0|%k0, %2}";
5664     }
5665 }
5666   [(set (attr "type")
5667      (cond [(eq_attr "alternative" "1")
5668               (const_string "lea")
5669             ; Current assemblers are broken and do not allow @GOTOFF in
5670             ; ought but a memory context.
5671             (match_operand:SI 2 "pic_symbolic_operand" "")
5672               (const_string "lea")
5673             (match_operand:SI 2 "incdec_operand" "")
5674               (const_string "incdec")
5675            ]
5676            (const_string "alu")))
5677    (set_attr "mode" "SI")])
5678
5679 ;; Convert lea to the lea pattern to avoid flags dependency.
5680 (define_split
5681   [(set (match_operand:DI 0 "register_operand" "")
5682         (zero_extend:DI
5683           (plus:SI (match_operand:SI 1 "register_operand" "")
5684                    (match_operand:SI 2 "nonmemory_operand" ""))))
5685    (clobber (reg:CC FLAGS_REG))]
5686   "TARGET_64BIT && reload_completed
5687    && true_regnum (operands[0]) != true_regnum (operands[1])"
5688   [(set (match_dup 0)
5689         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5690 {
5691   operands[1] = gen_lowpart (Pmode, operands[1]);
5692   operands[2] = gen_lowpart (Pmode, operands[2]);
5693 })
5694
5695 (define_insn "*addsi_2"
5696   [(set (reg 17)
5697         (compare
5698           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5699                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5700           (const_int 0)))                       
5701    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5702         (plus:SI (match_dup 1) (match_dup 2)))]
5703   "ix86_match_ccmode (insn, CCGOCmode)
5704    && ix86_binary_operator_ok (PLUS, SImode, operands)
5705    /* Current assemblers are broken and do not allow @GOTOFF in
5706       ought but a memory context.  */
5707    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5708 {
5709   switch (get_attr_type (insn))
5710     {
5711     case TYPE_INCDEC:
5712       if (! rtx_equal_p (operands[0], operands[1]))
5713         abort ();
5714       if (operands[2] == const1_rtx)
5715         return "inc{l}\t%0";
5716       else if (operands[2] == constm1_rtx)
5717         return "dec{l}\t%0";
5718       else
5719         abort();
5720
5721     default:
5722       if (! rtx_equal_p (operands[0], operands[1]))
5723         abort ();
5724       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5725          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5726       if (GET_CODE (operands[2]) == CONST_INT
5727           && (INTVAL (operands[2]) == 128
5728               || (INTVAL (operands[2]) < 0
5729                   && INTVAL (operands[2]) != -128)))
5730         {
5731           operands[2] = GEN_INT (-INTVAL (operands[2]));
5732           return "sub{l}\t{%2, %0|%0, %2}";
5733         }
5734       return "add{l}\t{%2, %0|%0, %2}";
5735     }
5736 }
5737   [(set (attr "type")
5738      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5739         (const_string "incdec")
5740         (const_string "alu")))
5741    (set_attr "mode" "SI")])
5742
5743 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5744 (define_insn "*addsi_2_zext"
5745   [(set (reg 17)
5746         (compare
5747           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5748                    (match_operand:SI 2 "general_operand" "rmni"))
5749           (const_int 0)))                       
5750    (set (match_operand:DI 0 "register_operand" "=r")
5751         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5752   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5753    && ix86_binary_operator_ok (PLUS, SImode, operands)
5754    /* Current assemblers are broken and do not allow @GOTOFF in
5755       ought but a memory context.  */
5756    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5757 {
5758   switch (get_attr_type (insn))
5759     {
5760     case TYPE_INCDEC:
5761       if (operands[2] == const1_rtx)
5762         return "inc{l}\t%k0";
5763       else if (operands[2] == constm1_rtx)
5764         return "dec{l}\t%k0";
5765       else
5766         abort();
5767
5768     default:
5769       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5770          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5771       if (GET_CODE (operands[2]) == CONST_INT
5772           && (INTVAL (operands[2]) == 128
5773               || (INTVAL (operands[2]) < 0
5774                   && INTVAL (operands[2]) != -128)))
5775         {
5776           operands[2] = GEN_INT (-INTVAL (operands[2]));
5777           return "sub{l}\t{%2, %k0|%k0, %2}";
5778         }
5779       return "add{l}\t{%2, %k0|%k0, %2}";
5780     }
5781 }
5782   [(set (attr "type")
5783      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5784         (const_string "incdec")
5785         (const_string "alu")))
5786    (set_attr "mode" "SI")])
5787
5788 (define_insn "*addsi_3"
5789   [(set (reg 17)
5790         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5791                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5792    (clobber (match_scratch:SI 0 "=r"))]
5793   "ix86_match_ccmode (insn, CCZmode)
5794    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5795    /* Current assemblers are broken and do not allow @GOTOFF in
5796       ought but a memory context.  */
5797    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5798 {
5799   switch (get_attr_type (insn))
5800     {
5801     case TYPE_INCDEC:
5802       if (! rtx_equal_p (operands[0], operands[1]))
5803         abort ();
5804       if (operands[2] == const1_rtx)
5805         return "inc{l}\t%0";
5806       else if (operands[2] == constm1_rtx)
5807         return "dec{l}\t%0";
5808       else
5809         abort();
5810
5811     default:
5812       if (! rtx_equal_p (operands[0], operands[1]))
5813         abort ();
5814       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5815          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5816       if (GET_CODE (operands[2]) == CONST_INT
5817           && (INTVAL (operands[2]) == 128
5818               || (INTVAL (operands[2]) < 0
5819                   && INTVAL (operands[2]) != -128)))
5820         {
5821           operands[2] = GEN_INT (-INTVAL (operands[2]));
5822           return "sub{l}\t{%2, %0|%0, %2}";
5823         }
5824       return "add{l}\t{%2, %0|%0, %2}";
5825     }
5826 }
5827   [(set (attr "type")
5828      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5829         (const_string "incdec")
5830         (const_string "alu")))
5831    (set_attr "mode" "SI")])
5832
5833 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5834 (define_insn "*addsi_3_zext"
5835   [(set (reg 17)
5836         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5837                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5838    (set (match_operand:DI 0 "register_operand" "=r")
5839         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5840   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5841    && ix86_binary_operator_ok (PLUS, SImode, operands)
5842    /* Current assemblers are broken and do not allow @GOTOFF in
5843       ought but a memory context.  */
5844    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5845 {
5846   switch (get_attr_type (insn))
5847     {
5848     case TYPE_INCDEC:
5849       if (operands[2] == const1_rtx)
5850         return "inc{l}\t%k0";
5851       else if (operands[2] == constm1_rtx)
5852         return "dec{l}\t%k0";
5853       else
5854         abort();
5855
5856     default:
5857       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5858          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5859       if (GET_CODE (operands[2]) == CONST_INT
5860           && (INTVAL (operands[2]) == 128
5861               || (INTVAL (operands[2]) < 0
5862                   && INTVAL (operands[2]) != -128)))
5863         {
5864           operands[2] = GEN_INT (-INTVAL (operands[2]));
5865           return "sub{l}\t{%2, %k0|%k0, %2}";
5866         }
5867       return "add{l}\t{%2, %k0|%k0, %2}";
5868     }
5869 }
5870   [(set (attr "type")
5871      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5872         (const_string "incdec")
5873         (const_string "alu")))
5874    (set_attr "mode" "SI")])
5875
5876 ; For comparisons against 1, -1 and 128, we may generate better code
5877 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5878 ; is matched then.  We can't accept general immediate, because for
5879 ; case of overflows,  the result is messed up.
5880 ; This pattern also don't hold of 0x80000000, since the value overflows
5881 ; when negated.
5882 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5883 ; only for comparisons not depending on it.
5884 (define_insn "*addsi_4"
5885   [(set (reg 17)
5886         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5887                  (match_operand:SI 2 "const_int_operand" "n")))
5888    (clobber (match_scratch:SI 0 "=rm"))]
5889   "ix86_match_ccmode (insn, CCGCmode)
5890    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5891 {
5892   switch (get_attr_type (insn))
5893     {
5894     case TYPE_INCDEC:
5895       if (operands[2] == constm1_rtx)
5896         return "inc{l}\t%0";
5897       else if (operands[2] == const1_rtx)
5898         return "dec{l}\t%0";
5899       else
5900         abort();
5901
5902     default:
5903       if (! rtx_equal_p (operands[0], operands[1]))
5904         abort ();
5905       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5906          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5907       if ((INTVAL (operands[2]) == -128
5908            || (INTVAL (operands[2]) > 0
5909                && INTVAL (operands[2]) != 128)))
5910         return "sub{l}\t{%2, %0|%0, %2}";
5911       operands[2] = GEN_INT (-INTVAL (operands[2]));
5912       return "add{l}\t{%2, %0|%0, %2}";
5913     }
5914 }
5915   [(set (attr "type")
5916      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5917         (const_string "incdec")
5918         (const_string "alu")))
5919    (set_attr "mode" "SI")])
5920
5921 (define_insn "*addsi_5"
5922   [(set (reg 17)
5923         (compare
5924           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5925                    (match_operand:SI 2 "general_operand" "rmni"))
5926           (const_int 0)))                       
5927    (clobber (match_scratch:SI 0 "=r"))]
5928   "ix86_match_ccmode (insn, CCGOCmode)
5929    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5930    /* Current assemblers are broken and do not allow @GOTOFF in
5931       ought but a memory context.  */
5932    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5933 {
5934   switch (get_attr_type (insn))
5935     {
5936     case TYPE_INCDEC:
5937       if (! rtx_equal_p (operands[0], operands[1]))
5938         abort ();
5939       if (operands[2] == const1_rtx)
5940         return "inc{l}\t%0";
5941       else if (operands[2] == constm1_rtx)
5942         return "dec{l}\t%0";
5943       else
5944         abort();
5945
5946     default:
5947       if (! rtx_equal_p (operands[0], operands[1]))
5948         abort ();
5949       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5950          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5951       if (GET_CODE (operands[2]) == CONST_INT
5952           && (INTVAL (operands[2]) == 128
5953               || (INTVAL (operands[2]) < 0
5954                   && INTVAL (operands[2]) != -128)))
5955         {
5956           operands[2] = GEN_INT (-INTVAL (operands[2]));
5957           return "sub{l}\t{%2, %0|%0, %2}";
5958         }
5959       return "add{l}\t{%2, %0|%0, %2}";
5960     }
5961 }
5962   [(set (attr "type")
5963      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5964         (const_string "incdec")
5965         (const_string "alu")))
5966    (set_attr "mode" "SI")])
5967
5968 (define_expand "addhi3"
5969   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5970                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5971                             (match_operand:HI 2 "general_operand" "")))
5972               (clobber (reg:CC FLAGS_REG))])]
5973   "TARGET_HIMODE_MATH"
5974   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5975
5976 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5977 ;; type optimizations enabled by define-splits.  This is not important
5978 ;; for PII, and in fact harmful because of partial register stalls.
5979
5980 (define_insn "*addhi_1_lea"
5981   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5982         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5983                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5984    (clobber (reg:CC FLAGS_REG))]
5985   "!TARGET_PARTIAL_REG_STALL
5986    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5987 {
5988   switch (get_attr_type (insn))
5989     {
5990     case TYPE_LEA:
5991       return "#";
5992     case TYPE_INCDEC:
5993       if (operands[2] == const1_rtx)
5994         return "inc{w}\t%0";
5995       else if (operands[2] == constm1_rtx)
5996         return "dec{w}\t%0";
5997       abort();
5998
5999     default:
6000       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6001          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6002       if (GET_CODE (operands[2]) == CONST_INT
6003           && (INTVAL (operands[2]) == 128
6004               || (INTVAL (operands[2]) < 0
6005                   && INTVAL (operands[2]) != -128)))
6006         {
6007           operands[2] = GEN_INT (-INTVAL (operands[2]));
6008           return "sub{w}\t{%2, %0|%0, %2}";
6009         }
6010       return "add{w}\t{%2, %0|%0, %2}";
6011     }
6012 }
6013   [(set (attr "type")
6014      (if_then_else (eq_attr "alternative" "2")
6015         (const_string "lea")
6016         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6017            (const_string "incdec")
6018            (const_string "alu"))))
6019    (set_attr "mode" "HI,HI,SI")])
6020
6021 (define_insn "*addhi_1"
6022   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6023         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6024                  (match_operand:HI 2 "general_operand" "ri,rm")))
6025    (clobber (reg:CC FLAGS_REG))]
6026   "TARGET_PARTIAL_REG_STALL
6027    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6028 {
6029   switch (get_attr_type (insn))
6030     {
6031     case TYPE_INCDEC:
6032       if (operands[2] == const1_rtx)
6033         return "inc{w}\t%0";
6034       else if (operands[2] == constm1_rtx)
6035         return "dec{w}\t%0";
6036       abort();
6037
6038     default:
6039       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6040          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6041       if (GET_CODE (operands[2]) == CONST_INT
6042           && (INTVAL (operands[2]) == 128
6043               || (INTVAL (operands[2]) < 0
6044                   && INTVAL (operands[2]) != -128)))
6045         {
6046           operands[2] = GEN_INT (-INTVAL (operands[2]));
6047           return "sub{w}\t{%2, %0|%0, %2}";
6048         }
6049       return "add{w}\t{%2, %0|%0, %2}";
6050     }
6051 }
6052   [(set (attr "type")
6053      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6054         (const_string "incdec")
6055         (const_string "alu")))
6056    (set_attr "mode" "HI")])
6057
6058 (define_insn "*addhi_2"
6059   [(set (reg 17)
6060         (compare
6061           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6062                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6063           (const_int 0)))                       
6064    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6065         (plus:HI (match_dup 1) (match_dup 2)))]
6066   "ix86_match_ccmode (insn, CCGOCmode)
6067    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6068 {
6069   switch (get_attr_type (insn))
6070     {
6071     case TYPE_INCDEC:
6072       if (operands[2] == const1_rtx)
6073         return "inc{w}\t%0";
6074       else if (operands[2] == constm1_rtx)
6075         return "dec{w}\t%0";
6076       abort();
6077
6078     default:
6079       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6080          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6081       if (GET_CODE (operands[2]) == CONST_INT
6082           && (INTVAL (operands[2]) == 128
6083               || (INTVAL (operands[2]) < 0
6084                   && INTVAL (operands[2]) != -128)))
6085         {
6086           operands[2] = GEN_INT (-INTVAL (operands[2]));
6087           return "sub{w}\t{%2, %0|%0, %2}";
6088         }
6089       return "add{w}\t{%2, %0|%0, %2}";
6090     }
6091 }
6092   [(set (attr "type")
6093      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6094         (const_string "incdec")
6095         (const_string "alu")))
6096    (set_attr "mode" "HI")])
6097
6098 (define_insn "*addhi_3"
6099   [(set (reg 17)
6100         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6101                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6102    (clobber (match_scratch:HI 0 "=r"))]
6103   "ix86_match_ccmode (insn, CCZmode)
6104    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6105 {
6106   switch (get_attr_type (insn))
6107     {
6108     case TYPE_INCDEC:
6109       if (operands[2] == const1_rtx)
6110         return "inc{w}\t%0";
6111       else if (operands[2] == constm1_rtx)
6112         return "dec{w}\t%0";
6113       abort();
6114
6115     default:
6116       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6117          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6118       if (GET_CODE (operands[2]) == CONST_INT
6119           && (INTVAL (operands[2]) == 128
6120               || (INTVAL (operands[2]) < 0
6121                   && INTVAL (operands[2]) != -128)))
6122         {
6123           operands[2] = GEN_INT (-INTVAL (operands[2]));
6124           return "sub{w}\t{%2, %0|%0, %2}";
6125         }
6126       return "add{w}\t{%2, %0|%0, %2}";
6127     }
6128 }
6129   [(set (attr "type")
6130      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6131         (const_string "incdec")
6132         (const_string "alu")))
6133    (set_attr "mode" "HI")])
6134
6135 ; See comments above addsi_3_imm for details.
6136 (define_insn "*addhi_4"
6137   [(set (reg 17)
6138         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6139                  (match_operand:HI 2 "const_int_operand" "n")))
6140    (clobber (match_scratch:HI 0 "=rm"))]
6141   "ix86_match_ccmode (insn, CCGCmode)
6142    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6143 {
6144   switch (get_attr_type (insn))
6145     {
6146     case TYPE_INCDEC:
6147       if (operands[2] == constm1_rtx)
6148         return "inc{w}\t%0";
6149       else if (operands[2] == const1_rtx)
6150         return "dec{w}\t%0";
6151       else
6152         abort();
6153
6154     default:
6155       if (! rtx_equal_p (operands[0], operands[1]))
6156         abort ();
6157       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6158          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6159       if ((INTVAL (operands[2]) == -128
6160            || (INTVAL (operands[2]) > 0
6161                && INTVAL (operands[2]) != 128)))
6162         return "sub{w}\t{%2, %0|%0, %2}";
6163       operands[2] = GEN_INT (-INTVAL (operands[2]));
6164       return "add{w}\t{%2, %0|%0, %2}";
6165     }
6166 }
6167   [(set (attr "type")
6168      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6169         (const_string "incdec")
6170         (const_string "alu")))
6171    (set_attr "mode" "SI")])
6172
6173
6174 (define_insn "*addhi_5"
6175   [(set (reg 17)
6176         (compare
6177           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6178                    (match_operand:HI 2 "general_operand" "rmni"))
6179           (const_int 0)))                       
6180    (clobber (match_scratch:HI 0 "=r"))]
6181   "ix86_match_ccmode (insn, CCGOCmode)
6182    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6183 {
6184   switch (get_attr_type (insn))
6185     {
6186     case TYPE_INCDEC:
6187       if (operands[2] == const1_rtx)
6188         return "inc{w}\t%0";
6189       else if (operands[2] == constm1_rtx)
6190         return "dec{w}\t%0";
6191       abort();
6192
6193     default:
6194       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6195          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6196       if (GET_CODE (operands[2]) == CONST_INT
6197           && (INTVAL (operands[2]) == 128
6198               || (INTVAL (operands[2]) < 0
6199                   && INTVAL (operands[2]) != -128)))
6200         {
6201           operands[2] = GEN_INT (-INTVAL (operands[2]));
6202           return "sub{w}\t{%2, %0|%0, %2}";
6203         }
6204       return "add{w}\t{%2, %0|%0, %2}";
6205     }
6206 }
6207   [(set (attr "type")
6208      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6209         (const_string "incdec")
6210         (const_string "alu")))
6211    (set_attr "mode" "HI")])
6212
6213 (define_expand "addqi3"
6214   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6215                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6216                             (match_operand:QI 2 "general_operand" "")))
6217               (clobber (reg:CC FLAGS_REG))])]
6218   "TARGET_QIMODE_MATH"
6219   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6220
6221 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6222 (define_insn "*addqi_1_lea"
6223   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6224         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6225                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6226    (clobber (reg:CC FLAGS_REG))]
6227   "!TARGET_PARTIAL_REG_STALL
6228    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6229 {
6230   int widen = (which_alternative == 2);
6231   switch (get_attr_type (insn))
6232     {
6233     case TYPE_LEA:
6234       return "#";
6235     case TYPE_INCDEC:
6236       if (operands[2] == const1_rtx)
6237         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6238       else if (operands[2] == constm1_rtx)
6239         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6240       abort();
6241
6242     default:
6243       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6244          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6245       if (GET_CODE (operands[2]) == CONST_INT
6246           && (INTVAL (operands[2]) == 128
6247               || (INTVAL (operands[2]) < 0
6248                   && INTVAL (operands[2]) != -128)))
6249         {
6250           operands[2] = GEN_INT (-INTVAL (operands[2]));
6251           if (widen)
6252             return "sub{l}\t{%2, %k0|%k0, %2}";
6253           else
6254             return "sub{b}\t{%2, %0|%0, %2}";
6255         }
6256       if (widen)
6257         return "add{l}\t{%k2, %k0|%k0, %k2}";
6258       else
6259         return "add{b}\t{%2, %0|%0, %2}";
6260     }
6261 }
6262   [(set (attr "type")
6263      (if_then_else (eq_attr "alternative" "3")
6264         (const_string "lea")
6265         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6266            (const_string "incdec")
6267            (const_string "alu"))))
6268    (set_attr "mode" "QI,QI,SI,SI")])
6269
6270 (define_insn "*addqi_1"
6271   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6272         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6273                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6274    (clobber (reg:CC FLAGS_REG))]
6275   "TARGET_PARTIAL_REG_STALL
6276    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6277 {
6278   int widen = (which_alternative == 2);
6279   switch (get_attr_type (insn))
6280     {
6281     case TYPE_INCDEC:
6282       if (operands[2] == const1_rtx)
6283         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6284       else if (operands[2] == constm1_rtx)
6285         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6286       abort();
6287
6288     default:
6289       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6290          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6291       if (GET_CODE (operands[2]) == CONST_INT
6292           && (INTVAL (operands[2]) == 128
6293               || (INTVAL (operands[2]) < 0
6294                   && INTVAL (operands[2]) != -128)))
6295         {
6296           operands[2] = GEN_INT (-INTVAL (operands[2]));
6297           if (widen)
6298             return "sub{l}\t{%2, %k0|%k0, %2}";
6299           else
6300             return "sub{b}\t{%2, %0|%0, %2}";
6301         }
6302       if (widen)
6303         return "add{l}\t{%k2, %k0|%k0, %k2}";
6304       else
6305         return "add{b}\t{%2, %0|%0, %2}";
6306     }
6307 }
6308   [(set (attr "type")
6309      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6310         (const_string "incdec")
6311         (const_string "alu")))
6312    (set_attr "mode" "QI,QI,SI")])
6313
6314 (define_insn "*addqi_1_slp"
6315   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6316         (plus:QI (match_dup 0)
6317                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6318    (clobber (reg:CC FLAGS_REG))]
6319   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6320    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6321 {
6322   switch (get_attr_type (insn))
6323     {
6324     case TYPE_INCDEC:
6325       if (operands[1] == const1_rtx)
6326         return "inc{b}\t%0";
6327       else if (operands[1] == constm1_rtx)
6328         return "dec{b}\t%0";
6329       abort();
6330
6331     default:
6332       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6333       if (GET_CODE (operands[1]) == CONST_INT
6334           && INTVAL (operands[1]) < 0)
6335         {
6336           operands[1] = GEN_INT (-INTVAL (operands[1]));
6337           return "sub{b}\t{%1, %0|%0, %1}";
6338         }
6339       return "add{b}\t{%1, %0|%0, %1}";
6340     }
6341 }
6342   [(set (attr "type")
6343      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6344         (const_string "incdec")
6345         (const_string "alu1")))
6346    (set_attr "mode" "QI")])
6347
6348 (define_insn "*addqi_2"
6349   [(set (reg 17)
6350         (compare
6351           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6352                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6353           (const_int 0)))
6354    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6355         (plus:QI (match_dup 1) (match_dup 2)))]
6356   "ix86_match_ccmode (insn, CCGOCmode)
6357    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6358 {
6359   switch (get_attr_type (insn))
6360     {
6361     case TYPE_INCDEC:
6362       if (operands[2] == const1_rtx)
6363         return "inc{b}\t%0";
6364       else if (operands[2] == constm1_rtx
6365                || (GET_CODE (operands[2]) == CONST_INT
6366                    && INTVAL (operands[2]) == 255))
6367         return "dec{b}\t%0";
6368       abort();
6369
6370     default:
6371       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6372       if (GET_CODE (operands[2]) == CONST_INT
6373           && INTVAL (operands[2]) < 0)
6374         {
6375           operands[2] = GEN_INT (-INTVAL (operands[2]));
6376           return "sub{b}\t{%2, %0|%0, %2}";
6377         }
6378       return "add{b}\t{%2, %0|%0, %2}";
6379     }
6380 }
6381   [(set (attr "type")
6382      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6383         (const_string "incdec")
6384         (const_string "alu")))
6385    (set_attr "mode" "QI")])
6386
6387 (define_insn "*addqi_3"
6388   [(set (reg 17)
6389         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6390                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6391    (clobber (match_scratch:QI 0 "=q"))]
6392   "ix86_match_ccmode (insn, CCZmode)
6393    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6394 {
6395   switch (get_attr_type (insn))
6396     {
6397     case TYPE_INCDEC:
6398       if (operands[2] == const1_rtx)
6399         return "inc{b}\t%0";
6400       else if (operands[2] == constm1_rtx
6401                || (GET_CODE (operands[2]) == CONST_INT
6402                    && INTVAL (operands[2]) == 255))
6403         return "dec{b}\t%0";
6404       abort();
6405
6406     default:
6407       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6408       if (GET_CODE (operands[2]) == CONST_INT
6409           && INTVAL (operands[2]) < 0)
6410         {
6411           operands[2] = GEN_INT (-INTVAL (operands[2]));
6412           return "sub{b}\t{%2, %0|%0, %2}";
6413         }
6414       return "add{b}\t{%2, %0|%0, %2}";
6415     }
6416 }
6417   [(set (attr "type")
6418      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6419         (const_string "incdec")
6420         (const_string "alu")))
6421    (set_attr "mode" "QI")])
6422
6423 ; See comments above addsi_3_imm for details.
6424 (define_insn "*addqi_4"
6425   [(set (reg 17)
6426         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6427                  (match_operand:QI 2 "const_int_operand" "n")))
6428    (clobber (match_scratch:QI 0 "=qm"))]
6429   "ix86_match_ccmode (insn, CCGCmode)
6430    && (INTVAL (operands[2]) & 0xff) != 0x80"
6431 {
6432   switch (get_attr_type (insn))
6433     {
6434     case TYPE_INCDEC:
6435       if (operands[2] == constm1_rtx
6436           || (GET_CODE (operands[2]) == CONST_INT
6437               && INTVAL (operands[2]) == 255))
6438         return "inc{b}\t%0";
6439       else if (operands[2] == const1_rtx)
6440         return "dec{b}\t%0";
6441       else
6442         abort();
6443
6444     default:
6445       if (! rtx_equal_p (operands[0], operands[1]))
6446         abort ();
6447       if (INTVAL (operands[2]) < 0)
6448         {
6449           operands[2] = GEN_INT (-INTVAL (operands[2]));
6450           return "add{b}\t{%2, %0|%0, %2}";
6451         }
6452       return "sub{b}\t{%2, %0|%0, %2}";
6453     }
6454 }
6455   [(set (attr "type")
6456      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6457         (const_string "incdec")
6458         (const_string "alu")))
6459    (set_attr "mode" "QI")])
6460
6461
6462 (define_insn "*addqi_5"
6463   [(set (reg 17)
6464         (compare
6465           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6466                    (match_operand:QI 2 "general_operand" "qmni"))
6467           (const_int 0)))
6468    (clobber (match_scratch:QI 0 "=q"))]
6469   "ix86_match_ccmode (insn, CCGOCmode)
6470    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6471 {
6472   switch (get_attr_type (insn))
6473     {
6474     case TYPE_INCDEC:
6475       if (operands[2] == const1_rtx)
6476         return "inc{b}\t%0";
6477       else if (operands[2] == constm1_rtx
6478                || (GET_CODE (operands[2]) == CONST_INT
6479                    && INTVAL (operands[2]) == 255))
6480         return "dec{b}\t%0";
6481       abort();
6482
6483     default:
6484       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6485       if (GET_CODE (operands[2]) == CONST_INT
6486           && INTVAL (operands[2]) < 0)
6487         {
6488           operands[2] = GEN_INT (-INTVAL (operands[2]));
6489           return "sub{b}\t{%2, %0|%0, %2}";
6490         }
6491       return "add{b}\t{%2, %0|%0, %2}";
6492     }
6493 }
6494   [(set (attr "type")
6495      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6496         (const_string "incdec")
6497         (const_string "alu")))
6498    (set_attr "mode" "QI")])
6499
6500
6501 (define_insn "addqi_ext_1"
6502   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6503                          (const_int 8)
6504                          (const_int 8))
6505         (plus:SI
6506           (zero_extract:SI
6507             (match_operand 1 "ext_register_operand" "0")
6508             (const_int 8)
6509             (const_int 8))
6510           (match_operand:QI 2 "general_operand" "Qmn")))
6511    (clobber (reg:CC FLAGS_REG))]
6512   "!TARGET_64BIT"
6513 {
6514   switch (get_attr_type (insn))
6515     {
6516     case TYPE_INCDEC:
6517       if (operands[2] == const1_rtx)
6518         return "inc{b}\t%h0";
6519       else if (operands[2] == constm1_rtx
6520                || (GET_CODE (operands[2]) == CONST_INT
6521                    && INTVAL (operands[2]) == 255))
6522         return "dec{b}\t%h0";
6523       abort();
6524
6525     default:
6526       return "add{b}\t{%2, %h0|%h0, %2}";
6527     }
6528 }
6529   [(set (attr "type")
6530      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6531         (const_string "incdec")
6532         (const_string "alu")))
6533    (set_attr "mode" "QI")])
6534
6535 (define_insn "*addqi_ext_1_rex64"
6536   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6537                          (const_int 8)
6538                          (const_int 8))
6539         (plus:SI
6540           (zero_extract:SI
6541             (match_operand 1 "ext_register_operand" "0")
6542             (const_int 8)
6543             (const_int 8))
6544           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6545    (clobber (reg:CC FLAGS_REG))]
6546   "TARGET_64BIT"
6547 {
6548   switch (get_attr_type (insn))
6549     {
6550     case TYPE_INCDEC:
6551       if (operands[2] == const1_rtx)
6552         return "inc{b}\t%h0";
6553       else if (operands[2] == constm1_rtx
6554                || (GET_CODE (operands[2]) == CONST_INT
6555                    && INTVAL (operands[2]) == 255))
6556         return "dec{b}\t%h0";
6557       abort();
6558
6559     default:
6560       return "add{b}\t{%2, %h0|%h0, %2}";
6561     }
6562 }
6563   [(set (attr "type")
6564      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6565         (const_string "incdec")
6566         (const_string "alu")))
6567    (set_attr "mode" "QI")])
6568
6569 (define_insn "*addqi_ext_2"
6570   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6571                          (const_int 8)
6572                          (const_int 8))
6573         (plus:SI
6574           (zero_extract:SI
6575             (match_operand 1 "ext_register_operand" "%0")
6576             (const_int 8)
6577             (const_int 8))
6578           (zero_extract:SI
6579             (match_operand 2 "ext_register_operand" "Q")
6580             (const_int 8)
6581             (const_int 8))))
6582    (clobber (reg:CC FLAGS_REG))]
6583   ""
6584   "add{b}\t{%h2, %h0|%h0, %h2}"
6585   [(set_attr "type" "alu")
6586    (set_attr "mode" "QI")])
6587
6588 ;; The patterns that match these are at the end of this file.
6589
6590 (define_expand "addxf3"
6591   [(set (match_operand:XF 0 "register_operand" "")
6592         (plus:XF (match_operand:XF 1 "register_operand" "")
6593                  (match_operand:XF 2 "register_operand" "")))]
6594   "TARGET_80387"
6595   "")
6596
6597 (define_expand "adddf3"
6598   [(set (match_operand:DF 0 "register_operand" "")
6599         (plus:DF (match_operand:DF 1 "register_operand" "")
6600                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6601   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6602   "")
6603
6604 (define_expand "addsf3"
6605   [(set (match_operand:SF 0 "register_operand" "")
6606         (plus:SF (match_operand:SF 1 "register_operand" "")
6607                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6608   "TARGET_80387 || TARGET_SSE_MATH"
6609   "")
6610 \f
6611 ;; Subtract instructions
6612
6613 ;; %%% splits for subsidi3
6614
6615 (define_expand "subdi3"
6616   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6617                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6618                              (match_operand:DI 2 "x86_64_general_operand" "")))
6619               (clobber (reg:CC FLAGS_REG))])]
6620   ""
6621   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6622
6623 (define_insn "*subdi3_1"
6624   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6625         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6626                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6627    (clobber (reg:CC FLAGS_REG))]
6628   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6629   "#")
6630
6631 (define_split
6632   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6633         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6634                   (match_operand:DI 2 "general_operand" "")))
6635    (clobber (reg:CC FLAGS_REG))]
6636   "!TARGET_64BIT && reload_completed"
6637   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6638               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6639    (parallel [(set (match_dup 3)
6640                    (minus:SI (match_dup 4)
6641                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6642                                       (match_dup 5))))
6643               (clobber (reg:CC FLAGS_REG))])]
6644   "split_di (operands+0, 1, operands+0, operands+3);
6645    split_di (operands+1, 1, operands+1, operands+4);
6646    split_di (operands+2, 1, operands+2, operands+5);")
6647
6648 (define_insn "subdi3_carry_rex64"
6649   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6650           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6651             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6652                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6653    (clobber (reg:CC FLAGS_REG))]
6654   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6655   "sbb{q}\t{%2, %0|%0, %2}"
6656   [(set_attr "type" "alu")
6657    (set_attr "pent_pair" "pu")
6658    (set_attr "mode" "DI")])
6659
6660 (define_insn "*subdi_1_rex64"
6661   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6662         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6663                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6664    (clobber (reg:CC FLAGS_REG))]
6665   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6666   "sub{q}\t{%2, %0|%0, %2}"
6667   [(set_attr "type" "alu")
6668    (set_attr "mode" "DI")])
6669
6670 (define_insn "*subdi_2_rex64"
6671   [(set (reg 17)
6672         (compare
6673           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6674                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6675           (const_int 0)))
6676    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6677         (minus:DI (match_dup 1) (match_dup 2)))]
6678   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6679    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6680   "sub{q}\t{%2, %0|%0, %2}"
6681   [(set_attr "type" "alu")
6682    (set_attr "mode" "DI")])
6683
6684 (define_insn "*subdi_3_rex63"
6685   [(set (reg 17)
6686         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6687                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6688    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6689         (minus:DI (match_dup 1) (match_dup 2)))]
6690   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692   "sub{q}\t{%2, %0|%0, %2}"
6693   [(set_attr "type" "alu")
6694    (set_attr "mode" "DI")])
6695
6696 (define_insn "subqi3_carry"
6697   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6698           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6699             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6700                (match_operand:QI 2 "general_operand" "qi,qm"))))
6701    (clobber (reg:CC FLAGS_REG))]
6702   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6703   "sbb{b}\t{%2, %0|%0, %2}"
6704   [(set_attr "type" "alu")
6705    (set_attr "pent_pair" "pu")
6706    (set_attr "mode" "QI")])
6707
6708 (define_insn "subhi3_carry"
6709   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6710           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6711             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6712                (match_operand:HI 2 "general_operand" "ri,rm"))))
6713    (clobber (reg:CC FLAGS_REG))]
6714   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6715   "sbb{w}\t{%2, %0|%0, %2}"
6716   [(set_attr "type" "alu")
6717    (set_attr "pent_pair" "pu")
6718    (set_attr "mode" "HI")])
6719
6720 (define_insn "subsi3_carry"
6721   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6722           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6723             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6724                (match_operand:SI 2 "general_operand" "ri,rm"))))
6725    (clobber (reg:CC FLAGS_REG))]
6726   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6727   "sbb{l}\t{%2, %0|%0, %2}"
6728   [(set_attr "type" "alu")
6729    (set_attr "pent_pair" "pu")
6730    (set_attr "mode" "SI")])
6731
6732 (define_insn "subsi3_carry_zext"
6733   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6734           (zero_extend:DI
6735             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6736               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6737                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6738    (clobber (reg:CC FLAGS_REG))]
6739   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6740   "sbb{l}\t{%2, %k0|%k0, %2}"
6741   [(set_attr "type" "alu")
6742    (set_attr "pent_pair" "pu")
6743    (set_attr "mode" "SI")])
6744
6745 (define_expand "subsi3"
6746   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6747                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6748                              (match_operand:SI 2 "general_operand" "")))
6749               (clobber (reg:CC FLAGS_REG))])]
6750   ""
6751   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6752
6753 (define_insn "*subsi_1"
6754   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6755         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6756                   (match_operand:SI 2 "general_operand" "ri,rm")))
6757    (clobber (reg:CC FLAGS_REG))]
6758   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6759   "sub{l}\t{%2, %0|%0, %2}"
6760   [(set_attr "type" "alu")
6761    (set_attr "mode" "SI")])
6762
6763 (define_insn "*subsi_1_zext"
6764   [(set (match_operand:DI 0 "register_operand" "=r")
6765         (zero_extend:DI
6766           (minus:SI (match_operand:SI 1 "register_operand" "0")
6767                     (match_operand:SI 2 "general_operand" "rim"))))
6768    (clobber (reg:CC FLAGS_REG))]
6769   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6770   "sub{l}\t{%2, %k0|%k0, %2}"
6771   [(set_attr "type" "alu")
6772    (set_attr "mode" "SI")])
6773
6774 (define_insn "*subsi_2"
6775   [(set (reg 17)
6776         (compare
6777           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6778                     (match_operand:SI 2 "general_operand" "ri,rm"))
6779           (const_int 0)))
6780    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6781         (minus:SI (match_dup 1) (match_dup 2)))]
6782   "ix86_match_ccmode (insn, CCGOCmode)
6783    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784   "sub{l}\t{%2, %0|%0, %2}"
6785   [(set_attr "type" "alu")
6786    (set_attr "mode" "SI")])
6787
6788 (define_insn "*subsi_2_zext"
6789   [(set (reg 17)
6790         (compare
6791           (minus:SI (match_operand:SI 1 "register_operand" "0")
6792                     (match_operand:SI 2 "general_operand" "rim"))
6793           (const_int 0)))
6794    (set (match_operand:DI 0 "register_operand" "=r")
6795         (zero_extend:DI
6796           (minus:SI (match_dup 1)
6797                     (match_dup 2))))]
6798   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6799    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6800   "sub{l}\t{%2, %k0|%k0, %2}"
6801   [(set_attr "type" "alu")
6802    (set_attr "mode" "SI")])
6803
6804 (define_insn "*subsi_3"
6805   [(set (reg 17)
6806         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6807                  (match_operand:SI 2 "general_operand" "ri,rm")))
6808    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6809         (minus:SI (match_dup 1) (match_dup 2)))]
6810   "ix86_match_ccmode (insn, CCmode)
6811    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6812   "sub{l}\t{%2, %0|%0, %2}"
6813   [(set_attr "type" "alu")
6814    (set_attr "mode" "SI")])
6815
6816 (define_insn "*subsi_3_zext"
6817   [(set (reg 17)
6818         (compare (match_operand:SI 1 "register_operand" "0")
6819                  (match_operand:SI 2 "general_operand" "rim")))
6820    (set (match_operand:DI 0 "register_operand" "=r")
6821         (zero_extend:DI
6822           (minus:SI (match_dup 1)
6823                     (match_dup 2))))]
6824   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6825    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6826   "sub{q}\t{%2, %0|%0, %2}"
6827   [(set_attr "type" "alu")
6828    (set_attr "mode" "DI")])
6829
6830 (define_expand "subhi3"
6831   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6832                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6833                              (match_operand:HI 2 "general_operand" "")))
6834               (clobber (reg:CC FLAGS_REG))])]
6835   "TARGET_HIMODE_MATH"
6836   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6837
6838 (define_insn "*subhi_1"
6839   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6840         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6841                   (match_operand:HI 2 "general_operand" "ri,rm")))
6842    (clobber (reg:CC FLAGS_REG))]
6843   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6844   "sub{w}\t{%2, %0|%0, %2}"
6845   [(set_attr "type" "alu")
6846    (set_attr "mode" "HI")])
6847
6848 (define_insn "*subhi_2"
6849   [(set (reg 17)
6850         (compare
6851           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6852                     (match_operand:HI 2 "general_operand" "ri,rm"))
6853           (const_int 0)))
6854    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6855         (minus:HI (match_dup 1) (match_dup 2)))]
6856   "ix86_match_ccmode (insn, CCGOCmode)
6857    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6858   "sub{w}\t{%2, %0|%0, %2}"
6859   [(set_attr "type" "alu")
6860    (set_attr "mode" "HI")])
6861
6862 (define_insn "*subhi_3"
6863   [(set (reg 17)
6864         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6865                  (match_operand:HI 2 "general_operand" "ri,rm")))
6866    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6867         (minus:HI (match_dup 1) (match_dup 2)))]
6868   "ix86_match_ccmode (insn, CCmode)
6869    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6870   "sub{w}\t{%2, %0|%0, %2}"
6871   [(set_attr "type" "alu")
6872    (set_attr "mode" "HI")])
6873
6874 (define_expand "subqi3"
6875   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6876                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6877                              (match_operand:QI 2 "general_operand" "")))
6878               (clobber (reg:CC FLAGS_REG))])]
6879   "TARGET_QIMODE_MATH"
6880   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6881
6882 (define_insn "*subqi_1"
6883   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6884         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6885                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6886    (clobber (reg:CC FLAGS_REG))]
6887   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6888   "sub{b}\t{%2, %0|%0, %2}"
6889   [(set_attr "type" "alu")
6890    (set_attr "mode" "QI")])
6891
6892 (define_insn "*subqi_1_slp"
6893   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6894         (minus:QI (match_dup 0)
6895                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6896    (clobber (reg:CC FLAGS_REG))]
6897   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6898    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6899   "sub{b}\t{%1, %0|%0, %1}"
6900   [(set_attr "type" "alu1")
6901    (set_attr "mode" "QI")])
6902
6903 (define_insn "*subqi_2"
6904   [(set (reg 17)
6905         (compare
6906           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6907                     (match_operand:QI 2 "general_operand" "qi,qm"))
6908           (const_int 0)))
6909    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6910         (minus:HI (match_dup 1) (match_dup 2)))]
6911   "ix86_match_ccmode (insn, CCGOCmode)
6912    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6913   "sub{b}\t{%2, %0|%0, %2}"
6914   [(set_attr "type" "alu")
6915    (set_attr "mode" "QI")])
6916
6917 (define_insn "*subqi_3"
6918   [(set (reg 17)
6919         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6920                  (match_operand:QI 2 "general_operand" "qi,qm")))
6921    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6922         (minus:HI (match_dup 1) (match_dup 2)))]
6923   "ix86_match_ccmode (insn, CCmode)
6924    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6925   "sub{b}\t{%2, %0|%0, %2}"
6926   [(set_attr "type" "alu")
6927    (set_attr "mode" "QI")])
6928
6929 ;; The patterns that match these are at the end of this file.
6930
6931 (define_expand "subxf3"
6932   [(set (match_operand:XF 0 "register_operand" "")
6933         (minus:XF (match_operand:XF 1 "register_operand" "")
6934                   (match_operand:XF 2 "register_operand" "")))]
6935   "TARGET_80387"
6936   "")
6937
6938 (define_expand "subdf3"
6939   [(set (match_operand:DF 0 "register_operand" "")
6940         (minus:DF (match_operand:DF 1 "register_operand" "")
6941                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6942   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6943   "")
6944
6945 (define_expand "subsf3"
6946   [(set (match_operand:SF 0 "register_operand" "")
6947         (minus:SF (match_operand:SF 1 "register_operand" "")
6948                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6949   "TARGET_80387 || TARGET_SSE_MATH"
6950   "")
6951 \f
6952 ;; Multiply instructions
6953
6954 (define_expand "muldi3"
6955   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6956                    (mult:DI (match_operand:DI 1 "register_operand" "")
6957                             (match_operand:DI 2 "x86_64_general_operand" "")))
6958               (clobber (reg:CC FLAGS_REG))])]
6959   "TARGET_64BIT"
6960   "")
6961
6962 (define_insn "*muldi3_1_rex64"
6963   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6964         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6965                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6966    (clobber (reg:CC FLAGS_REG))]
6967   "TARGET_64BIT
6968    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6969   "@
6970    imul{q}\t{%2, %1, %0|%0, %1, %2}
6971    imul{q}\t{%2, %1, %0|%0, %1, %2}
6972    imul{q}\t{%2, %0|%0, %2}"
6973   [(set_attr "type" "imul")
6974    (set_attr "prefix_0f" "0,0,1")
6975    (set (attr "athlon_decode")
6976         (cond [(eq_attr "cpu" "athlon")
6977                   (const_string "vector")
6978                (eq_attr "alternative" "1")
6979                   (const_string "vector")
6980                (and (eq_attr "alternative" "2")
6981                     (match_operand 1 "memory_operand" ""))
6982                   (const_string "vector")]
6983               (const_string "direct")))
6984    (set_attr "mode" "DI")])
6985
6986 (define_expand "mulsi3"
6987   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6988                    (mult:SI (match_operand:SI 1 "register_operand" "")
6989                             (match_operand:SI 2 "general_operand" "")))
6990               (clobber (reg:CC FLAGS_REG))])]
6991   ""
6992   "")
6993
6994 (define_insn "*mulsi3_1"
6995   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6996         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6997                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6998    (clobber (reg:CC FLAGS_REG))]
6999   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7000   "@
7001    imul{l}\t{%2, %1, %0|%0, %1, %2}
7002    imul{l}\t{%2, %1, %0|%0, %1, %2}
7003    imul{l}\t{%2, %0|%0, %2}"
7004   [(set_attr "type" "imul")
7005    (set_attr "prefix_0f" "0,0,1")
7006    (set (attr "athlon_decode")
7007         (cond [(eq_attr "cpu" "athlon")
7008                   (const_string "vector")
7009                (eq_attr "alternative" "1")
7010                   (const_string "vector")
7011                (and (eq_attr "alternative" "2")
7012                     (match_operand 1 "memory_operand" ""))
7013                   (const_string "vector")]
7014               (const_string "direct")))
7015    (set_attr "mode" "SI")])
7016
7017 (define_insn "*mulsi3_1_zext"
7018   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7019         (zero_extend:DI
7020           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7021                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7022    (clobber (reg:CC FLAGS_REG))]
7023   "TARGET_64BIT
7024    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7025   "@
7026    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7027    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7028    imul{l}\t{%2, %k0|%k0, %2}"
7029   [(set_attr "type" "imul")
7030    (set_attr "prefix_0f" "0,0,1")
7031    (set (attr "athlon_decode")
7032         (cond [(eq_attr "cpu" "athlon")
7033                   (const_string "vector")
7034                (eq_attr "alternative" "1")
7035                   (const_string "vector")
7036                (and (eq_attr "alternative" "2")
7037                     (match_operand 1 "memory_operand" ""))
7038                   (const_string "vector")]
7039               (const_string "direct")))
7040    (set_attr "mode" "SI")])
7041
7042 (define_expand "mulhi3"
7043   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7044                    (mult:HI (match_operand:HI 1 "register_operand" "")
7045                             (match_operand:HI 2 "general_operand" "")))
7046               (clobber (reg:CC FLAGS_REG))])]
7047   "TARGET_HIMODE_MATH"
7048   "")
7049
7050 (define_insn "*mulhi3_1"
7051   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7052         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7053                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7054    (clobber (reg:CC FLAGS_REG))]
7055   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7056   "@
7057    imul{w}\t{%2, %1, %0|%0, %1, %2}
7058    imul{w}\t{%2, %1, %0|%0, %1, %2}
7059    imul{w}\t{%2, %0|%0, %2}"
7060   [(set_attr "type" "imul")
7061    (set_attr "prefix_0f" "0,0,1")
7062    (set (attr "athlon_decode")
7063         (cond [(eq_attr "cpu" "athlon")
7064                   (const_string "vector")
7065                (eq_attr "alternative" "1,2")
7066                   (const_string "vector")]
7067               (const_string "direct")))
7068    (set_attr "mode" "HI")])
7069
7070 (define_expand "mulqi3"
7071   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7072                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7073                             (match_operand:QI 2 "register_operand" "")))
7074               (clobber (reg:CC FLAGS_REG))])]
7075   "TARGET_QIMODE_MATH"
7076   "")
7077
7078 (define_insn "*mulqi3_1"
7079   [(set (match_operand:QI 0 "register_operand" "=a")
7080         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7081                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7082    (clobber (reg:CC FLAGS_REG))]
7083   "TARGET_QIMODE_MATH
7084    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7085   "mul{b}\t%2"
7086   [(set_attr "type" "imul")
7087    (set_attr "length_immediate" "0")
7088    (set (attr "athlon_decode")
7089      (if_then_else (eq_attr "cpu" "athlon")
7090         (const_string "vector")
7091         (const_string "direct")))
7092    (set_attr "mode" "QI")])
7093
7094 (define_expand "umulqihi3"
7095   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7096                    (mult:HI (zero_extend:HI
7097                               (match_operand:QI 1 "nonimmediate_operand" ""))
7098                             (zero_extend:HI
7099                               (match_operand:QI 2 "register_operand" ""))))
7100               (clobber (reg:CC FLAGS_REG))])]
7101   "TARGET_QIMODE_MATH"
7102   "")
7103
7104 (define_insn "*umulqihi3_1"
7105   [(set (match_operand:HI 0 "register_operand" "=a")
7106         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7107                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7108    (clobber (reg:CC FLAGS_REG))]
7109   "TARGET_QIMODE_MATH
7110    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7111   "mul{b}\t%2"
7112   [(set_attr "type" "imul")
7113    (set_attr "length_immediate" "0")
7114    (set (attr "athlon_decode")
7115      (if_then_else (eq_attr "cpu" "athlon")
7116         (const_string "vector")
7117         (const_string "direct")))
7118    (set_attr "mode" "QI")])
7119
7120 (define_expand "mulqihi3"
7121   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7122                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7123                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7124               (clobber (reg:CC FLAGS_REG))])]
7125   "TARGET_QIMODE_MATH"
7126   "")
7127
7128 (define_insn "*mulqihi3_insn"
7129   [(set (match_operand:HI 0 "register_operand" "=a")
7130         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7131                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7132    (clobber (reg:CC FLAGS_REG))]
7133   "TARGET_QIMODE_MATH
7134    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7135   "imul{b}\t%2"
7136   [(set_attr "type" "imul")
7137    (set_attr "length_immediate" "0")
7138    (set (attr "athlon_decode")
7139      (if_then_else (eq_attr "cpu" "athlon")
7140         (const_string "vector")
7141         (const_string "direct")))
7142    (set_attr "mode" "QI")])
7143
7144 (define_expand "umulditi3"
7145   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7146                    (mult:TI (zero_extend:TI
7147                               (match_operand:DI 1 "nonimmediate_operand" ""))
7148                             (zero_extend:TI
7149                               (match_operand:DI 2 "register_operand" ""))))
7150               (clobber (reg:CC FLAGS_REG))])]
7151   "TARGET_64BIT"
7152   "")
7153
7154 (define_insn "*umulditi3_insn"
7155   [(set (match_operand:TI 0 "register_operand" "=A")
7156         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7157                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7158    (clobber (reg:CC FLAGS_REG))]
7159   "TARGET_64BIT
7160    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7161   "mul{q}\t%2"
7162   [(set_attr "type" "imul")
7163    (set_attr "length_immediate" "0")
7164    (set (attr "athlon_decode")
7165      (if_then_else (eq_attr "cpu" "athlon")
7166         (const_string "vector")
7167         (const_string "double")))
7168    (set_attr "mode" "DI")])
7169
7170 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7171 (define_expand "umulsidi3"
7172   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7173                    (mult:DI (zero_extend:DI
7174                               (match_operand:SI 1 "nonimmediate_operand" ""))
7175                             (zero_extend:DI
7176                               (match_operand:SI 2 "register_operand" ""))))
7177               (clobber (reg:CC FLAGS_REG))])]
7178   "!TARGET_64BIT"
7179   "")
7180
7181 (define_insn "*umulsidi3_insn"
7182   [(set (match_operand:DI 0 "register_operand" "=A")
7183         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7184                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7185    (clobber (reg:CC FLAGS_REG))]
7186   "!TARGET_64BIT
7187    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7188   "mul{l}\t%2"
7189   [(set_attr "type" "imul")
7190    (set_attr "length_immediate" "0")
7191    (set (attr "athlon_decode")
7192      (if_then_else (eq_attr "cpu" "athlon")
7193         (const_string "vector")
7194         (const_string "double")))
7195    (set_attr "mode" "SI")])
7196
7197 (define_expand "mulditi3"
7198   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7199                    (mult:TI (sign_extend:TI
7200                               (match_operand:DI 1 "nonimmediate_operand" ""))
7201                             (sign_extend:TI
7202                               (match_operand:DI 2 "register_operand" ""))))
7203               (clobber (reg:CC FLAGS_REG))])]
7204   "TARGET_64BIT"
7205   "")
7206
7207 (define_insn "*mulditi3_insn"
7208   [(set (match_operand:TI 0 "register_operand" "=A")
7209         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7210                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7211    (clobber (reg:CC FLAGS_REG))]
7212   "TARGET_64BIT
7213    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7214   "imul{q}\t%2"
7215   [(set_attr "type" "imul")
7216    (set_attr "length_immediate" "0")
7217    (set (attr "athlon_decode")
7218      (if_then_else (eq_attr "cpu" "athlon")
7219         (const_string "vector")
7220         (const_string "double")))
7221    (set_attr "mode" "DI")])
7222
7223 (define_expand "mulsidi3"
7224   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7225                    (mult:DI (sign_extend:DI
7226                               (match_operand:SI 1 "nonimmediate_operand" ""))
7227                             (sign_extend:DI
7228                               (match_operand:SI 2 "register_operand" ""))))
7229               (clobber (reg:CC FLAGS_REG))])]
7230   "!TARGET_64BIT"
7231   "")
7232
7233 (define_insn "*mulsidi3_insn"
7234   [(set (match_operand:DI 0 "register_operand" "=A")
7235         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7236                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7237    (clobber (reg:CC FLAGS_REG))]
7238   "!TARGET_64BIT
7239    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7240   "imul{l}\t%2"
7241   [(set_attr "type" "imul")
7242    (set_attr "length_immediate" "0")
7243    (set (attr "athlon_decode")
7244      (if_then_else (eq_attr "cpu" "athlon")
7245         (const_string "vector")
7246         (const_string "double")))
7247    (set_attr "mode" "SI")])
7248
7249 (define_expand "umuldi3_highpart"
7250   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7251                    (truncate:DI
7252                      (lshiftrt:TI
7253                        (mult:TI (zero_extend:TI
7254                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7255                                 (zero_extend:TI
7256                                   (match_operand:DI 2 "register_operand" "")))
7257                        (const_int 64))))
7258               (clobber (match_scratch:DI 3 ""))
7259               (clobber (reg:CC FLAGS_REG))])]
7260   "TARGET_64BIT"
7261   "")
7262
7263 (define_insn "*umuldi3_highpart_rex64"
7264   [(set (match_operand:DI 0 "register_operand" "=d")
7265         (truncate:DI
7266           (lshiftrt:TI
7267             (mult:TI (zero_extend:TI
7268                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7269                      (zero_extend:TI
7270                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7271             (const_int 64))))
7272    (clobber (match_scratch:DI 3 "=1"))
7273    (clobber (reg:CC FLAGS_REG))]
7274   "TARGET_64BIT
7275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7276   "mul{q}\t%2"
7277   [(set_attr "type" "imul")
7278    (set_attr "length_immediate" "0")
7279    (set (attr "athlon_decode")
7280      (if_then_else (eq_attr "cpu" "athlon")
7281         (const_string "vector")
7282         (const_string "double")))
7283    (set_attr "mode" "DI")])
7284
7285 (define_expand "umulsi3_highpart"
7286   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7287                    (truncate:SI
7288                      (lshiftrt:DI
7289                        (mult:DI (zero_extend:DI
7290                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7291                                 (zero_extend:DI
7292                                   (match_operand:SI 2 "register_operand" "")))
7293                        (const_int 32))))
7294               (clobber (match_scratch:SI 3 ""))
7295               (clobber (reg:CC FLAGS_REG))])]
7296   ""
7297   "")
7298
7299 (define_insn "*umulsi3_highpart_insn"
7300   [(set (match_operand:SI 0 "register_operand" "=d")
7301         (truncate:SI
7302           (lshiftrt:DI
7303             (mult:DI (zero_extend:DI
7304                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7305                      (zero_extend:DI
7306                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7307             (const_int 32))))
7308    (clobber (match_scratch:SI 3 "=1"))
7309    (clobber (reg:CC FLAGS_REG))]
7310   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7311   "mul{l}\t%2"
7312   [(set_attr "type" "imul")
7313    (set_attr "length_immediate" "0")
7314    (set (attr "athlon_decode")
7315      (if_then_else (eq_attr "cpu" "athlon")
7316         (const_string "vector")
7317         (const_string "double")))
7318    (set_attr "mode" "SI")])
7319
7320 (define_insn "*umulsi3_highpart_zext"
7321   [(set (match_operand:DI 0 "register_operand" "=d")
7322         (zero_extend:DI (truncate:SI
7323           (lshiftrt:DI
7324             (mult:DI (zero_extend:DI
7325                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7326                      (zero_extend:DI
7327                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7328             (const_int 32)))))
7329    (clobber (match_scratch:SI 3 "=1"))
7330    (clobber (reg:CC FLAGS_REG))]
7331   "TARGET_64BIT
7332    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7333   "mul{l}\t%2"
7334   [(set_attr "type" "imul")
7335    (set_attr "length_immediate" "0")
7336    (set (attr "athlon_decode")
7337      (if_then_else (eq_attr "cpu" "athlon")
7338         (const_string "vector")
7339         (const_string "double")))
7340    (set_attr "mode" "SI")])
7341
7342 (define_expand "smuldi3_highpart"
7343   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7344                    (truncate:DI
7345                      (lshiftrt:TI
7346                        (mult:TI (sign_extend:TI
7347                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7348                                 (sign_extend:TI
7349                                   (match_operand:DI 2 "register_operand" "")))
7350                        (const_int 64))))
7351               (clobber (match_scratch:DI 3 ""))
7352               (clobber (reg:CC FLAGS_REG))])]
7353   "TARGET_64BIT"
7354   "")
7355
7356 (define_insn "*smuldi3_highpart_rex64"
7357   [(set (match_operand:DI 0 "register_operand" "=d")
7358         (truncate:DI
7359           (lshiftrt:TI
7360             (mult:TI (sign_extend:TI
7361                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7362                      (sign_extend:TI
7363                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7364             (const_int 64))))
7365    (clobber (match_scratch:DI 3 "=1"))
7366    (clobber (reg:CC FLAGS_REG))]
7367   "TARGET_64BIT
7368    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7369   "imul{q}\t%2"
7370   [(set_attr "type" "imul")
7371    (set (attr "athlon_decode")
7372      (if_then_else (eq_attr "cpu" "athlon")
7373         (const_string "vector")
7374         (const_string "double")))
7375    (set_attr "mode" "DI")])
7376
7377 (define_expand "smulsi3_highpart"
7378   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7379                    (truncate:SI
7380                      (lshiftrt:DI
7381                        (mult:DI (sign_extend:DI
7382                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7383                                 (sign_extend:DI
7384                                   (match_operand:SI 2 "register_operand" "")))
7385                        (const_int 32))))
7386               (clobber (match_scratch:SI 3 ""))
7387               (clobber (reg:CC FLAGS_REG))])]
7388   ""
7389   "")
7390
7391 (define_insn "*smulsi3_highpart_insn"
7392   [(set (match_operand:SI 0 "register_operand" "=d")
7393         (truncate:SI
7394           (lshiftrt:DI
7395             (mult:DI (sign_extend:DI
7396                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7397                      (sign_extend:DI
7398                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7399             (const_int 32))))
7400    (clobber (match_scratch:SI 3 "=1"))
7401    (clobber (reg:CC FLAGS_REG))]
7402   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7403   "imul{l}\t%2"
7404   [(set_attr "type" "imul")
7405    (set (attr "athlon_decode")
7406      (if_then_else (eq_attr "cpu" "athlon")
7407         (const_string "vector")
7408         (const_string "double")))
7409    (set_attr "mode" "SI")])
7410
7411 (define_insn "*smulsi3_highpart_zext"
7412   [(set (match_operand:DI 0 "register_operand" "=d")
7413         (zero_extend:DI (truncate:SI
7414           (lshiftrt:DI
7415             (mult:DI (sign_extend:DI
7416                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7417                      (sign_extend:DI
7418                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7419             (const_int 32)))))
7420    (clobber (match_scratch:SI 3 "=1"))
7421    (clobber (reg:CC FLAGS_REG))]
7422   "TARGET_64BIT
7423    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7424   "imul{l}\t%2"
7425   [(set_attr "type" "imul")
7426    (set (attr "athlon_decode")
7427      (if_then_else (eq_attr "cpu" "athlon")
7428         (const_string "vector")
7429         (const_string "double")))
7430    (set_attr "mode" "SI")])
7431
7432 ;; The patterns that match these are at the end of this file.
7433
7434 (define_expand "mulxf3"
7435   [(set (match_operand:XF 0 "register_operand" "")
7436         (mult:XF (match_operand:XF 1 "register_operand" "")
7437                  (match_operand:XF 2 "register_operand" "")))]
7438   "TARGET_80387"
7439   "")
7440
7441 (define_expand "muldf3"
7442   [(set (match_operand:DF 0 "register_operand" "")
7443         (mult:DF (match_operand:DF 1 "register_operand" "")
7444                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7445   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7446   "")
7447
7448 (define_expand "mulsf3"
7449   [(set (match_operand:SF 0 "register_operand" "")
7450         (mult:SF (match_operand:SF 1 "register_operand" "")
7451                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7452   "TARGET_80387 || TARGET_SSE_MATH"
7453   "")
7454 \f
7455 ;; Divide instructions
7456
7457 (define_insn "divqi3"
7458   [(set (match_operand:QI 0 "register_operand" "=a")
7459         (div:QI (match_operand:HI 1 "register_operand" "0")
7460                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7461    (clobber (reg:CC FLAGS_REG))]
7462   "TARGET_QIMODE_MATH"
7463   "idiv{b}\t%2"
7464   [(set_attr "type" "idiv")
7465    (set_attr "mode" "QI")])
7466
7467 (define_insn "udivqi3"
7468   [(set (match_operand:QI 0 "register_operand" "=a")
7469         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7470                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7471    (clobber (reg:CC FLAGS_REG))]
7472   "TARGET_QIMODE_MATH"
7473   "div{b}\t%2"
7474   [(set_attr "type" "idiv")
7475    (set_attr "mode" "QI")])
7476
7477 ;; The patterns that match these are at the end of this file.
7478
7479 (define_expand "divxf3"
7480   [(set (match_operand:XF 0 "register_operand" "")
7481         (div:XF (match_operand:XF 1 "register_operand" "")
7482                 (match_operand:XF 2 "register_operand" "")))]
7483   "TARGET_80387"
7484   "")
7485
7486 (define_expand "divdf3"
7487   [(set (match_operand:DF 0 "register_operand" "")
7488         (div:DF (match_operand:DF 1 "register_operand" "")
7489                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7490    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7491    "")
7492  
7493 (define_expand "divsf3"
7494   [(set (match_operand:SF 0 "register_operand" "")
7495         (div:SF (match_operand:SF 1 "register_operand" "")
7496                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7497   "TARGET_80387 || TARGET_SSE_MATH"
7498   "")
7499 \f
7500 ;; Remainder instructions.
7501
7502 (define_expand "divmoddi4"
7503   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7504                    (div:DI (match_operand:DI 1 "register_operand" "")
7505                            (match_operand:DI 2 "nonimmediate_operand" "")))
7506               (set (match_operand:DI 3 "register_operand" "")
7507                    (mod:DI (match_dup 1) (match_dup 2)))
7508               (clobber (reg:CC FLAGS_REG))])]
7509   "TARGET_64BIT"
7510   "")
7511
7512 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7513 ;; Penalize eax case slightly because it results in worse scheduling
7514 ;; of code.
7515 (define_insn "*divmoddi4_nocltd_rex64"
7516   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7517         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7518                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7519    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7520         (mod:DI (match_dup 2) (match_dup 3)))
7521    (clobber (reg:CC FLAGS_REG))]
7522   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7523   "#"
7524   [(set_attr "type" "multi")])
7525
7526 (define_insn "*divmoddi4_cltd_rex64"
7527   [(set (match_operand:DI 0 "register_operand" "=a")
7528         (div:DI (match_operand:DI 2 "register_operand" "a")
7529                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7530    (set (match_operand:DI 1 "register_operand" "=&d")
7531         (mod:DI (match_dup 2) (match_dup 3)))
7532    (clobber (reg:CC FLAGS_REG))]
7533   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7534   "#"
7535   [(set_attr "type" "multi")])
7536
7537 (define_insn "*divmoddi_noext_rex64"
7538   [(set (match_operand:DI 0 "register_operand" "=a")
7539         (div:DI (match_operand:DI 1 "register_operand" "0")
7540                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7541    (set (match_operand:DI 3 "register_operand" "=d")
7542         (mod:DI (match_dup 1) (match_dup 2)))
7543    (use (match_operand:DI 4 "register_operand" "3"))
7544    (clobber (reg:CC FLAGS_REG))]
7545   "TARGET_64BIT"
7546   "idiv{q}\t%2"
7547   [(set_attr "type" "idiv")
7548    (set_attr "mode" "DI")])
7549
7550 (define_split
7551   [(set (match_operand:DI 0 "register_operand" "")
7552         (div:DI (match_operand:DI 1 "register_operand" "")
7553                 (match_operand:DI 2 "nonimmediate_operand" "")))
7554    (set (match_operand:DI 3 "register_operand" "")
7555         (mod:DI (match_dup 1) (match_dup 2)))
7556    (clobber (reg:CC FLAGS_REG))]
7557   "TARGET_64BIT && reload_completed"
7558   [(parallel [(set (match_dup 3)
7559                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7560               (clobber (reg:CC FLAGS_REG))])
7561    (parallel [(set (match_dup 0)
7562                    (div:DI (reg:DI 0) (match_dup 2)))
7563               (set (match_dup 3)
7564                    (mod:DI (reg:DI 0) (match_dup 2)))
7565               (use (match_dup 3))
7566               (clobber (reg:CC FLAGS_REG))])]
7567 {
7568   /* Avoid use of cltd in favor of a mov+shift.  */
7569   if (!TARGET_USE_CLTD && !optimize_size)
7570     {
7571       if (true_regnum (operands[1]))
7572         emit_move_insn (operands[0], operands[1]);
7573       else
7574         emit_move_insn (operands[3], operands[1]);
7575       operands[4] = operands[3];
7576     }
7577   else
7578     {
7579       if (true_regnum (operands[1]))
7580         abort();
7581       operands[4] = operands[1];
7582     }
7583 })
7584
7585
7586 (define_expand "divmodsi4"
7587   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7588                    (div:SI (match_operand:SI 1 "register_operand" "")
7589                            (match_operand:SI 2 "nonimmediate_operand" "")))
7590               (set (match_operand:SI 3 "register_operand" "")
7591                    (mod:SI (match_dup 1) (match_dup 2)))
7592               (clobber (reg:CC FLAGS_REG))])]
7593   ""
7594   "")
7595
7596 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7597 ;; Penalize eax case slightly because it results in worse scheduling
7598 ;; of code.
7599 (define_insn "*divmodsi4_nocltd"
7600   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7601         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7602                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7603    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7604         (mod:SI (match_dup 2) (match_dup 3)))
7605    (clobber (reg:CC FLAGS_REG))]
7606   "!optimize_size && !TARGET_USE_CLTD"
7607   "#"
7608   [(set_attr "type" "multi")])
7609
7610 (define_insn "*divmodsi4_cltd"
7611   [(set (match_operand:SI 0 "register_operand" "=a")
7612         (div:SI (match_operand:SI 2 "register_operand" "a")
7613                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7614    (set (match_operand:SI 1 "register_operand" "=&d")
7615         (mod:SI (match_dup 2) (match_dup 3)))
7616    (clobber (reg:CC FLAGS_REG))]
7617   "optimize_size || TARGET_USE_CLTD"
7618   "#"
7619   [(set_attr "type" "multi")])
7620
7621 (define_insn "*divmodsi_noext"
7622   [(set (match_operand:SI 0 "register_operand" "=a")
7623         (div:SI (match_operand:SI 1 "register_operand" "0")
7624                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7625    (set (match_operand:SI 3 "register_operand" "=d")
7626         (mod:SI (match_dup 1) (match_dup 2)))
7627    (use (match_operand:SI 4 "register_operand" "3"))
7628    (clobber (reg:CC FLAGS_REG))]
7629   ""
7630   "idiv{l}\t%2"
7631   [(set_attr "type" "idiv")
7632    (set_attr "mode" "SI")])
7633
7634 (define_split
7635   [(set (match_operand:SI 0 "register_operand" "")
7636         (div:SI (match_operand:SI 1 "register_operand" "")
7637                 (match_operand:SI 2 "nonimmediate_operand" "")))
7638    (set (match_operand:SI 3 "register_operand" "")
7639         (mod:SI (match_dup 1) (match_dup 2)))
7640    (clobber (reg:CC FLAGS_REG))]
7641   "reload_completed"
7642   [(parallel [(set (match_dup 3)
7643                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7644               (clobber (reg:CC FLAGS_REG))])
7645    (parallel [(set (match_dup 0)
7646                    (div:SI (reg:SI 0) (match_dup 2)))
7647               (set (match_dup 3)
7648                    (mod:SI (reg:SI 0) (match_dup 2)))
7649               (use (match_dup 3))
7650               (clobber (reg:CC FLAGS_REG))])]
7651 {
7652   /* Avoid use of cltd in favor of a mov+shift.  */
7653   if (!TARGET_USE_CLTD && !optimize_size)
7654     {
7655       if (true_regnum (operands[1]))
7656         emit_move_insn (operands[0], operands[1]);
7657       else
7658         emit_move_insn (operands[3], operands[1]);
7659       operands[4] = operands[3];
7660     }
7661   else
7662     {
7663       if (true_regnum (operands[1]))
7664         abort();
7665       operands[4] = operands[1];
7666     }
7667 })
7668 ;; %%% Split me.
7669 (define_insn "divmodhi4"
7670   [(set (match_operand:HI 0 "register_operand" "=a")
7671         (div:HI (match_operand:HI 1 "register_operand" "0")
7672                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7673    (set (match_operand:HI 3 "register_operand" "=&d")
7674         (mod:HI (match_dup 1) (match_dup 2)))
7675    (clobber (reg:CC FLAGS_REG))]
7676   "TARGET_HIMODE_MATH"
7677   "cwtd\;idiv{w}\t%2"
7678   [(set_attr "type" "multi")
7679    (set_attr "length_immediate" "0")
7680    (set_attr "mode" "SI")])
7681
7682 (define_insn "udivmoddi4"
7683   [(set (match_operand:DI 0 "register_operand" "=a")
7684         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7685                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7686    (set (match_operand:DI 3 "register_operand" "=&d")
7687         (umod:DI (match_dup 1) (match_dup 2)))
7688    (clobber (reg:CC FLAGS_REG))]
7689   "TARGET_64BIT"
7690   "xor{q}\t%3, %3\;div{q}\t%2"
7691   [(set_attr "type" "multi")
7692    (set_attr "length_immediate" "0")
7693    (set_attr "mode" "DI")])
7694
7695 (define_insn "*udivmoddi4_noext"
7696   [(set (match_operand:DI 0 "register_operand" "=a")
7697         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7698                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7699    (set (match_operand:DI 3 "register_operand" "=d")
7700         (umod:DI (match_dup 1) (match_dup 2)))
7701    (use (match_dup 3))
7702    (clobber (reg:CC FLAGS_REG))]
7703   "TARGET_64BIT"
7704   "div{q}\t%2"
7705   [(set_attr "type" "idiv")
7706    (set_attr "mode" "DI")])
7707
7708 (define_split
7709   [(set (match_operand:DI 0 "register_operand" "")
7710         (udiv:DI (match_operand:DI 1 "register_operand" "")
7711                  (match_operand:DI 2 "nonimmediate_operand" "")))
7712    (set (match_operand:DI 3 "register_operand" "")
7713         (umod:DI (match_dup 1) (match_dup 2)))
7714    (clobber (reg:CC FLAGS_REG))]
7715   "TARGET_64BIT && reload_completed"
7716   [(set (match_dup 3) (const_int 0))
7717    (parallel [(set (match_dup 0)
7718                    (udiv:DI (match_dup 1) (match_dup 2)))
7719               (set (match_dup 3)
7720                    (umod:DI (match_dup 1) (match_dup 2)))
7721               (use (match_dup 3))
7722               (clobber (reg:CC FLAGS_REG))])]
7723   "")
7724
7725 (define_insn "udivmodsi4"
7726   [(set (match_operand:SI 0 "register_operand" "=a")
7727         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7728                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7729    (set (match_operand:SI 3 "register_operand" "=&d")
7730         (umod:SI (match_dup 1) (match_dup 2)))
7731    (clobber (reg:CC FLAGS_REG))]
7732   ""
7733   "xor{l}\t%3, %3\;div{l}\t%2"
7734   [(set_attr "type" "multi")
7735    (set_attr "length_immediate" "0")
7736    (set_attr "mode" "SI")])
7737
7738 (define_insn "*udivmodsi4_noext"
7739   [(set (match_operand:SI 0 "register_operand" "=a")
7740         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7741                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7742    (set (match_operand:SI 3 "register_operand" "=d")
7743         (umod:SI (match_dup 1) (match_dup 2)))
7744    (use (match_dup 3))
7745    (clobber (reg:CC FLAGS_REG))]
7746   ""
7747   "div{l}\t%2"
7748   [(set_attr "type" "idiv")
7749    (set_attr "mode" "SI")])
7750
7751 (define_split
7752   [(set (match_operand:SI 0 "register_operand" "")
7753         (udiv:SI (match_operand:SI 1 "register_operand" "")
7754                  (match_operand:SI 2 "nonimmediate_operand" "")))
7755    (set (match_operand:SI 3 "register_operand" "")
7756         (umod:SI (match_dup 1) (match_dup 2)))
7757    (clobber (reg:CC FLAGS_REG))]
7758   "reload_completed"
7759   [(set (match_dup 3) (const_int 0))
7760    (parallel [(set (match_dup 0)
7761                    (udiv:SI (match_dup 1) (match_dup 2)))
7762               (set (match_dup 3)
7763                    (umod:SI (match_dup 1) (match_dup 2)))
7764               (use (match_dup 3))
7765               (clobber (reg:CC FLAGS_REG))])]
7766   "")
7767
7768 (define_expand "udivmodhi4"
7769   [(set (match_dup 4) (const_int 0))
7770    (parallel [(set (match_operand:HI 0 "register_operand" "")
7771                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7772                             (match_operand:HI 2 "nonimmediate_operand" "")))
7773               (set (match_operand:HI 3 "register_operand" "")
7774                    (umod:HI (match_dup 1) (match_dup 2)))
7775               (use (match_dup 4))
7776               (clobber (reg:CC FLAGS_REG))])]
7777   "TARGET_HIMODE_MATH"
7778   "operands[4] = gen_reg_rtx (HImode);")
7779
7780 (define_insn "*udivmodhi_noext"
7781   [(set (match_operand:HI 0 "register_operand" "=a")
7782         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7783                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7784    (set (match_operand:HI 3 "register_operand" "=d")
7785         (umod:HI (match_dup 1) (match_dup 2)))
7786    (use (match_operand:HI 4 "register_operand" "3"))
7787    (clobber (reg:CC FLAGS_REG))]
7788   ""
7789   "div{w}\t%2"
7790   [(set_attr "type" "idiv")
7791    (set_attr "mode" "HI")])
7792
7793 ;; We cannot use div/idiv for double division, because it causes
7794 ;; "division by zero" on the overflow and that's not what we expect
7795 ;; from truncate.  Because true (non truncating) double division is
7796 ;; never generated, we can't create this insn anyway.
7797 ;
7798 ;(define_insn ""
7799 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7800 ;       (truncate:SI
7801 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7802 ;                  (zero_extend:DI
7803 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7804 ;   (set (match_operand:SI 3 "register_operand" "=d")
7805 ;       (truncate:SI
7806 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7807 ;   (clobber (reg:CC FLAGS_REG))]
7808 ;  ""
7809 ;  "div{l}\t{%2, %0|%0, %2}"
7810 ;  [(set_attr "type" "idiv")])
7811 \f
7812 ;;- Logical AND instructions
7813
7814 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7815 ;; Note that this excludes ah.
7816
7817 (define_insn "*testdi_1_rex64"
7818   [(set (reg 17)
7819         (compare
7820           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7821                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7822           (const_int 0)))]
7823   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7824    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7825   "@
7826    test{l}\t{%k1, %k0|%k0, %k1}
7827    test{l}\t{%k1, %k0|%k0, %k1}
7828    test{q}\t{%1, %0|%0, %1}
7829    test{q}\t{%1, %0|%0, %1}
7830    test{q}\t{%1, %0|%0, %1}"
7831   [(set_attr "type" "test")
7832    (set_attr "modrm" "0,1,0,1,1")
7833    (set_attr "mode" "SI,SI,DI,DI,DI")
7834    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7835
7836 (define_insn "testsi_1"
7837   [(set (reg 17)
7838         (compare
7839           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7840                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7841           (const_int 0)))]
7842   "ix86_match_ccmode (insn, CCNOmode)
7843    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7844   "test{l}\t{%1, %0|%0, %1}"
7845   [(set_attr "type" "test")
7846    (set_attr "modrm" "0,1,1")
7847    (set_attr "mode" "SI")
7848    (set_attr "pent_pair" "uv,np,uv")])
7849
7850 (define_expand "testsi_ccno_1"
7851   [(set (reg:CCNO FLAGS_REG)
7852         (compare:CCNO
7853           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7854                   (match_operand:SI 1 "nonmemory_operand" ""))
7855           (const_int 0)))]
7856   ""
7857   "")
7858
7859 (define_insn "*testhi_1"
7860   [(set (reg 17)
7861         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7862                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7863                  (const_int 0)))]
7864   "ix86_match_ccmode (insn, CCNOmode)
7865    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7866   "test{w}\t{%1, %0|%0, %1}"
7867   [(set_attr "type" "test")
7868    (set_attr "modrm" "0,1,1")
7869    (set_attr "mode" "HI")
7870    (set_attr "pent_pair" "uv,np,uv")])
7871
7872 (define_expand "testqi_ccz_1"
7873   [(set (reg:CCZ FLAGS_REG)
7874         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7875                              (match_operand:QI 1 "nonmemory_operand" ""))
7876                  (const_int 0)))]
7877   ""
7878   "")
7879
7880 (define_insn "*testqi_1"
7881   [(set (reg 17)
7882         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7883                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7884                  (const_int 0)))]
7885   "ix86_match_ccmode (insn, CCNOmode)
7886    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7887 {
7888   if (which_alternative == 3)
7889     {
7890       if (GET_CODE (operands[1]) == CONST_INT
7891           && (INTVAL (operands[1]) & 0xffffff00))
7892         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7893       return "test{l}\t{%1, %k0|%k0, %1}";
7894     }
7895   return "test{b}\t{%1, %0|%0, %1}";
7896 }
7897   [(set_attr "type" "test")
7898    (set_attr "modrm" "0,1,1,1")
7899    (set_attr "mode" "QI,QI,QI,SI")
7900    (set_attr "pent_pair" "uv,np,uv,np")])
7901
7902 (define_expand "testqi_ext_ccno_0"
7903   [(set (reg:CCNO FLAGS_REG)
7904         (compare:CCNO
7905           (and:SI
7906             (zero_extract:SI
7907               (match_operand 0 "ext_register_operand" "")
7908               (const_int 8)
7909               (const_int 8))
7910             (match_operand 1 "const_int_operand" ""))
7911           (const_int 0)))]
7912   ""
7913   "")
7914
7915 (define_insn "*testqi_ext_0"
7916   [(set (reg 17)
7917         (compare
7918           (and:SI
7919             (zero_extract:SI
7920               (match_operand 0 "ext_register_operand" "Q")
7921               (const_int 8)
7922               (const_int 8))
7923             (match_operand 1 "const_int_operand" "n"))
7924           (const_int 0)))]
7925   "ix86_match_ccmode (insn, CCNOmode)"
7926   "test{b}\t{%1, %h0|%h0, %1}"
7927   [(set_attr "type" "test")
7928    (set_attr "mode" "QI")
7929    (set_attr "length_immediate" "1")
7930    (set_attr "pent_pair" "np")])
7931
7932 (define_insn "*testqi_ext_1"
7933   [(set (reg 17)
7934         (compare
7935           (and:SI
7936             (zero_extract:SI
7937               (match_operand 0 "ext_register_operand" "Q")
7938               (const_int 8)
7939               (const_int 8))
7940             (zero_extend:SI
7941               (match_operand:QI 1 "general_operand" "Qm")))
7942           (const_int 0)))]
7943   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7944    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7945   "test{b}\t{%1, %h0|%h0, %1}"
7946   [(set_attr "type" "test")
7947    (set_attr "mode" "QI")])
7948
7949 (define_insn "*testqi_ext_1_rex64"
7950   [(set (reg 17)
7951         (compare
7952           (and:SI
7953             (zero_extract:SI
7954               (match_operand 0 "ext_register_operand" "Q")
7955               (const_int 8)
7956               (const_int 8))
7957             (zero_extend:SI
7958               (match_operand:QI 1 "register_operand" "Q")))
7959           (const_int 0)))]
7960   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7961   "test{b}\t{%1, %h0|%h0, %1}"
7962   [(set_attr "type" "test")
7963    (set_attr "mode" "QI")])
7964
7965 (define_insn "*testqi_ext_2"
7966   [(set (reg 17)
7967         (compare
7968           (and:SI
7969             (zero_extract:SI
7970               (match_operand 0 "ext_register_operand" "Q")
7971               (const_int 8)
7972               (const_int 8))
7973             (zero_extract:SI
7974               (match_operand 1 "ext_register_operand" "Q")
7975               (const_int 8)
7976               (const_int 8)))
7977           (const_int 0)))]
7978   "ix86_match_ccmode (insn, CCNOmode)"
7979   "test{b}\t{%h1, %h0|%h0, %h1}"
7980   [(set_attr "type" "test")
7981    (set_attr "mode" "QI")])
7982
7983 ;; Combine likes to form bit extractions for some tests.  Humor it.
7984 (define_insn "*testqi_ext_3"
7985   [(set (reg 17)
7986         (compare (zero_extract:SI
7987                    (match_operand 0 "nonimmediate_operand" "rm")
7988                    (match_operand:SI 1 "const_int_operand" "")
7989                    (match_operand:SI 2 "const_int_operand" ""))
7990                  (const_int 0)))]
7991   "ix86_match_ccmode (insn, CCNOmode)
7992    && (GET_MODE (operands[0]) == SImode
7993        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7994        || GET_MODE (operands[0]) == HImode
7995        || GET_MODE (operands[0]) == QImode)"
7996   "#")
7997
7998 (define_insn "*testqi_ext_3_rex64"
7999   [(set (reg 17)
8000         (compare (zero_extract:DI
8001                    (match_operand 0 "nonimmediate_operand" "rm")
8002                    (match_operand:DI 1 "const_int_operand" "")
8003                    (match_operand:DI 2 "const_int_operand" ""))
8004                  (const_int 0)))]
8005   "TARGET_64BIT
8006    && ix86_match_ccmode (insn, CCNOmode)
8007    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8008    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8009    /* Ensure that resulting mask is zero or sign extended operand.  */
8010    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8011        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8012            && INTVAL (operands[1]) > 32))
8013    && (GET_MODE (operands[0]) == SImode
8014        || GET_MODE (operands[0]) == DImode
8015        || GET_MODE (operands[0]) == HImode
8016        || GET_MODE (operands[0]) == QImode)"
8017   "#")
8018
8019 (define_split
8020   [(set (reg 17)
8021         (compare (zero_extract
8022                    (match_operand 0 "nonimmediate_operand" "")
8023                    (match_operand 1 "const_int_operand" "")
8024                    (match_operand 2 "const_int_operand" ""))
8025                  (const_int 0)))]
8026   "ix86_match_ccmode (insn, CCNOmode)"
8027   [(set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
8028 {
8029   HOST_WIDE_INT len = INTVAL (operands[1]);
8030   HOST_WIDE_INT pos = INTVAL (operands[2]);
8031   HOST_WIDE_INT mask;
8032   enum machine_mode mode, submode;
8033
8034   mode = GET_MODE (operands[0]);
8035   if (GET_CODE (operands[0]) == MEM)
8036     {
8037       /* ??? Combine likes to put non-volatile mem extractions in QImode
8038          no matter the size of the test.  So find a mode that works.  */
8039       if (! MEM_VOLATILE_P (operands[0]))
8040         {
8041           mode = smallest_mode_for_size (pos + len, MODE_INT);
8042           operands[0] = adjust_address (operands[0], mode, 0);
8043         }
8044     }
8045   else if (GET_CODE (operands[0]) == SUBREG
8046            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8047                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8048            && pos + len <= GET_MODE_BITSIZE (submode))
8049     {
8050       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8051       mode = submode;
8052       operands[0] = SUBREG_REG (operands[0]);
8053     }
8054   else if (mode == HImode && pos + len <= 8)
8055     {
8056       /* Small HImode tests can be converted to QImode.  */
8057       mode = QImode;
8058       operands[0] = gen_lowpart (QImode, operands[0]);
8059     }
8060
8061   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8062   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8063
8064   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8065 })
8066
8067 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8068 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8069 ;; this is relatively important trick.
8070 ;; Do the conversion only post-reload to avoid limiting of the register class
8071 ;; to QI regs.
8072 (define_split
8073   [(set (reg 17)
8074         (compare
8075           (and (match_operand 0 "register_operand" "")
8076                (match_operand 1 "const_int_operand" ""))
8077           (const_int 0)))]
8078    "reload_completed
8079     && QI_REG_P (operands[0])
8080     && ((ix86_match_ccmode (insn, CCZmode)
8081          && !(INTVAL (operands[1]) & ~(255 << 8)))
8082         || (ix86_match_ccmode (insn, CCNOmode)
8083             && !(INTVAL (operands[1]) & ~(127 << 8))))
8084     && GET_MODE (operands[0]) != QImode"
8085   [(set (reg:CCNO FLAGS_REG)
8086         (compare:CCNO
8087           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8088                   (match_dup 1))
8089           (const_int 0)))]
8090   "operands[0] = gen_lowpart (SImode, operands[0]);
8091    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8092
8093 (define_split
8094   [(set (reg 17)
8095         (compare
8096           (and (match_operand 0 "nonimmediate_operand" "")
8097                (match_operand 1 "const_int_operand" ""))
8098           (const_int 0)))]
8099    "reload_completed
8100     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8101     && ((ix86_match_ccmode (insn, CCZmode)
8102          && !(INTVAL (operands[1]) & ~255))
8103         || (ix86_match_ccmode (insn, CCNOmode)
8104             && !(INTVAL (operands[1]) & ~127)))
8105     && GET_MODE (operands[0]) != QImode"
8106   [(set (reg:CCNO FLAGS_REG)
8107         (compare:CCNO
8108           (and:QI (match_dup 0)
8109                   (match_dup 1))
8110           (const_int 0)))]
8111   "operands[0] = gen_lowpart (QImode, operands[0]);
8112    operands[1] = gen_lowpart (QImode, operands[1]);")
8113
8114
8115 ;; %%% This used to optimize known byte-wide and operations to memory,
8116 ;; and sometimes to QImode registers.  If this is considered useful,
8117 ;; it should be done with splitters.
8118
8119 (define_expand "anddi3"
8120   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8121         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8122                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8123    (clobber (reg:CC FLAGS_REG))]
8124   "TARGET_64BIT"
8125   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8126
8127 (define_insn "*anddi_1_rex64"
8128   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8129         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8130                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8131    (clobber (reg:CC FLAGS_REG))]
8132   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8133 {
8134   switch (get_attr_type (insn))
8135     {
8136     case TYPE_IMOVX:
8137       {
8138         enum machine_mode mode;
8139
8140         if (GET_CODE (operands[2]) != CONST_INT)
8141           abort ();
8142         if (INTVAL (operands[2]) == 0xff)
8143           mode = QImode;
8144         else if (INTVAL (operands[2]) == 0xffff)
8145           mode = HImode;
8146         else
8147           abort ();
8148         
8149         operands[1] = gen_lowpart (mode, operands[1]);
8150         if (mode == QImode)
8151           return "movz{bq|x}\t{%1,%0|%0, %1}";
8152         else
8153           return "movz{wq|x}\t{%1,%0|%0, %1}";
8154       }
8155
8156     default:
8157       if (! rtx_equal_p (operands[0], operands[1]))
8158         abort ();
8159       if (get_attr_mode (insn) == MODE_SI)
8160         return "and{l}\t{%k2, %k0|%k0, %k2}";
8161       else
8162         return "and{q}\t{%2, %0|%0, %2}";
8163     }
8164 }
8165   [(set_attr "type" "alu,alu,alu,imovx")
8166    (set_attr "length_immediate" "*,*,*,0")
8167    (set_attr "mode" "SI,DI,DI,DI")])
8168
8169 (define_insn "*anddi_2"
8170   [(set (reg 17)
8171         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8172                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8173                  (const_int 0)))
8174    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8175         (and:DI (match_dup 1) (match_dup 2)))]
8176   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8177    && ix86_binary_operator_ok (AND, DImode, operands)"
8178   "@
8179    and{l}\t{%k2, %k0|%k0, %k2}
8180    and{q}\t{%2, %0|%0, %2}
8181    and{q}\t{%2, %0|%0, %2}"
8182   [(set_attr "type" "alu")
8183    (set_attr "mode" "SI,DI,DI")])
8184
8185 (define_expand "andsi3"
8186   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8187         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8188                 (match_operand:SI 2 "general_operand" "")))
8189    (clobber (reg:CC FLAGS_REG))]
8190   ""
8191   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8192
8193 (define_insn "*andsi_1"
8194   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8195         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8196                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8197    (clobber (reg:CC FLAGS_REG))]
8198   "ix86_binary_operator_ok (AND, SImode, operands)"
8199 {
8200   switch (get_attr_type (insn))
8201     {
8202     case TYPE_IMOVX:
8203       {
8204         enum machine_mode mode;
8205
8206         if (GET_CODE (operands[2]) != CONST_INT)
8207           abort ();
8208         if (INTVAL (operands[2]) == 0xff)
8209           mode = QImode;
8210         else if (INTVAL (operands[2]) == 0xffff)
8211           mode = HImode;
8212         else
8213           abort ();
8214         
8215         operands[1] = gen_lowpart (mode, operands[1]);
8216         if (mode == QImode)
8217           return "movz{bl|x}\t{%1,%0|%0, %1}";
8218         else
8219           return "movz{wl|x}\t{%1,%0|%0, %1}";
8220       }
8221
8222     default:
8223       if (! rtx_equal_p (operands[0], operands[1]))
8224         abort ();
8225       return "and{l}\t{%2, %0|%0, %2}";
8226     }
8227 }
8228   [(set_attr "type" "alu,alu,imovx")
8229    (set_attr "length_immediate" "*,*,0")
8230    (set_attr "mode" "SI")])
8231
8232 (define_split
8233   [(set (match_operand 0 "register_operand" "")
8234         (and (match_dup 0)
8235              (const_int -65536)))
8236    (clobber (reg:CC FLAGS_REG))]
8237   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8238   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8239   "operands[1] = gen_lowpart (HImode, operands[0]);")
8240
8241 (define_split
8242   [(set (match_operand 0 "ext_register_operand" "")
8243         (and (match_dup 0)
8244              (const_int -256)))
8245    (clobber (reg:CC FLAGS_REG))]
8246   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8247   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8248   "operands[1] = gen_lowpart (QImode, operands[0]);")
8249
8250 (define_split
8251   [(set (match_operand 0 "ext_register_operand" "")
8252         (and (match_dup 0)
8253              (const_int -65281)))
8254    (clobber (reg:CC FLAGS_REG))]
8255   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8256   [(parallel [(set (zero_extract:SI (match_dup 0)
8257                                     (const_int 8)
8258                                     (const_int 8))
8259                    (xor:SI 
8260                      (zero_extract:SI (match_dup 0)
8261                                       (const_int 8)
8262                                       (const_int 8))
8263                      (zero_extract:SI (match_dup 0)
8264                                       (const_int 8)
8265                                       (const_int 8))))
8266               (clobber (reg:CC FLAGS_REG))])]
8267   "operands[0] = gen_lowpart (SImode, operands[0]);")
8268
8269 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8270 (define_insn "*andsi_1_zext"
8271   [(set (match_operand:DI 0 "register_operand" "=r")
8272         (zero_extend:DI
8273           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8274                   (match_operand:SI 2 "general_operand" "rim"))))
8275    (clobber (reg:CC FLAGS_REG))]
8276   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8277   "and{l}\t{%2, %k0|%k0, %2}"
8278   [(set_attr "type" "alu")
8279    (set_attr "mode" "SI")])
8280
8281 (define_insn "*andsi_2"
8282   [(set (reg 17)
8283         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8284                          (match_operand:SI 2 "general_operand" "rim,ri"))
8285                  (const_int 0)))
8286    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8287         (and:SI (match_dup 1) (match_dup 2)))]
8288   "ix86_match_ccmode (insn, CCNOmode)
8289    && ix86_binary_operator_ok (AND, SImode, operands)"
8290   "and{l}\t{%2, %0|%0, %2}"
8291   [(set_attr "type" "alu")
8292    (set_attr "mode" "SI")])
8293
8294 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8295 (define_insn "*andsi_2_zext"
8296   [(set (reg 17)
8297         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8298                          (match_operand:SI 2 "general_operand" "rim"))
8299                  (const_int 0)))
8300    (set (match_operand:DI 0 "register_operand" "=r")
8301         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8302   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8303    && ix86_binary_operator_ok (AND, SImode, operands)"
8304   "and{l}\t{%2, %k0|%k0, %2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "SI")])
8307
8308 (define_expand "andhi3"
8309   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8310         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8311                 (match_operand:HI 2 "general_operand" "")))
8312    (clobber (reg:CC FLAGS_REG))]
8313   "TARGET_HIMODE_MATH"
8314   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8315
8316 (define_insn "*andhi_1"
8317   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8318         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8319                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8320    (clobber (reg:CC FLAGS_REG))]
8321   "ix86_binary_operator_ok (AND, HImode, operands)"
8322 {
8323   switch (get_attr_type (insn))
8324     {
8325     case TYPE_IMOVX:
8326       if (GET_CODE (operands[2]) != CONST_INT)
8327         abort ();
8328       if (INTVAL (operands[2]) == 0xff)
8329         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8330       abort ();
8331
8332     default:
8333       if (! rtx_equal_p (operands[0], operands[1]))
8334         abort ();
8335
8336       return "and{w}\t{%2, %0|%0, %2}";
8337     }
8338 }
8339   [(set_attr "type" "alu,alu,imovx")
8340    (set_attr "length_immediate" "*,*,0")
8341    (set_attr "mode" "HI,HI,SI")])
8342
8343 (define_insn "*andhi_2"
8344   [(set (reg 17)
8345         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8346                          (match_operand:HI 2 "general_operand" "rim,ri"))
8347                  (const_int 0)))
8348    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8349         (and:HI (match_dup 1) (match_dup 2)))]
8350   "ix86_match_ccmode (insn, CCNOmode)
8351    && ix86_binary_operator_ok (AND, HImode, operands)"
8352   "and{w}\t{%2, %0|%0, %2}"
8353   [(set_attr "type" "alu")
8354    (set_attr "mode" "HI")])
8355
8356 (define_expand "andqi3"
8357   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8358         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8359                 (match_operand:QI 2 "general_operand" "")))
8360    (clobber (reg:CC FLAGS_REG))]
8361   "TARGET_QIMODE_MATH"
8362   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8363
8364 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8365 (define_insn "*andqi_1"
8366   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8367         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8368                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8369    (clobber (reg:CC FLAGS_REG))]
8370   "ix86_binary_operator_ok (AND, QImode, operands)"
8371   "@
8372    and{b}\t{%2, %0|%0, %2}
8373    and{b}\t{%2, %0|%0, %2}
8374    and{l}\t{%k2, %k0|%k0, %k2}"
8375   [(set_attr "type" "alu")
8376    (set_attr "mode" "QI,QI,SI")])
8377
8378 (define_insn "*andqi_1_slp"
8379   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8380         (and:QI (match_dup 0)
8381                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8382    (clobber (reg:CC FLAGS_REG))]
8383   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8384    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8385   "and{b}\t{%1, %0|%0, %1}"
8386   [(set_attr "type" "alu1")
8387    (set_attr "mode" "QI")])
8388
8389 (define_insn "*andqi_2"
8390   [(set (reg 17)
8391         (compare (and:QI
8392                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8393                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8394                  (const_int 0)))
8395    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8396         (and:QI (match_dup 1) (match_dup 2)))]
8397   "ix86_match_ccmode (insn, CCNOmode)
8398    && ix86_binary_operator_ok (AND, QImode, operands)"
8399 {
8400   if (which_alternative == 2)
8401     {
8402       if (GET_CODE (operands[2]) == CONST_INT
8403           && (INTVAL (operands[2]) & 0xffffff00))
8404         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8405       return "and{l}\t{%2, %k0|%k0, %2}";
8406     }
8407   return "and{b}\t{%2, %0|%0, %2}";
8408 }
8409   [(set_attr "type" "alu")
8410    (set_attr "mode" "QI,QI,SI")])
8411
8412 (define_insn "*andqi_2_slp"
8413   [(set (reg 17)
8414         (compare (and:QI
8415                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8416                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8417                  (const_int 0)))
8418    (set (strict_low_part (match_dup 0))
8419         (and:QI (match_dup 0) (match_dup 1)))]
8420   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8421    && ix86_match_ccmode (insn, CCNOmode)
8422    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8423   "and{b}\t{%1, %0|%0, %1}"
8424   [(set_attr "type" "alu1")
8425    (set_attr "mode" "QI")])
8426
8427 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8428 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8429 ;; for a QImode operand, which of course failed.
8430
8431 (define_insn "andqi_ext_0"
8432   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8433                          (const_int 8)
8434                          (const_int 8))
8435         (and:SI 
8436           (zero_extract:SI
8437             (match_operand 1 "ext_register_operand" "0")
8438             (const_int 8)
8439             (const_int 8))
8440           (match_operand 2 "const_int_operand" "n")))
8441    (clobber (reg:CC FLAGS_REG))]
8442   ""
8443   "and{b}\t{%2, %h0|%h0, %2}"
8444   [(set_attr "type" "alu")
8445    (set_attr "length_immediate" "1")
8446    (set_attr "mode" "QI")])
8447
8448 ;; Generated by peephole translating test to and.  This shows up
8449 ;; often in fp comparisons.
8450
8451 (define_insn "*andqi_ext_0_cc"
8452   [(set (reg 17)
8453         (compare
8454           (and:SI
8455             (zero_extract:SI
8456               (match_operand 1 "ext_register_operand" "0")
8457               (const_int 8)
8458               (const_int 8))
8459             (match_operand 2 "const_int_operand" "n"))
8460           (const_int 0)))
8461    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462                          (const_int 8)
8463                          (const_int 8))
8464         (and:SI 
8465           (zero_extract:SI
8466             (match_dup 1)
8467             (const_int 8)
8468             (const_int 8))
8469           (match_dup 2)))]
8470   "ix86_match_ccmode (insn, CCNOmode)"
8471   "and{b}\t{%2, %h0|%h0, %2}"
8472   [(set_attr "type" "alu")
8473    (set_attr "length_immediate" "1")
8474    (set_attr "mode" "QI")])
8475
8476 (define_insn "*andqi_ext_1"
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:QI 2 "general_operand" "Qm"))))
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_1_rex64"
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_extend:SI
8504             (match_operand 2 "ext_register_operand" "Q"))))
8505    (clobber (reg:CC FLAGS_REG))]
8506   "TARGET_64BIT"
8507   "and{b}\t{%2, %h0|%h0, %2}"
8508   [(set_attr "type" "alu")
8509    (set_attr "length_immediate" "0")
8510    (set_attr "mode" "QI")])
8511
8512 (define_insn "*andqi_ext_2"
8513   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8514                          (const_int 8)
8515                          (const_int 8))
8516         (and:SI
8517           (zero_extract:SI
8518             (match_operand 1 "ext_register_operand" "%0")
8519             (const_int 8)
8520             (const_int 8))
8521           (zero_extract:SI
8522             (match_operand 2 "ext_register_operand" "Q")
8523             (const_int 8)
8524             (const_int 8))))
8525    (clobber (reg:CC FLAGS_REG))]
8526   ""
8527   "and{b}\t{%h2, %h0|%h0, %h2}"
8528   [(set_attr "type" "alu")
8529    (set_attr "length_immediate" "0")
8530    (set_attr "mode" "QI")])
8531
8532 ;; Convert wide AND instructions with immediate operand to shorter QImode
8533 ;; equivalents when possible.
8534 ;; Don't do the splitting with memory operands, since it introduces risk
8535 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8536 ;; for size, but that can (should?) be handled by generic code instead.
8537 (define_split
8538   [(set (match_operand 0 "register_operand" "")
8539         (and (match_operand 1 "register_operand" "")
8540              (match_operand 2 "const_int_operand" "")))
8541    (clobber (reg:CC FLAGS_REG))]
8542    "reload_completed
8543     && QI_REG_P (operands[0])
8544     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8545     && !(~INTVAL (operands[2]) & ~(255 << 8))
8546     && GET_MODE (operands[0]) != QImode"
8547   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8548                    (and:SI (zero_extract:SI (match_dup 1)
8549                                             (const_int 8) (const_int 8))
8550                            (match_dup 2)))
8551               (clobber (reg:CC FLAGS_REG))])]
8552   "operands[0] = gen_lowpart (SImode, operands[0]);
8553    operands[1] = gen_lowpart (SImode, operands[1]);
8554    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8555
8556 ;; Since AND can be encoded with sign extended immediate, this is only
8557 ;; profitable when 7th bit is not set.
8558 (define_split
8559   [(set (match_operand 0 "register_operand" "")
8560         (and (match_operand 1 "general_operand" "")
8561              (match_operand 2 "const_int_operand" "")))
8562    (clobber (reg:CC FLAGS_REG))]
8563    "reload_completed
8564     && ANY_QI_REG_P (operands[0])
8565     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8566     && !(~INTVAL (operands[2]) & ~255)
8567     && !(INTVAL (operands[2]) & 128)
8568     && GET_MODE (operands[0]) != QImode"
8569   [(parallel [(set (strict_low_part (match_dup 0))
8570                    (and:QI (match_dup 1)
8571                            (match_dup 2)))
8572               (clobber (reg:CC FLAGS_REG))])]
8573   "operands[0] = gen_lowpart (QImode, operands[0]);
8574    operands[1] = gen_lowpart (QImode, operands[1]);
8575    operands[2] = gen_lowpart (QImode, operands[2]);")
8576 \f
8577 ;; Logical inclusive OR instructions
8578
8579 ;; %%% This used to optimize known byte-wide and operations to memory.
8580 ;; If this is considered useful, it should be done with splitters.
8581
8582 (define_expand "iordi3"
8583   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8584         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8585                 (match_operand:DI 2 "x86_64_general_operand" "")))
8586    (clobber (reg:CC FLAGS_REG))]
8587   "TARGET_64BIT"
8588   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8589
8590 (define_insn "*iordi_1_rex64"
8591   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8592         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8593                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8594    (clobber (reg:CC FLAGS_REG))]
8595   "TARGET_64BIT
8596    && ix86_binary_operator_ok (IOR, DImode, operands)"
8597   "or{q}\t{%2, %0|%0, %2}"
8598   [(set_attr "type" "alu")
8599    (set_attr "mode" "DI")])
8600
8601 (define_insn "*iordi_2_rex64"
8602   [(set (reg 17)
8603         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8604                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8605                  (const_int 0)))
8606    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8607         (ior:DI (match_dup 1) (match_dup 2)))]
8608   "TARGET_64BIT
8609    && ix86_match_ccmode (insn, CCNOmode)
8610    && ix86_binary_operator_ok (IOR, DImode, operands)"
8611   "or{q}\t{%2, %0|%0, %2}"
8612   [(set_attr "type" "alu")
8613    (set_attr "mode" "DI")])
8614
8615 (define_insn "*iordi_3_rex64"
8616   [(set (reg 17)
8617         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8618                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8619                  (const_int 0)))
8620    (clobber (match_scratch:DI 0 "=r"))]
8621   "TARGET_64BIT
8622    && ix86_match_ccmode (insn, CCNOmode)
8623    && ix86_binary_operator_ok (IOR, DImode, operands)"
8624   "or{q}\t{%2, %0|%0, %2}"
8625   [(set_attr "type" "alu")
8626    (set_attr "mode" "DI")])
8627
8628
8629 (define_expand "iorsi3"
8630   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8631         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8632                 (match_operand:SI 2 "general_operand" "")))
8633    (clobber (reg:CC FLAGS_REG))]
8634   ""
8635   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8636
8637 (define_insn "*iorsi_1"
8638   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8639         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8640                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8641    (clobber (reg:CC FLAGS_REG))]
8642   "ix86_binary_operator_ok (IOR, SImode, operands)"
8643   "or{l}\t{%2, %0|%0, %2}"
8644   [(set_attr "type" "alu")
8645    (set_attr "mode" "SI")])
8646
8647 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8648 (define_insn "*iorsi_1_zext"
8649   [(set (match_operand:DI 0 "register_operand" "=rm")
8650         (zero_extend:DI
8651           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8652                   (match_operand:SI 2 "general_operand" "rim"))))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8655   "or{l}\t{%2, %k0|%k0, %2}"
8656   [(set_attr "type" "alu")
8657    (set_attr "mode" "SI")])
8658
8659 (define_insn "*iorsi_1_zext_imm"
8660   [(set (match_operand:DI 0 "register_operand" "=rm")
8661         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8662                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8663    (clobber (reg:CC FLAGS_REG))]
8664   "TARGET_64BIT"
8665   "or{l}\t{%2, %k0|%k0, %2}"
8666   [(set_attr "type" "alu")
8667    (set_attr "mode" "SI")])
8668
8669 (define_insn "*iorsi_2"
8670   [(set (reg 17)
8671         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8672                          (match_operand:SI 2 "general_operand" "rim,ri"))
8673                  (const_int 0)))
8674    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8675         (ior:SI (match_dup 1) (match_dup 2)))]
8676   "ix86_match_ccmode (insn, CCNOmode)
8677    && ix86_binary_operator_ok (IOR, SImode, operands)"
8678   "or{l}\t{%2, %0|%0, %2}"
8679   [(set_attr "type" "alu")
8680    (set_attr "mode" "SI")])
8681
8682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8683 ;; ??? Special case for immediate operand is missing - it is tricky.
8684 (define_insn "*iorsi_2_zext"
8685   [(set (reg 17)
8686         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8687                          (match_operand:SI 2 "general_operand" "rim"))
8688                  (const_int 0)))
8689    (set (match_operand:DI 0 "register_operand" "=r")
8690         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8691   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8692    && ix86_binary_operator_ok (IOR, SImode, operands)"
8693   "or{l}\t{%2, %k0|%k0, %2}"
8694   [(set_attr "type" "alu")
8695    (set_attr "mode" "SI")])
8696
8697 (define_insn "*iorsi_2_zext_imm"
8698   [(set (reg 17)
8699         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8700                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8701                  (const_int 0)))
8702    (set (match_operand:DI 0 "register_operand" "=r")
8703         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8704   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8705    && ix86_binary_operator_ok (IOR, SImode, operands)"
8706   "or{l}\t{%2, %k0|%k0, %2}"
8707   [(set_attr "type" "alu")
8708    (set_attr "mode" "SI")])
8709
8710 (define_insn "*iorsi_3"
8711   [(set (reg 17)
8712         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8713                          (match_operand:SI 2 "general_operand" "rim"))
8714                  (const_int 0)))
8715    (clobber (match_scratch:SI 0 "=r"))]
8716   "ix86_match_ccmode (insn, CCNOmode)
8717    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8718   "or{l}\t{%2, %0|%0, %2}"
8719   [(set_attr "type" "alu")
8720    (set_attr "mode" "SI")])
8721
8722 (define_expand "iorhi3"
8723   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8724         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8725                 (match_operand:HI 2 "general_operand" "")))
8726    (clobber (reg:CC FLAGS_REG))]
8727   "TARGET_HIMODE_MATH"
8728   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8729
8730 (define_insn "*iorhi_1"
8731   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8732         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8733                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8734    (clobber (reg:CC FLAGS_REG))]
8735   "ix86_binary_operator_ok (IOR, HImode, operands)"
8736   "or{w}\t{%2, %0|%0, %2}"
8737   [(set_attr "type" "alu")
8738    (set_attr "mode" "HI")])
8739
8740 (define_insn "*iorhi_2"
8741   [(set (reg 17)
8742         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8743                          (match_operand:HI 2 "general_operand" "rim,ri"))
8744                  (const_int 0)))
8745    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8746         (ior:HI (match_dup 1) (match_dup 2)))]
8747   "ix86_match_ccmode (insn, CCNOmode)
8748    && ix86_binary_operator_ok (IOR, HImode, operands)"
8749   "or{w}\t{%2, %0|%0, %2}"
8750   [(set_attr "type" "alu")
8751    (set_attr "mode" "HI")])
8752
8753 (define_insn "*iorhi_3"
8754   [(set (reg 17)
8755         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8756                          (match_operand:HI 2 "general_operand" "rim"))
8757                  (const_int 0)))
8758    (clobber (match_scratch:HI 0 "=r"))]
8759   "ix86_match_ccmode (insn, CCNOmode)
8760    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8761   "or{w}\t{%2, %0|%0, %2}"
8762   [(set_attr "type" "alu")
8763    (set_attr "mode" "HI")])
8764
8765 (define_expand "iorqi3"
8766   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8767         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8768                 (match_operand:QI 2 "general_operand" "")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "TARGET_QIMODE_MATH"
8771   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8772
8773 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8774 (define_insn "*iorqi_1"
8775   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8776         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8777                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8778    (clobber (reg:CC FLAGS_REG))]
8779   "ix86_binary_operator_ok (IOR, QImode, operands)"
8780   "@
8781    or{b}\t{%2, %0|%0, %2}
8782    or{b}\t{%2, %0|%0, %2}
8783    or{l}\t{%k2, %k0|%k0, %k2}"
8784   [(set_attr "type" "alu")
8785    (set_attr "mode" "QI,QI,SI")])
8786
8787 (define_insn "*iorqi_1_slp"
8788   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8789         (ior:QI (match_dup 0)
8790                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8793    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8794   "or{b}\t{%1, %0|%0, %1}"
8795   [(set_attr "type" "alu1")
8796    (set_attr "mode" "QI")])
8797
8798 (define_insn "*iorqi_2"
8799   [(set (reg 17)
8800         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8801                          (match_operand:QI 2 "general_operand" "qim,qi"))
8802                  (const_int 0)))
8803    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8804         (ior:QI (match_dup 1) (match_dup 2)))]
8805   "ix86_match_ccmode (insn, CCNOmode)
8806    && ix86_binary_operator_ok (IOR, QImode, operands)"
8807   "or{b}\t{%2, %0|%0, %2}"
8808   [(set_attr "type" "alu")
8809    (set_attr "mode" "QI")])
8810
8811 (define_insn "*iorqi_2_slp"
8812   [(set (reg 17)
8813         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8814                          (match_operand:QI 1 "general_operand" "qim,qi"))
8815                  (const_int 0)))
8816    (set (strict_low_part (match_dup 0))
8817         (ior:QI (match_dup 0) (match_dup 1)))]
8818   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8819    && ix86_match_ccmode (insn, CCNOmode)
8820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8821   "or{b}\t{%1, %0|%0, %1}"
8822   [(set_attr "type" "alu1")
8823    (set_attr "mode" "QI")])
8824
8825 (define_insn "*iorqi_3"
8826   [(set (reg 17)
8827         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8828                          (match_operand:QI 2 "general_operand" "qim"))
8829                  (const_int 0)))
8830    (clobber (match_scratch:QI 0 "=q"))]
8831   "ix86_match_ccmode (insn, CCNOmode)
8832    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8833   "or{b}\t{%2, %0|%0, %2}"
8834   [(set_attr "type" "alu")
8835    (set_attr "mode" "QI")])
8836
8837 (define_insn "iorqi_ext_0"
8838   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8839                          (const_int 8)
8840                          (const_int 8))
8841         (ior:SI 
8842           (zero_extract:SI
8843             (match_operand 1 "ext_register_operand" "0")
8844             (const_int 8)
8845             (const_int 8))
8846           (match_operand 2 "const_int_operand" "n")))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8849   "or{b}\t{%2, %h0|%h0, %2}"
8850   [(set_attr "type" "alu")
8851    (set_attr "length_immediate" "1")
8852    (set_attr "mode" "QI")])
8853
8854 (define_insn "*iorqi_ext_1"
8855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8856                          (const_int 8)
8857                          (const_int 8))
8858         (ior:SI 
8859           (zero_extract:SI
8860             (match_operand 1 "ext_register_operand" "0")
8861             (const_int 8)
8862             (const_int 8))
8863           (zero_extend:SI
8864             (match_operand:QI 2 "general_operand" "Qm"))))
8865    (clobber (reg:CC FLAGS_REG))]
8866   "!TARGET_64BIT
8867    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8868   "or{b}\t{%2, %h0|%h0, %2}"
8869   [(set_attr "type" "alu")
8870    (set_attr "length_immediate" "0")
8871    (set_attr "mode" "QI")])
8872
8873 (define_insn "*iorqi_ext_1_rex64"
8874   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8875                          (const_int 8)
8876                          (const_int 8))
8877         (ior:SI 
8878           (zero_extract:SI
8879             (match_operand 1 "ext_register_operand" "0")
8880             (const_int 8)
8881             (const_int 8))
8882           (zero_extend:SI
8883             (match_operand 2 "ext_register_operand" "Q"))))
8884    (clobber (reg:CC FLAGS_REG))]
8885   "TARGET_64BIT
8886    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8887   "or{b}\t{%2, %h0|%h0, %2}"
8888   [(set_attr "type" "alu")
8889    (set_attr "length_immediate" "0")
8890    (set_attr "mode" "QI")])
8891
8892 (define_insn "*iorqi_ext_2"
8893   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8894                          (const_int 8)
8895                          (const_int 8))
8896         (ior:SI 
8897           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8898                            (const_int 8)
8899                            (const_int 8))
8900           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8901                            (const_int 8)
8902                            (const_int 8))))
8903    (clobber (reg:CC FLAGS_REG))]
8904   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8905   "ior{b}\t{%h2, %h0|%h0, %h2}"
8906   [(set_attr "type" "alu")
8907    (set_attr "length_immediate" "0")
8908    (set_attr "mode" "QI")])
8909
8910 (define_split
8911   [(set (match_operand 0 "register_operand" "")
8912         (ior (match_operand 1 "register_operand" "")
8913              (match_operand 2 "const_int_operand" "")))
8914    (clobber (reg:CC FLAGS_REG))]
8915    "reload_completed
8916     && QI_REG_P (operands[0])
8917     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8918     && !(INTVAL (operands[2]) & ~(255 << 8))
8919     && GET_MODE (operands[0]) != QImode"
8920   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8921                    (ior:SI (zero_extract:SI (match_dup 1)
8922                                             (const_int 8) (const_int 8))
8923                            (match_dup 2)))
8924               (clobber (reg:CC FLAGS_REG))])]
8925   "operands[0] = gen_lowpart (SImode, operands[0]);
8926    operands[1] = gen_lowpart (SImode, operands[1]);
8927    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8928
8929 ;; Since OR can be encoded with sign extended immediate, this is only
8930 ;; profitable when 7th bit is set.
8931 (define_split
8932   [(set (match_operand 0 "register_operand" "")
8933         (ior (match_operand 1 "general_operand" "")
8934              (match_operand 2 "const_int_operand" "")))
8935    (clobber (reg:CC FLAGS_REG))]
8936    "reload_completed
8937     && ANY_QI_REG_P (operands[0])
8938     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8939     && !(INTVAL (operands[2]) & ~255)
8940     && (INTVAL (operands[2]) & 128)
8941     && GET_MODE (operands[0]) != QImode"
8942   [(parallel [(set (strict_low_part (match_dup 0))
8943                    (ior:QI (match_dup 1)
8944                            (match_dup 2)))
8945               (clobber (reg:CC FLAGS_REG))])]
8946   "operands[0] = gen_lowpart (QImode, operands[0]);
8947    operands[1] = gen_lowpart (QImode, operands[1]);
8948    operands[2] = gen_lowpart (QImode, operands[2]);")
8949 \f
8950 ;; Logical XOR instructions
8951
8952 ;; %%% This used to optimize known byte-wide and operations to memory.
8953 ;; If this is considered useful, it should be done with splitters.
8954
8955 (define_expand "xordi3"
8956   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8957         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8958                 (match_operand:DI 2 "x86_64_general_operand" "")))
8959    (clobber (reg:CC FLAGS_REG))]
8960   "TARGET_64BIT"
8961   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8962
8963 (define_insn "*xordi_1_rex64"
8964   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8965         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8966                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8967    (clobber (reg:CC FLAGS_REG))]
8968   "TARGET_64BIT
8969    && ix86_binary_operator_ok (XOR, DImode, operands)"
8970   "@
8971    xor{q}\t{%2, %0|%0, %2}
8972    xor{q}\t{%2, %0|%0, %2}"
8973   [(set_attr "type" "alu")
8974    (set_attr "mode" "DI,DI")])
8975
8976 (define_insn "*xordi_2_rex64"
8977   [(set (reg 17)
8978         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8979                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8980                  (const_int 0)))
8981    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8982         (xor:DI (match_dup 1) (match_dup 2)))]
8983   "TARGET_64BIT
8984    && ix86_match_ccmode (insn, CCNOmode)
8985    && ix86_binary_operator_ok (XOR, DImode, operands)"
8986   "@
8987    xor{q}\t{%2, %0|%0, %2}
8988    xor{q}\t{%2, %0|%0, %2}"
8989   [(set_attr "type" "alu")
8990    (set_attr "mode" "DI,DI")])
8991
8992 (define_insn "*xordi_3_rex64"
8993   [(set (reg 17)
8994         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8995                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8996                  (const_int 0)))
8997    (clobber (match_scratch:DI 0 "=r"))]
8998   "TARGET_64BIT
8999    && ix86_match_ccmode (insn, CCNOmode)
9000    && ix86_binary_operator_ok (XOR, DImode, operands)"
9001   "xor{q}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "DI")])
9004
9005 (define_expand "xorsi3"
9006   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9007         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9008                 (match_operand:SI 2 "general_operand" "")))
9009    (clobber (reg:CC FLAGS_REG))]
9010   ""
9011   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9012
9013 (define_insn "*xorsi_1"
9014   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9015         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9016                 (match_operand:SI 2 "general_operand" "ri,rm")))
9017    (clobber (reg:CC FLAGS_REG))]
9018   "ix86_binary_operator_ok (XOR, SImode, operands)"
9019   "xor{l}\t{%2, %0|%0, %2}"
9020   [(set_attr "type" "alu")
9021    (set_attr "mode" "SI")])
9022
9023 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9024 ;; Add speccase for immediates
9025 (define_insn "*xorsi_1_zext"
9026   [(set (match_operand:DI 0 "register_operand" "=r")
9027         (zero_extend:DI
9028           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9029                   (match_operand:SI 2 "general_operand" "rim"))))
9030    (clobber (reg:CC FLAGS_REG))]
9031   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9032   "xor{l}\t{%2, %k0|%k0, %2}"
9033   [(set_attr "type" "alu")
9034    (set_attr "mode" "SI")])
9035
9036 (define_insn "*xorsi_1_zext_imm"
9037   [(set (match_operand:DI 0 "register_operand" "=r")
9038         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9039                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9040    (clobber (reg:CC FLAGS_REG))]
9041   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9042   "xor{l}\t{%2, %k0|%k0, %2}"
9043   [(set_attr "type" "alu")
9044    (set_attr "mode" "SI")])
9045
9046 (define_insn "*xorsi_2"
9047   [(set (reg 17)
9048         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9049                          (match_operand:SI 2 "general_operand" "rim,ri"))
9050                  (const_int 0)))
9051    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9052         (xor:SI (match_dup 1) (match_dup 2)))]
9053   "ix86_match_ccmode (insn, CCNOmode)
9054    && ix86_binary_operator_ok (XOR, SImode, operands)"
9055   "xor{l}\t{%2, %0|%0, %2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "mode" "SI")])
9058
9059 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9060 ;; ??? Special case for immediate operand is missing - it is tricky.
9061 (define_insn "*xorsi_2_zext"
9062   [(set (reg 17)
9063         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9064                          (match_operand:SI 2 "general_operand" "rim"))
9065                  (const_int 0)))
9066    (set (match_operand:DI 0 "register_operand" "=r")
9067         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9068   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9069    && ix86_binary_operator_ok (XOR, SImode, operands)"
9070   "xor{l}\t{%2, %k0|%k0, %2}"
9071   [(set_attr "type" "alu")
9072    (set_attr "mode" "SI")])
9073
9074 (define_insn "*xorsi_2_zext_imm"
9075   [(set (reg 17)
9076         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9077                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9078                  (const_int 0)))
9079    (set (match_operand:DI 0 "register_operand" "=r")
9080         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9081   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9082    && ix86_binary_operator_ok (XOR, SImode, operands)"
9083   "xor{l}\t{%2, %k0|%k0, %2}"
9084   [(set_attr "type" "alu")
9085    (set_attr "mode" "SI")])
9086
9087 (define_insn "*xorsi_3"
9088   [(set (reg 17)
9089         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9090                          (match_operand:SI 2 "general_operand" "rim"))
9091                  (const_int 0)))
9092    (clobber (match_scratch:SI 0 "=r"))]
9093   "ix86_match_ccmode (insn, CCNOmode)
9094    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9095   "xor{l}\t{%2, %0|%0, %2}"
9096   [(set_attr "type" "alu")
9097    (set_attr "mode" "SI")])
9098
9099 (define_expand "xorhi3"
9100   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9101         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9102                 (match_operand:HI 2 "general_operand" "")))
9103    (clobber (reg:CC FLAGS_REG))]
9104   "TARGET_HIMODE_MATH"
9105   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9106
9107 (define_insn "*xorhi_1"
9108   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9109         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9110                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9111    (clobber (reg:CC FLAGS_REG))]
9112   "ix86_binary_operator_ok (XOR, HImode, operands)"
9113   "xor{w}\t{%2, %0|%0, %2}"
9114   [(set_attr "type" "alu")
9115    (set_attr "mode" "HI")])
9116
9117 (define_insn "*xorhi_2"
9118   [(set (reg 17)
9119         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9120                          (match_operand:HI 2 "general_operand" "rim,ri"))
9121                  (const_int 0)))
9122    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9123         (xor:HI (match_dup 1) (match_dup 2)))]
9124   "ix86_match_ccmode (insn, CCNOmode)
9125    && ix86_binary_operator_ok (XOR, HImode, operands)"
9126   "xor{w}\t{%2, %0|%0, %2}"
9127   [(set_attr "type" "alu")
9128    (set_attr "mode" "HI")])
9129
9130 (define_insn "*xorhi_3"
9131   [(set (reg 17)
9132         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9133                          (match_operand:HI 2 "general_operand" "rim"))
9134                  (const_int 0)))
9135    (clobber (match_scratch:HI 0 "=r"))]
9136   "ix86_match_ccmode (insn, CCNOmode)
9137    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9138   "xor{w}\t{%2, %0|%0, %2}"
9139   [(set_attr "type" "alu")
9140    (set_attr "mode" "HI")])
9141
9142 (define_expand "xorqi3"
9143   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9144         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9145                 (match_operand:QI 2 "general_operand" "")))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "TARGET_QIMODE_MATH"
9148   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9149
9150 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9151 (define_insn "*xorqi_1"
9152   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9153         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9154                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9155    (clobber (reg:CC FLAGS_REG))]
9156   "ix86_binary_operator_ok (XOR, QImode, operands)"
9157   "@
9158    xor{b}\t{%2, %0|%0, %2}
9159    xor{b}\t{%2, %0|%0, %2}
9160    xor{l}\t{%k2, %k0|%k0, %k2}"
9161   [(set_attr "type" "alu")
9162    (set_attr "mode" "QI,QI,SI")])
9163
9164 (define_insn "*xorqi_1_slp"
9165   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9166         (xor:QI (match_dup 0)
9167                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9168    (clobber (reg:CC FLAGS_REG))]
9169   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9170    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9171   "xor{b}\t{%1, %0|%0, %1}"
9172   [(set_attr "type" "alu1")
9173    (set_attr "mode" "QI")])
9174
9175 (define_insn "xorqi_ext_0"
9176   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9177                          (const_int 8)
9178                          (const_int 8))
9179         (xor:SI 
9180           (zero_extract:SI
9181             (match_operand 1 "ext_register_operand" "0")
9182             (const_int 8)
9183             (const_int 8))
9184           (match_operand 2 "const_int_operand" "n")))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9187   "xor{b}\t{%2, %h0|%h0, %2}"
9188   [(set_attr "type" "alu")
9189    (set_attr "length_immediate" "1")
9190    (set_attr "mode" "QI")])
9191
9192 (define_insn "*xorqi_ext_1"
9193   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9194                          (const_int 8)
9195                          (const_int 8))
9196         (xor:SI 
9197           (zero_extract:SI
9198             (match_operand 1 "ext_register_operand" "0")
9199             (const_int 8)
9200             (const_int 8))
9201           (zero_extend:SI
9202             (match_operand:QI 2 "general_operand" "Qm"))))
9203    (clobber (reg:CC FLAGS_REG))]
9204   "!TARGET_64BIT
9205    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9206   "xor{b}\t{%2, %h0|%h0, %2}"
9207   [(set_attr "type" "alu")
9208    (set_attr "length_immediate" "0")
9209    (set_attr "mode" "QI")])
9210
9211 (define_insn "*xorqi_ext_1_rex64"
9212   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9213                          (const_int 8)
9214                          (const_int 8))
9215         (xor:SI 
9216           (zero_extract:SI
9217             (match_operand 1 "ext_register_operand" "0")
9218             (const_int 8)
9219             (const_int 8))
9220           (zero_extend:SI
9221             (match_operand 2 "ext_register_operand" "Q"))))
9222    (clobber (reg:CC FLAGS_REG))]
9223   "TARGET_64BIT
9224    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9225   "xor{b}\t{%2, %h0|%h0, %2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "length_immediate" "0")
9228    (set_attr "mode" "QI")])
9229
9230 (define_insn "*xorqi_ext_2"
9231   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9232                          (const_int 8)
9233                          (const_int 8))
9234         (xor:SI 
9235           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9236                            (const_int 8)
9237                            (const_int 8))
9238           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9239                            (const_int 8)
9240                            (const_int 8))))
9241    (clobber (reg:CC FLAGS_REG))]
9242   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9243   "xor{b}\t{%h2, %h0|%h0, %h2}"
9244   [(set_attr "type" "alu")
9245    (set_attr "length_immediate" "0")
9246    (set_attr "mode" "QI")])
9247
9248 (define_insn "*xorqi_cc_1"
9249   [(set (reg 17)
9250         (compare
9251           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9252                   (match_operand:QI 2 "general_operand" "qim,qi"))
9253           (const_int 0)))
9254    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9255         (xor:QI (match_dup 1) (match_dup 2)))]
9256   "ix86_match_ccmode (insn, CCNOmode)
9257    && ix86_binary_operator_ok (XOR, QImode, operands)"
9258   "xor{b}\t{%2, %0|%0, %2}"
9259   [(set_attr "type" "alu")
9260    (set_attr "mode" "QI")])
9261
9262 (define_insn "*xorqi_2_slp"
9263   [(set (reg 17)
9264         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9265                          (match_operand:QI 1 "general_operand" "qim,qi"))
9266                  (const_int 0)))
9267    (set (strict_low_part (match_dup 0))
9268         (xor:QI (match_dup 0) (match_dup 1)))]
9269   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9270    && ix86_match_ccmode (insn, CCNOmode)
9271    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9272   "xor{b}\t{%1, %0|%0, %1}"
9273   [(set_attr "type" "alu1")
9274    (set_attr "mode" "QI")])
9275
9276 (define_insn "*xorqi_cc_2"
9277   [(set (reg 17)
9278         (compare
9279           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9280                   (match_operand:QI 2 "general_operand" "qim"))
9281           (const_int 0)))
9282    (clobber (match_scratch:QI 0 "=q"))]
9283   "ix86_match_ccmode (insn, CCNOmode)
9284    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9285   "xor{b}\t{%2, %0|%0, %2}"
9286   [(set_attr "type" "alu")
9287    (set_attr "mode" "QI")])
9288
9289 (define_insn "*xorqi_cc_ext_1"
9290   [(set (reg 17)
9291         (compare
9292           (xor:SI
9293             (zero_extract:SI
9294               (match_operand 1 "ext_register_operand" "0")
9295               (const_int 8)
9296               (const_int 8))
9297             (match_operand:QI 2 "general_operand" "qmn"))
9298           (const_int 0)))
9299    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9300                          (const_int 8)
9301                          (const_int 8))
9302         (xor:SI 
9303           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9304           (match_dup 2)))]
9305   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9306   "xor{b}\t{%2, %h0|%h0, %2}"
9307   [(set_attr "type" "alu")
9308    (set_attr "mode" "QI")])
9309
9310 (define_insn "*xorqi_cc_ext_1_rex64"
9311   [(set (reg 17)
9312         (compare
9313           (xor:SI
9314             (zero_extract:SI
9315               (match_operand 1 "ext_register_operand" "0")
9316               (const_int 8)
9317               (const_int 8))
9318             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9319           (const_int 0)))
9320    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9321                          (const_int 8)
9322                          (const_int 8))
9323         (xor:SI 
9324           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9325           (match_dup 2)))]
9326   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9327   "xor{b}\t{%2, %h0|%h0, %2}"
9328   [(set_attr "type" "alu")
9329    (set_attr "mode" "QI")])
9330
9331 (define_expand "xorqi_cc_ext_1"
9332   [(parallel [
9333      (set (reg:CCNO FLAGS_REG)
9334           (compare:CCNO
9335             (xor:SI
9336               (zero_extract:SI
9337                 (match_operand 1 "ext_register_operand" "")
9338                 (const_int 8)
9339                 (const_int 8))
9340               (match_operand:QI 2 "general_operand" ""))
9341             (const_int 0)))
9342      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9343                            (const_int 8)
9344                            (const_int 8))
9345           (xor:SI 
9346             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9347             (match_dup 2)))])]
9348   ""
9349   "")
9350
9351 (define_split
9352   [(set (match_operand 0 "register_operand" "")
9353         (xor (match_operand 1 "register_operand" "")
9354              (match_operand 2 "const_int_operand" "")))
9355    (clobber (reg:CC FLAGS_REG))]
9356    "reload_completed
9357     && QI_REG_P (operands[0])
9358     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9359     && !(INTVAL (operands[2]) & ~(255 << 8))
9360     && GET_MODE (operands[0]) != QImode"
9361   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9362                    (xor:SI (zero_extract:SI (match_dup 1)
9363                                             (const_int 8) (const_int 8))
9364                            (match_dup 2)))
9365               (clobber (reg:CC FLAGS_REG))])]
9366   "operands[0] = gen_lowpart (SImode, operands[0]);
9367    operands[1] = gen_lowpart (SImode, operands[1]);
9368    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9369
9370 ;; Since XOR can be encoded with sign extended immediate, this is only
9371 ;; profitable when 7th bit is set.
9372 (define_split
9373   [(set (match_operand 0 "register_operand" "")
9374         (xor (match_operand 1 "general_operand" "")
9375              (match_operand 2 "const_int_operand" "")))
9376    (clobber (reg:CC FLAGS_REG))]
9377    "reload_completed
9378     && ANY_QI_REG_P (operands[0])
9379     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9380     && !(INTVAL (operands[2]) & ~255)
9381     && (INTVAL (operands[2]) & 128)
9382     && GET_MODE (operands[0]) != QImode"
9383   [(parallel [(set (strict_low_part (match_dup 0))
9384                    (xor:QI (match_dup 1)
9385                            (match_dup 2)))
9386               (clobber (reg:CC FLAGS_REG))])]
9387   "operands[0] = gen_lowpart (QImode, operands[0]);
9388    operands[1] = gen_lowpart (QImode, operands[1]);
9389    operands[2] = gen_lowpart (QImode, operands[2]);")
9390 \f
9391 ;; Negation instructions
9392
9393 (define_expand "negdi2"
9394   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9395                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9396               (clobber (reg:CC FLAGS_REG))])]
9397   ""
9398   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9399
9400 (define_insn "*negdi2_1"
9401   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9402         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9403    (clobber (reg:CC FLAGS_REG))]
9404   "!TARGET_64BIT
9405    && ix86_unary_operator_ok (NEG, DImode, operands)"
9406   "#")
9407
9408 (define_split
9409   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9410         (neg:DI (match_operand:DI 1 "general_operand" "")))
9411    (clobber (reg:CC FLAGS_REG))]
9412   "!TARGET_64BIT && reload_completed"
9413   [(parallel
9414     [(set (reg:CCZ FLAGS_REG)
9415           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9416      (set (match_dup 0) (neg:SI (match_dup 2)))])
9417    (parallel
9418     [(set (match_dup 1)
9419           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9420                             (match_dup 3))
9421                    (const_int 0)))
9422      (clobber (reg:CC FLAGS_REG))])
9423    (parallel
9424     [(set (match_dup 1)
9425           (neg:SI (match_dup 1)))
9426      (clobber (reg:CC FLAGS_REG))])]
9427   "split_di (operands+1, 1, operands+2, operands+3);
9428    split_di (operands+0, 1, operands+0, operands+1);")
9429
9430 (define_insn "*negdi2_1_rex64"
9431   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9432         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9433    (clobber (reg:CC FLAGS_REG))]
9434   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9435   "neg{q}\t%0"
9436   [(set_attr "type" "negnot")
9437    (set_attr "mode" "DI")])
9438
9439 ;; The problem with neg is that it does not perform (compare x 0),
9440 ;; it really performs (compare 0 x), which leaves us with the zero
9441 ;; flag being the only useful item.
9442
9443 (define_insn "*negdi2_cmpz_rex64"
9444   [(set (reg:CCZ FLAGS_REG)
9445         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9446                      (const_int 0)))
9447    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9448         (neg:DI (match_dup 1)))]
9449   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9450   "neg{q}\t%0"
9451   [(set_attr "type" "negnot")
9452    (set_attr "mode" "DI")])
9453
9454
9455 (define_expand "negsi2"
9456   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9457                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9458               (clobber (reg:CC FLAGS_REG))])]
9459   ""
9460   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9461
9462 (define_insn "*negsi2_1"
9463   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9464         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9465    (clobber (reg:CC FLAGS_REG))]
9466   "ix86_unary_operator_ok (NEG, SImode, operands)"
9467   "neg{l}\t%0"
9468   [(set_attr "type" "negnot")
9469    (set_attr "mode" "SI")])
9470
9471 ;; Combine is quite creative about this pattern.
9472 (define_insn "*negsi2_1_zext"
9473   [(set (match_operand:DI 0 "register_operand" "=r")
9474         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9475                                         (const_int 32)))
9476                      (const_int 32)))
9477    (clobber (reg:CC FLAGS_REG))]
9478   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9479   "neg{l}\t%k0"
9480   [(set_attr "type" "negnot")
9481    (set_attr "mode" "SI")])
9482
9483 ;; The problem with neg is that it does not perform (compare x 0),
9484 ;; it really performs (compare 0 x), which leaves us with the zero
9485 ;; flag being the only useful item.
9486
9487 (define_insn "*negsi2_cmpz"
9488   [(set (reg:CCZ FLAGS_REG)
9489         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9490                      (const_int 0)))
9491    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9492         (neg:SI (match_dup 1)))]
9493   "ix86_unary_operator_ok (NEG, SImode, operands)"
9494   "neg{l}\t%0"
9495   [(set_attr "type" "negnot")
9496    (set_attr "mode" "SI")])
9497
9498 (define_insn "*negsi2_cmpz_zext"
9499   [(set (reg:CCZ FLAGS_REG)
9500         (compare:CCZ (lshiftrt:DI
9501                        (neg:DI (ashift:DI
9502                                  (match_operand:DI 1 "register_operand" "0")
9503                                  (const_int 32)))
9504                        (const_int 32))
9505                      (const_int 0)))
9506    (set (match_operand:DI 0 "register_operand" "=r")
9507         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9508                                         (const_int 32)))
9509                      (const_int 32)))]
9510   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9511   "neg{l}\t%k0"
9512   [(set_attr "type" "negnot")
9513    (set_attr "mode" "SI")])
9514
9515 (define_expand "neghi2"
9516   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9517                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9518               (clobber (reg:CC FLAGS_REG))])]
9519   "TARGET_HIMODE_MATH"
9520   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9521
9522 (define_insn "*neghi2_1"
9523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9524         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9525    (clobber (reg:CC FLAGS_REG))]
9526   "ix86_unary_operator_ok (NEG, HImode, operands)"
9527   "neg{w}\t%0"
9528   [(set_attr "type" "negnot")
9529    (set_attr "mode" "HI")])
9530
9531 (define_insn "*neghi2_cmpz"
9532   [(set (reg:CCZ FLAGS_REG)
9533         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9534                      (const_int 0)))
9535    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9536         (neg:HI (match_dup 1)))]
9537   "ix86_unary_operator_ok (NEG, HImode, operands)"
9538   "neg{w}\t%0"
9539   [(set_attr "type" "negnot")
9540    (set_attr "mode" "HI")])
9541
9542 (define_expand "negqi2"
9543   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9544                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9545               (clobber (reg:CC FLAGS_REG))])]
9546   "TARGET_QIMODE_MATH"
9547   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9548
9549 (define_insn "*negqi2_1"
9550   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9551         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9552    (clobber (reg:CC FLAGS_REG))]
9553   "ix86_unary_operator_ok (NEG, QImode, operands)"
9554   "neg{b}\t%0"
9555   [(set_attr "type" "negnot")
9556    (set_attr "mode" "QI")])
9557
9558 (define_insn "*negqi2_cmpz"
9559   [(set (reg:CCZ FLAGS_REG)
9560         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9561                      (const_int 0)))
9562    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9563         (neg:QI (match_dup 1)))]
9564   "ix86_unary_operator_ok (NEG, QImode, operands)"
9565   "neg{b}\t%0"
9566   [(set_attr "type" "negnot")
9567    (set_attr "mode" "QI")])
9568
9569 ;; Changing of sign for FP values is doable using integer unit too.
9570
9571 (define_expand "negsf2"
9572   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9573                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9574               (clobber (reg:CC FLAGS_REG))])]
9575   "TARGET_80387"
9576   "if (TARGET_SSE)
9577      {
9578        /* In case operand is in memory,  we will not use SSE.  */
9579        if (memory_operand (operands[0], VOIDmode)
9580            && rtx_equal_p (operands[0], operands[1]))
9581          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9582        else
9583         {
9584           /* Using SSE is tricky, since we need bitwise negation of -0
9585              in register.  */
9586           rtx reg = gen_reg_rtx (SFmode);
9587           rtx dest = operands[0];
9588           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9589
9590           operands[1] = force_reg (SFmode, operands[1]);
9591           operands[0] = force_reg (SFmode, operands[0]);
9592           reg = force_reg (V4SFmode,
9593                            gen_rtx_CONST_VECTOR (V4SFmode,
9594                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9595                                         CONST0_RTX (SFmode),
9596                                         CONST0_RTX (SFmode))));
9597           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9598           if (dest != operands[0])
9599             emit_move_insn (dest, operands[0]);
9600         }
9601        DONE;
9602      }
9603    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9604
9605 (define_insn "negsf2_memory"
9606   [(set (match_operand:SF 0 "memory_operand" "=m")
9607         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9608    (clobber (reg:CC FLAGS_REG))]
9609   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9610   "#")
9611
9612 (define_insn "negsf2_ifs"
9613   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9614         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9615    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9616    (clobber (reg:CC FLAGS_REG))]
9617   "TARGET_SSE
9618    && (reload_in_progress || reload_completed
9619        || (register_operand (operands[0], VOIDmode)
9620            && register_operand (operands[1], VOIDmode)))"
9621   "#")
9622
9623 (define_split
9624   [(set (match_operand:SF 0 "memory_operand" "")
9625         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9626    (use (match_operand:SF 2 "" ""))
9627    (clobber (reg:CC FLAGS_REG))]
9628   ""
9629   [(parallel [(set (match_dup 0)
9630                    (neg:SF (match_dup 1)))
9631               (clobber (reg:CC FLAGS_REG))])])
9632
9633 (define_split
9634   [(set (match_operand:SF 0 "register_operand" "")
9635         (neg:SF (match_operand:SF 1 "register_operand" "")))
9636    (use (match_operand:V4SF 2 "" ""))
9637    (clobber (reg:CC FLAGS_REG))]
9638   "reload_completed && !SSE_REG_P (operands[0])"
9639   [(parallel [(set (match_dup 0)
9640                    (neg:SF (match_dup 1)))
9641               (clobber (reg:CC FLAGS_REG))])])
9642
9643 (define_split
9644   [(set (match_operand:SF 0 "register_operand" "")
9645         (neg:SF (match_operand:SF 1 "register_operand" "")))
9646    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "reload_completed && SSE_REG_P (operands[0])"
9649   [(set (match_dup 0)
9650         (xor:V4SF (match_dup 1)
9651                   (match_dup 2)))]
9652 {
9653   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9654   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9655   if (operands_match_p (operands[0], operands[2]))
9656     {
9657       rtx tmp;
9658       tmp = operands[1];
9659       operands[1] = operands[2];
9660       operands[2] = tmp;
9661     }
9662 })
9663
9664
9665 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9666 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9667 ;; to itself.
9668 (define_insn "*negsf2_if"
9669   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9670         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9671    (clobber (reg:CC FLAGS_REG))]
9672   "TARGET_80387 && !TARGET_SSE
9673    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9674   "#")
9675
9676 (define_split
9677   [(set (match_operand:SF 0 "fp_register_operand" "")
9678         (neg:SF (match_operand:SF 1 "register_operand" "")))
9679    (clobber (reg:CC FLAGS_REG))]
9680   "TARGET_80387 && reload_completed"
9681   [(set (match_dup 0)
9682         (neg:SF (match_dup 1)))]
9683   "")
9684
9685 (define_split
9686   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9687         (neg:SF (match_operand:SF 1 "register_operand" "")))
9688    (clobber (reg:CC FLAGS_REG))]
9689   "TARGET_80387 && reload_completed"
9690   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9691               (clobber (reg:CC FLAGS_REG))])]
9692   "operands[1] = gen_int_mode (0x80000000, SImode);
9693    operands[0] = gen_lowpart (SImode, operands[0]);")
9694
9695 (define_split
9696   [(set (match_operand 0 "memory_operand" "")
9697         (neg (match_operand 1 "memory_operand" "")))
9698    (clobber (reg:CC FLAGS_REG))]
9699   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9700   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9701               (clobber (reg:CC FLAGS_REG))])]
9702 {
9703   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9704
9705   if (GET_MODE (operands[1]) == XFmode)
9706     size = 10;
9707   operands[0] = adjust_address (operands[0], QImode, size - 1);
9708   operands[1] = gen_int_mode (0x80, QImode);
9709 })
9710
9711 (define_expand "negdf2"
9712   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9713                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9714               (clobber (reg:CC FLAGS_REG))])]
9715   "TARGET_80387"
9716   "if (TARGET_SSE2)
9717      {
9718        /* In case operand is in memory,  we will not use SSE.  */
9719        if (memory_operand (operands[0], VOIDmode)
9720            && rtx_equal_p (operands[0], operands[1]))
9721          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9722        else
9723         {
9724           /* Using SSE is tricky, since we need bitwise negation of -0
9725              in register.  */
9726           rtx reg;
9727 #if HOST_BITS_PER_WIDE_INT >= 64
9728           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9729 #else
9730           rtx imm = immed_double_const (0, 0x80000000, DImode);
9731 #endif
9732           rtx dest = operands[0];
9733
9734           operands[1] = force_reg (DFmode, operands[1]);
9735           operands[0] = force_reg (DFmode, operands[0]);
9736           imm = gen_lowpart (DFmode, imm);
9737           reg = force_reg (V2DFmode,
9738                            gen_rtx_CONST_VECTOR (V2DFmode,
9739                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9740           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9741           if (dest != operands[0])
9742             emit_move_insn (dest, operands[0]);
9743         }
9744        DONE;
9745      }
9746    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9747
9748 (define_insn "negdf2_memory"
9749   [(set (match_operand:DF 0 "memory_operand" "=m")
9750         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9751    (clobber (reg:CC FLAGS_REG))]
9752   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9753   "#")
9754
9755 (define_insn "negdf2_ifs"
9756   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9757         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9758    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "!TARGET_64BIT && TARGET_SSE2
9761    && (reload_in_progress || reload_completed
9762        || (register_operand (operands[0], VOIDmode)
9763            && register_operand (operands[1], VOIDmode)))"
9764   "#")
9765
9766 (define_insn "*negdf2_ifs_rex64"
9767   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9768         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9769    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9770    (clobber (reg:CC FLAGS_REG))]
9771   "TARGET_64BIT && TARGET_SSE2
9772    && (reload_in_progress || reload_completed
9773        || (register_operand (operands[0], VOIDmode)
9774            && register_operand (operands[1], VOIDmode)))"
9775   "#")
9776
9777 (define_split
9778   [(set (match_operand:DF 0 "memory_operand" "")
9779         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9780    (use (match_operand:V2DF 2 "" ""))
9781    (clobber (reg:CC FLAGS_REG))]
9782   ""
9783   [(parallel [(set (match_dup 0)
9784                    (neg:DF (match_dup 1)))
9785               (clobber (reg:CC FLAGS_REG))])])
9786
9787 (define_split
9788   [(set (match_operand:DF 0 "register_operand" "")
9789         (neg:DF (match_operand:DF 1 "register_operand" "")))
9790    (use (match_operand:V2DF 2 "" ""))
9791    (clobber (reg:CC FLAGS_REG))]
9792   "reload_completed && !SSE_REG_P (operands[0])
9793    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9794   [(parallel [(set (match_dup 0)
9795                    (neg:DF (match_dup 1)))
9796               (clobber (reg:CC FLAGS_REG))])])
9797
9798 (define_split
9799   [(set (match_operand:DF 0 "register_operand" "")
9800         (neg:DF (match_operand:DF 1 "register_operand" "")))
9801    (use (match_operand:V2DF 2 "" ""))
9802    (clobber (reg:CC FLAGS_REG))]
9803   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9804   [(parallel [(set (match_dup 0)
9805                    (xor:DI (match_dup 1) (match_dup 2)))
9806               (clobber (reg:CC FLAGS_REG))])]
9807    "operands[0] = gen_lowpart (DImode, operands[0]);
9808     operands[1] = gen_lowpart (DImode, operands[1]);
9809     operands[2] = gen_lowpart (DImode, operands[2]);")
9810
9811 (define_split
9812   [(set (match_operand:DF 0 "register_operand" "")
9813         (neg:DF (match_operand:DF 1 "register_operand" "")))
9814    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9815    (clobber (reg:CC FLAGS_REG))]
9816   "reload_completed && SSE_REG_P (operands[0])"
9817   [(set (match_dup 0)
9818         (xor:V2DF (match_dup 1)
9819                   (match_dup 2)))]
9820 {
9821   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9822   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9823   /* Avoid possible reformatting on the operands.  */
9824   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9825     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9826   if (operands_match_p (operands[0], operands[2]))
9827     {
9828       rtx tmp;
9829       tmp = operands[1];
9830       operands[1] = operands[2];
9831       operands[2] = tmp;
9832     }
9833 })
9834
9835 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9836 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9837 ;; to itself.
9838 (define_insn "*negdf2_if"
9839   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9840         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9841    (clobber (reg:CC FLAGS_REG))]
9842   "!TARGET_64BIT && TARGET_80387
9843    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9844   "#")
9845
9846 ;; FIXME: We should to allow integer registers here.  Problem is that
9847 ;; we need another scratch register to get constant from.
9848 ;; Forcing constant to mem if no register available in peep2 should be
9849 ;; safe even for PIC mode, because of RIP relative addressing.
9850 (define_insn "*negdf2_if_rex64"
9851   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9852         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9853    (clobber (reg:CC FLAGS_REG))]
9854   "TARGET_64BIT && TARGET_80387
9855    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9856   "#")
9857
9858 (define_split
9859   [(set (match_operand:DF 0 "fp_register_operand" "")
9860         (neg:DF (match_operand:DF 1 "register_operand" "")))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "TARGET_80387 && reload_completed"
9863   [(set (match_dup 0)
9864         (neg:DF (match_dup 1)))]
9865   "")
9866
9867 (define_split
9868   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9869         (neg:DF (match_operand:DF 1 "register_operand" "")))
9870    (clobber (reg:CC FLAGS_REG))]
9871   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9872   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9873               (clobber (reg:CC FLAGS_REG))])]
9874   "operands[4] = gen_int_mode (0x80000000, SImode);
9875    split_di (operands+0, 1, operands+2, operands+3);")
9876
9877 (define_expand "negxf2"
9878   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9879                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9880               (clobber (reg:CC FLAGS_REG))])]
9881   "TARGET_80387"
9882   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9883
9884 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9885 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9886 ;; to itself.
9887 (define_insn "*negxf2_if"
9888   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9889         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9890    (clobber (reg:CC FLAGS_REG))]
9891   "TARGET_80387
9892    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9893   "#")
9894
9895 (define_split
9896   [(set (match_operand:XF 0 "fp_register_operand" "")
9897         (neg:XF (match_operand:XF 1 "register_operand" "")))
9898    (clobber (reg:CC FLAGS_REG))]
9899   "TARGET_80387 && reload_completed"
9900   [(set (match_dup 0)
9901         (neg:XF (match_dup 1)))]
9902   "")
9903
9904 (define_split
9905   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9906         (neg:XF (match_operand:XF 1 "register_operand" "")))
9907    (clobber (reg:CC FLAGS_REG))]
9908   "TARGET_80387 && reload_completed"
9909   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9910               (clobber (reg:CC FLAGS_REG))])]
9911   "operands[1] = GEN_INT (0x8000);
9912    operands[0] = gen_rtx_REG (SImode,
9913                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9914
9915 ;; Conditionalize these after reload. If they matches before reload, we 
9916 ;; lose the clobber and ability to use integer instructions.
9917
9918 (define_insn "*negsf2_1"
9919   [(set (match_operand:SF 0 "register_operand" "=f")
9920         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9921   "TARGET_80387 && reload_completed"
9922   "fchs"
9923   [(set_attr "type" "fsgn")
9924    (set_attr "mode" "SF")])
9925
9926 (define_insn "*negdf2_1"
9927   [(set (match_operand:DF 0 "register_operand" "=f")
9928         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9929   "TARGET_80387 && reload_completed"
9930   "fchs"
9931   [(set_attr "type" "fsgn")
9932    (set_attr "mode" "DF")])
9933
9934 (define_insn "*negextendsfdf2"
9935   [(set (match_operand:DF 0 "register_operand" "=f")
9936         (neg:DF (float_extend:DF
9937                   (match_operand:SF 1 "register_operand" "0"))))]
9938   "TARGET_80387"
9939   "fchs"
9940   [(set_attr "type" "fsgn")
9941    (set_attr "mode" "DF")])
9942
9943 (define_insn "*negxf2_1"
9944   [(set (match_operand:XF 0 "register_operand" "=f")
9945         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9946   "TARGET_80387 && reload_completed"
9947   "fchs"
9948   [(set_attr "type" "fsgn")
9949    (set_attr "mode" "XF")])
9950
9951 (define_insn "*negextenddfxf2"
9952   [(set (match_operand:XF 0 "register_operand" "=f")
9953         (neg:XF (float_extend:XF
9954                   (match_operand:DF 1 "register_operand" "0"))))]
9955   "TARGET_80387"
9956   "fchs"
9957   [(set_attr "type" "fsgn")
9958    (set_attr "mode" "XF")])
9959
9960 (define_insn "*negextendsfxf2"
9961   [(set (match_operand:XF 0 "register_operand" "=f")
9962         (neg:XF (float_extend:XF
9963                   (match_operand:SF 1 "register_operand" "0"))))]
9964   "TARGET_80387"
9965   "fchs"
9966   [(set_attr "type" "fsgn")
9967    (set_attr "mode" "XF")])
9968 \f
9969 ;; Absolute value instructions
9970
9971 (define_expand "abssf2"
9972   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9973                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9974               (clobber (reg:CC FLAGS_REG))])]
9975   "TARGET_80387"
9976   "if (TARGET_SSE)
9977      {
9978        /* In case operand is in memory,  we will not use SSE.  */
9979        if (memory_operand (operands[0], VOIDmode)
9980            && rtx_equal_p (operands[0], operands[1]))
9981          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9982        else
9983         {
9984           /* Using SSE is tricky, since we need bitwise negation of -0
9985              in register.  */
9986           rtx reg = gen_reg_rtx (V4SFmode);
9987           rtx dest = operands[0];
9988           rtx imm;
9989
9990           operands[1] = force_reg (SFmode, operands[1]);
9991           operands[0] = force_reg (SFmode, operands[0]);
9992           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9993           reg = force_reg (V4SFmode,
9994                            gen_rtx_CONST_VECTOR (V4SFmode,
9995                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
9996                                       CONST0_RTX (SFmode),
9997                                       CONST0_RTX (SFmode))));
9998           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9999           if (dest != operands[0])
10000             emit_move_insn (dest, operands[0]);
10001         }
10002        DONE;
10003      }
10004    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10005
10006 (define_insn "abssf2_memory"
10007   [(set (match_operand:SF 0 "memory_operand" "=m")
10008         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10009    (clobber (reg:CC FLAGS_REG))]
10010   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10011   "#")
10012
10013 (define_insn "abssf2_ifs"
10014   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10015         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10016    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10017    (clobber (reg:CC FLAGS_REG))]
10018   "TARGET_SSE
10019    && (reload_in_progress || reload_completed
10020        || (register_operand (operands[0], VOIDmode)
10021             && register_operand (operands[1], VOIDmode)))"
10022   "#")
10023
10024 (define_split
10025   [(set (match_operand:SF 0 "memory_operand" "")
10026         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10027    (use (match_operand:V4SF 2 "" ""))
10028    (clobber (reg:CC FLAGS_REG))]
10029   ""
10030   [(parallel [(set (match_dup 0)
10031                    (abs:SF (match_dup 1)))
10032               (clobber (reg:CC FLAGS_REG))])])
10033
10034 (define_split
10035   [(set (match_operand:SF 0 "register_operand" "")
10036         (abs:SF (match_operand:SF 1 "register_operand" "")))
10037    (use (match_operand:V4SF 2 "" ""))
10038    (clobber (reg:CC FLAGS_REG))]
10039   "reload_completed && !SSE_REG_P (operands[0])"
10040   [(parallel [(set (match_dup 0)
10041                    (abs:SF (match_dup 1)))
10042               (clobber (reg:CC FLAGS_REG))])])
10043
10044 (define_split
10045   [(set (match_operand:SF 0 "register_operand" "")
10046         (abs:SF (match_operand:SF 1 "register_operand" "")))
10047    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10048    (clobber (reg:CC FLAGS_REG))]
10049   "reload_completed && SSE_REG_P (operands[0])"
10050   [(set (match_dup 0)
10051         (and:V4SF (match_dup 1)
10052                   (match_dup 2)))]
10053 {
10054   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10055   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10056   if (operands_match_p (operands[0], operands[2]))
10057     {
10058       rtx tmp;
10059       tmp = operands[1];
10060       operands[1] = operands[2];
10061       operands[2] = tmp;
10062     }
10063 })
10064
10065 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10066 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10067 ;; to itself.
10068 (define_insn "*abssf2_if"
10069   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10070         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10071    (clobber (reg:CC FLAGS_REG))]
10072   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10073   "#")
10074
10075 (define_split
10076   [(set (match_operand:SF 0 "fp_register_operand" "")
10077         (abs:SF (match_operand:SF 1 "register_operand" "")))
10078    (clobber (reg:CC FLAGS_REG))]
10079   "TARGET_80387 && reload_completed"
10080   [(set (match_dup 0)
10081         (abs:SF (match_dup 1)))]
10082   "")
10083
10084 (define_split
10085   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10086         (abs:SF (match_operand:SF 1 "register_operand" "")))
10087    (clobber (reg:CC FLAGS_REG))]
10088   "TARGET_80387 && reload_completed"
10089   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10090               (clobber (reg:CC FLAGS_REG))])]
10091   "operands[1] = gen_int_mode (~0x80000000, SImode);
10092    operands[0] = gen_lowpart (SImode, operands[0]);")
10093
10094 (define_split
10095   [(set (match_operand 0 "memory_operand" "")
10096         (abs (match_operand 1 "memory_operand" "")))
10097    (clobber (reg:CC FLAGS_REG))]
10098   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10099   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10100               (clobber (reg:CC FLAGS_REG))])]
10101 {
10102   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10103
10104   if (GET_MODE (operands[1]) == XFmode)
10105     size = 10;
10106   operands[0] = adjust_address (operands[0], QImode, size - 1);
10107   operands[1] = gen_int_mode (~0x80, QImode);
10108 })
10109
10110 (define_expand "absdf2"
10111   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10112                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10113               (clobber (reg:CC FLAGS_REG))])]
10114   "TARGET_80387"
10115   "if (TARGET_SSE2)
10116      {
10117        /* In case operand is in memory,  we will not use SSE.  */
10118        if (memory_operand (operands[0], VOIDmode)
10119            && rtx_equal_p (operands[0], operands[1]))
10120          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10121        else
10122         {
10123           /* Using SSE is tricky, since we need bitwise negation of -0
10124              in register.  */
10125           rtx reg = gen_reg_rtx (V2DFmode);
10126 #if HOST_BITS_PER_WIDE_INT >= 64
10127           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10128 #else
10129           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10130 #endif
10131           rtx dest = operands[0];
10132
10133           operands[1] = force_reg (DFmode, operands[1]);
10134           operands[0] = force_reg (DFmode, operands[0]);
10135
10136           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10137           imm = gen_lowpart (DFmode, imm);
10138           reg = force_reg (V2DFmode,
10139                            gen_rtx_CONST_VECTOR (V2DFmode,
10140                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10141           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10142           if (dest != operands[0])
10143             emit_move_insn (dest, operands[0]);
10144         }
10145        DONE;
10146      }
10147    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10148
10149 (define_insn "absdf2_memory"
10150   [(set (match_operand:DF 0 "memory_operand" "=m")
10151         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10152    (clobber (reg:CC FLAGS_REG))]
10153   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10154   "#")
10155
10156 (define_insn "absdf2_ifs"
10157   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10158         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10159    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10160    (clobber (reg:CC FLAGS_REG))]
10161   "!TARGET_64BIT && TARGET_SSE2
10162    && (reload_in_progress || reload_completed
10163        || (register_operand (operands[0], VOIDmode)
10164            && register_operand (operands[1], VOIDmode)))"
10165   "#")
10166
10167 (define_insn "*absdf2_ifs_rex64"
10168   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10169         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10170    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10171    (clobber (reg:CC FLAGS_REG))]
10172   "TARGET_64BIT && TARGET_SSE2
10173    && (reload_in_progress || reload_completed
10174        || (register_operand (operands[0], VOIDmode)
10175            && register_operand (operands[1], VOIDmode)))"
10176   "#")
10177
10178 (define_split
10179   [(set (match_operand:DF 0 "memory_operand" "")
10180         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10181    (use (match_operand:V2DF 2 "" ""))
10182    (clobber (reg:CC FLAGS_REG))]
10183   ""
10184   [(parallel [(set (match_dup 0)
10185                    (abs:DF (match_dup 1)))
10186               (clobber (reg:CC FLAGS_REG))])])
10187
10188 (define_split
10189   [(set (match_operand:DF 0 "register_operand" "")
10190         (abs:DF (match_operand:DF 1 "register_operand" "")))
10191    (use (match_operand:V2DF 2 "" ""))
10192    (clobber (reg:CC FLAGS_REG))]
10193   "reload_completed && !SSE_REG_P (operands[0])"
10194   [(parallel [(set (match_dup 0)
10195                    (abs:DF (match_dup 1)))
10196               (clobber (reg:CC FLAGS_REG))])])
10197
10198 (define_split
10199   [(set (match_operand:DF 0 "register_operand" "")
10200         (abs:DF (match_operand:DF 1 "register_operand" "")))
10201    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10202    (clobber (reg:CC FLAGS_REG))]
10203   "reload_completed && SSE_REG_P (operands[0])"
10204   [(set (match_dup 0)
10205         (and:V2DF (match_dup 1)
10206                   (match_dup 2)))]
10207 {
10208   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10209   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10210   /* Avoid possible reformatting on the operands.  */
10211   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10212     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10213   if (operands_match_p (operands[0], operands[2]))
10214     {
10215       rtx tmp;
10216       tmp = operands[1];
10217       operands[1] = operands[2];
10218       operands[2] = tmp;
10219     }
10220 })
10221
10222
10223 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10224 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10225 ;; to itself.
10226 (define_insn "*absdf2_if"
10227   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10228         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10229    (clobber (reg:CC FLAGS_REG))]
10230   "!TARGET_64BIT && TARGET_80387
10231    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10232   "#")
10233
10234 ;; FIXME: We should to allow integer registers here.  Problem is that
10235 ;; we need another scratch register to get constant from.
10236 ;; Forcing constant to mem if no register available in peep2 should be
10237 ;; safe even for PIC mode, because of RIP relative addressing.
10238 (define_insn "*absdf2_if_rex64"
10239   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10240         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10241    (clobber (reg:CC FLAGS_REG))]
10242   "TARGET_64BIT && TARGET_80387
10243    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10244   "#")
10245
10246 (define_split
10247   [(set (match_operand:DF 0 "fp_register_operand" "")
10248         (abs:DF (match_operand:DF 1 "register_operand" "")))
10249    (clobber (reg:CC FLAGS_REG))]
10250   "TARGET_80387 && reload_completed"
10251   [(set (match_dup 0)
10252         (abs:DF (match_dup 1)))]
10253   "")
10254
10255 (define_split
10256   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10257         (abs:DF (match_operand:DF 1 "register_operand" "")))
10258    (clobber (reg:CC FLAGS_REG))]
10259   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10260   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10261               (clobber (reg:CC FLAGS_REG))])]
10262   "operands[4] = gen_int_mode (~0x80000000, SImode);
10263    split_di (operands+0, 1, operands+2, operands+3);")
10264
10265 (define_expand "absxf2"
10266   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10267                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10268               (clobber (reg:CC FLAGS_REG))])]
10269   "TARGET_80387"
10270   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10271
10272 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10273 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10274 ;; to itself.
10275 (define_insn "*absxf2_if"
10276   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10277         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10278    (clobber (reg:CC FLAGS_REG))]
10279   "TARGET_80387
10280    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10281   "#")
10282
10283 (define_split
10284   [(set (match_operand:XF 0 "fp_register_operand" "")
10285         (abs:XF (match_operand:XF 1 "register_operand" "")))
10286    (clobber (reg:CC FLAGS_REG))]
10287   "TARGET_80387 && reload_completed"
10288   [(set (match_dup 0)
10289         (abs:XF (match_dup 1)))]
10290   "")
10291
10292 (define_split
10293   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10294         (abs:XF (match_operand:XF 1 "register_operand" "")))
10295    (clobber (reg:CC FLAGS_REG))]
10296   "TARGET_80387 && reload_completed"
10297   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10298               (clobber (reg:CC FLAGS_REG))])]
10299   "operands[1] = GEN_INT (~0x8000);
10300    operands[0] = gen_rtx_REG (SImode,
10301                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10302
10303 (define_insn "*abssf2_1"
10304   [(set (match_operand:SF 0 "register_operand" "=f")
10305         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10306   "TARGET_80387 && reload_completed"
10307   "fabs"
10308   [(set_attr "type" "fsgn")
10309    (set_attr "mode" "SF")])
10310
10311 (define_insn "*absdf2_1"
10312   [(set (match_operand:DF 0 "register_operand" "=f")
10313         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10314   "TARGET_80387 && reload_completed"
10315   "fabs"
10316   [(set_attr "type" "fsgn")
10317    (set_attr "mode" "DF")])
10318
10319 (define_insn "*absextendsfdf2"
10320   [(set (match_operand:DF 0 "register_operand" "=f")
10321         (abs:DF (float_extend:DF
10322                   (match_operand:SF 1 "register_operand" "0"))))]
10323   "TARGET_80387"
10324   "fabs"
10325   [(set_attr "type" "fsgn")
10326    (set_attr "mode" "DF")])
10327
10328 (define_insn "*absxf2_1"
10329   [(set (match_operand:XF 0 "register_operand" "=f")
10330         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10331   "TARGET_80387 && reload_completed"
10332   "fabs"
10333   [(set_attr "type" "fsgn")
10334    (set_attr "mode" "DF")])
10335
10336 (define_insn "*absextenddfxf2"
10337   [(set (match_operand:XF 0 "register_operand" "=f")
10338         (abs:XF (float_extend:XF
10339           (match_operand:DF 1 "register_operand" "0"))))]
10340   "TARGET_80387"
10341   "fabs"
10342   [(set_attr "type" "fsgn")
10343    (set_attr "mode" "XF")])
10344
10345 (define_insn "*absextendsfxf2"
10346   [(set (match_operand:XF 0 "register_operand" "=f")
10347         (abs:XF (float_extend:XF
10348           (match_operand:SF 1 "register_operand" "0"))))]
10349   "TARGET_80387"
10350   "fabs"
10351   [(set_attr "type" "fsgn")
10352    (set_attr "mode" "XF")])
10353 \f
10354 ;; One complement instructions
10355
10356 (define_expand "one_cmpldi2"
10357   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10358         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10359   "TARGET_64BIT"
10360   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10361
10362 (define_insn "*one_cmpldi2_1_rex64"
10363   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10364         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10365   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10366   "not{q}\t%0"
10367   [(set_attr "type" "negnot")
10368    (set_attr "mode" "DI")])
10369
10370 (define_insn "*one_cmpldi2_2_rex64"
10371   [(set (reg 17)
10372         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10373                  (const_int 0)))
10374    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10375         (not:DI (match_dup 1)))]
10376   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10377    && ix86_unary_operator_ok (NOT, DImode, operands)"
10378   "#"
10379   [(set_attr "type" "alu1")
10380    (set_attr "mode" "DI")])
10381
10382 (define_split
10383   [(set (reg 17)
10384         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10385                  (const_int 0)))
10386    (set (match_operand:DI 0 "nonimmediate_operand" "")
10387         (not:DI (match_dup 1)))]
10388   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10389   [(parallel [(set (reg:CCNO FLAGS_REG)
10390                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10391                                  (const_int 0)))
10392               (set (match_dup 0)
10393                    (xor:DI (match_dup 1) (const_int -1)))])]
10394   "")
10395
10396 (define_expand "one_cmplsi2"
10397   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10398         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10399   ""
10400   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10401
10402 (define_insn "*one_cmplsi2_1"
10403   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10404         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10405   "ix86_unary_operator_ok (NOT, SImode, operands)"
10406   "not{l}\t%0"
10407   [(set_attr "type" "negnot")
10408    (set_attr "mode" "SI")])
10409
10410 ;; ??? Currently never generated - xor is used instead.
10411 (define_insn "*one_cmplsi2_1_zext"
10412   [(set (match_operand:DI 0 "register_operand" "=r")
10413         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10414   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10415   "not{l}\t%k0"
10416   [(set_attr "type" "negnot")
10417    (set_attr "mode" "SI")])
10418
10419 (define_insn "*one_cmplsi2_2"
10420   [(set (reg 17)
10421         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10422                  (const_int 0)))
10423    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10424         (not:SI (match_dup 1)))]
10425   "ix86_match_ccmode (insn, CCNOmode)
10426    && ix86_unary_operator_ok (NOT, SImode, operands)"
10427   "#"
10428   [(set_attr "type" "alu1")
10429    (set_attr "mode" "SI")])
10430
10431 (define_split
10432   [(set (reg 17)
10433         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10434                  (const_int 0)))
10435    (set (match_operand:SI 0 "nonimmediate_operand" "")
10436         (not:SI (match_dup 1)))]
10437   "ix86_match_ccmode (insn, CCNOmode)"
10438   [(parallel [(set (reg:CCNO FLAGS_REG)
10439                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10440                                  (const_int 0)))
10441               (set (match_dup 0)
10442                    (xor:SI (match_dup 1) (const_int -1)))])]
10443   "")
10444
10445 ;; ??? Currently never generated - xor is used instead.
10446 (define_insn "*one_cmplsi2_2_zext"
10447   [(set (reg 17)
10448         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10449                  (const_int 0)))
10450    (set (match_operand:DI 0 "register_operand" "=r")
10451         (zero_extend:DI (not:SI (match_dup 1))))]
10452   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10453    && ix86_unary_operator_ok (NOT, SImode, operands)"
10454   "#"
10455   [(set_attr "type" "alu1")
10456    (set_attr "mode" "SI")])
10457
10458 (define_split
10459   [(set (reg 17)
10460         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10461                  (const_int 0)))
10462    (set (match_operand:DI 0 "register_operand" "")
10463         (zero_extend:DI (not:SI (match_dup 1))))]
10464   "ix86_match_ccmode (insn, CCNOmode)"
10465   [(parallel [(set (reg:CCNO FLAGS_REG)
10466                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10467                                  (const_int 0)))
10468               (set (match_dup 0)
10469                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10470   "")
10471
10472 (define_expand "one_cmplhi2"
10473   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10474         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10475   "TARGET_HIMODE_MATH"
10476   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10477
10478 (define_insn "*one_cmplhi2_1"
10479   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10480         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10481   "ix86_unary_operator_ok (NOT, HImode, operands)"
10482   "not{w}\t%0"
10483   [(set_attr "type" "negnot")
10484    (set_attr "mode" "HI")])
10485
10486 (define_insn "*one_cmplhi2_2"
10487   [(set (reg 17)
10488         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10489                  (const_int 0)))
10490    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10491         (not:HI (match_dup 1)))]
10492   "ix86_match_ccmode (insn, CCNOmode)
10493    && ix86_unary_operator_ok (NEG, HImode, operands)"
10494   "#"
10495   [(set_attr "type" "alu1")
10496    (set_attr "mode" "HI")])
10497
10498 (define_split
10499   [(set (reg 17)
10500         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10501                  (const_int 0)))
10502    (set (match_operand:HI 0 "nonimmediate_operand" "")
10503         (not:HI (match_dup 1)))]
10504   "ix86_match_ccmode (insn, CCNOmode)"
10505   [(parallel [(set (reg:CCNO FLAGS_REG)
10506                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10507                                  (const_int 0)))
10508               (set (match_dup 0)
10509                    (xor:HI (match_dup 1) (const_int -1)))])]
10510   "")
10511
10512 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10513 (define_expand "one_cmplqi2"
10514   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10515         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10516   "TARGET_QIMODE_MATH"
10517   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10518
10519 (define_insn "*one_cmplqi2_1"
10520   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10521         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10522   "ix86_unary_operator_ok (NOT, QImode, operands)"
10523   "@
10524    not{b}\t%0
10525    not{l}\t%k0"
10526   [(set_attr "type" "negnot")
10527    (set_attr "mode" "QI,SI")])
10528
10529 (define_insn "*one_cmplqi2_2"
10530   [(set (reg 17)
10531         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10532                  (const_int 0)))
10533    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10534         (not:QI (match_dup 1)))]
10535   "ix86_match_ccmode (insn, CCNOmode)
10536    && ix86_unary_operator_ok (NOT, QImode, operands)"
10537   "#"
10538   [(set_attr "type" "alu1")
10539    (set_attr "mode" "QI")])
10540
10541 (define_split
10542   [(set (reg 17)
10543         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10544                  (const_int 0)))
10545    (set (match_operand:QI 0 "nonimmediate_operand" "")
10546         (not:QI (match_dup 1)))]
10547   "ix86_match_ccmode (insn, CCNOmode)"
10548   [(parallel [(set (reg:CCNO FLAGS_REG)
10549                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10550                                  (const_int 0)))
10551               (set (match_dup 0)
10552                    (xor:QI (match_dup 1) (const_int -1)))])]
10553   "")
10554 \f
10555 ;; Arithmetic shift instructions
10556
10557 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10558 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10559 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10560 ;; from the assembler input.
10561 ;;
10562 ;; This instruction shifts the target reg/mem as usual, but instead of
10563 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10564 ;; is a left shift double, bits are taken from the high order bits of
10565 ;; reg, else if the insn is a shift right double, bits are taken from the
10566 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10567 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10568 ;;
10569 ;; Since sh[lr]d does not change the `reg' operand, that is done
10570 ;; separately, making all shifts emit pairs of shift double and normal
10571 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10572 ;; support a 63 bit shift, each shift where the count is in a reg expands
10573 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10574 ;;
10575 ;; If the shift count is a constant, we need never emit more than one
10576 ;; shift pair, instead using moves and sign extension for counts greater
10577 ;; than 31.
10578
10579 (define_expand "ashldi3"
10580   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10581                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10582                               (match_operand:QI 2 "nonmemory_operand" "")))
10583               (clobber (reg:CC FLAGS_REG))])]
10584   ""
10585 {
10586   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10587     {
10588       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10589       DONE;
10590     }
10591   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10592   DONE;
10593 })
10594
10595 (define_insn "*ashldi3_1_rex64"
10596   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10597         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10598                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10599    (clobber (reg:CC FLAGS_REG))]
10600   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10601 {
10602   switch (get_attr_type (insn))
10603     {
10604     case TYPE_ALU:
10605       if (operands[2] != const1_rtx)
10606         abort ();
10607       if (!rtx_equal_p (operands[0], operands[1]))
10608         abort ();
10609       return "add{q}\t{%0, %0|%0, %0}";
10610
10611     case TYPE_LEA:
10612       if (GET_CODE (operands[2]) != CONST_INT
10613           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10614         abort ();
10615       operands[1] = gen_rtx_MULT (DImode, operands[1],
10616                                   GEN_INT (1 << INTVAL (operands[2])));
10617       return "lea{q}\t{%a1, %0|%0, %a1}";
10618
10619     default:
10620       if (REG_P (operands[2]))
10621         return "sal{q}\t{%b2, %0|%0, %b2}";
10622       else if (operands[2] == const1_rtx
10623                && (TARGET_SHIFT1 || optimize_size))
10624         return "sal{q}\t%0";
10625       else
10626         return "sal{q}\t{%2, %0|%0, %2}";
10627     }
10628 }
10629   [(set (attr "type")
10630      (cond [(eq_attr "alternative" "1")
10631               (const_string "lea")
10632             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10633                           (const_int 0))
10634                       (match_operand 0 "register_operand" ""))
10635                  (match_operand 2 "const1_operand" ""))
10636               (const_string "alu")
10637            ]
10638            (const_string "ishift")))
10639    (set_attr "mode" "DI")])
10640
10641 ;; Convert lea to the lea pattern to avoid flags dependency.
10642 (define_split
10643   [(set (match_operand:DI 0 "register_operand" "")
10644         (ashift:DI (match_operand:DI 1 "register_operand" "")
10645                    (match_operand:QI 2 "immediate_operand" "")))
10646    (clobber (reg:CC FLAGS_REG))]
10647   "TARGET_64BIT && reload_completed
10648    && true_regnum (operands[0]) != true_regnum (operands[1])"
10649   [(set (match_dup 0)
10650         (mult:DI (match_dup 1)
10651                  (match_dup 2)))]
10652   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10653
10654 ;; This pattern can't accept a variable shift count, since shifts by
10655 ;; zero don't affect the flags.  We assume that shifts by constant
10656 ;; zero are optimized away.
10657 (define_insn "*ashldi3_cmp_rex64"
10658   [(set (reg 17)
10659         (compare
10660           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10661                      (match_operand:QI 2 "immediate_operand" "e"))
10662           (const_int 0)))
10663    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10664         (ashift:DI (match_dup 1) (match_dup 2)))]
10665   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10666    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10667 {
10668   switch (get_attr_type (insn))
10669     {
10670     case TYPE_ALU:
10671       if (operands[2] != const1_rtx)
10672         abort ();
10673       return "add{q}\t{%0, %0|%0, %0}";
10674
10675     default:
10676       if (REG_P (operands[2]))
10677         return "sal{q}\t{%b2, %0|%0, %b2}";
10678       else if (operands[2] == const1_rtx
10679                && (TARGET_SHIFT1 || optimize_size))
10680         return "sal{q}\t%0";
10681       else
10682         return "sal{q}\t{%2, %0|%0, %2}";
10683     }
10684 }
10685   [(set (attr "type")
10686      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10687                           (const_int 0))
10688                       (match_operand 0 "register_operand" ""))
10689                  (match_operand 2 "const1_operand" ""))
10690               (const_string "alu")
10691            ]
10692            (const_string "ishift")))
10693    (set_attr "mode" "DI")])
10694
10695 (define_insn "ashldi3_1"
10696   [(set (match_operand:DI 0 "register_operand" "=r")
10697         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10698                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10699    (clobber (match_scratch:SI 3 "=&r"))
10700    (clobber (reg:CC FLAGS_REG))]
10701   "!TARGET_64BIT && TARGET_CMOVE"
10702   "#"
10703   [(set_attr "type" "multi")])
10704
10705 (define_insn "*ashldi3_2"
10706   [(set (match_operand:DI 0 "register_operand" "=r")
10707         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10708                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10709    (clobber (reg:CC FLAGS_REG))]
10710   "!TARGET_64BIT"
10711   "#"
10712   [(set_attr "type" "multi")])
10713
10714 (define_split
10715   [(set (match_operand:DI 0 "register_operand" "")
10716         (ashift:DI (match_operand:DI 1 "register_operand" "")
10717                    (match_operand:QI 2 "nonmemory_operand" "")))
10718    (clobber (match_scratch:SI 3 ""))
10719    (clobber (reg:CC FLAGS_REG))]
10720   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10721   [(const_int 0)]
10722   "ix86_split_ashldi (operands, operands[3]); DONE;")
10723
10724 (define_split
10725   [(set (match_operand:DI 0 "register_operand" "")
10726         (ashift:DI (match_operand:DI 1 "register_operand" "")
10727                    (match_operand:QI 2 "nonmemory_operand" "")))
10728    (clobber (reg:CC FLAGS_REG))]
10729   "!TARGET_64BIT && reload_completed"
10730   [(const_int 0)]
10731   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10732
10733 (define_insn "x86_shld_1"
10734   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10735         (ior:SI (ashift:SI (match_dup 0)
10736                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10737                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10738                   (minus:QI (const_int 32) (match_dup 2)))))
10739    (clobber (reg:CC FLAGS_REG))]
10740   ""
10741   "@
10742    shld{l}\t{%2, %1, %0|%0, %1, %2}
10743    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10744   [(set_attr "type" "ishift")
10745    (set_attr "prefix_0f" "1")
10746    (set_attr "mode" "SI")
10747    (set_attr "pent_pair" "np")
10748    (set_attr "athlon_decode" "vector")])
10749
10750 (define_expand "x86_shift_adj_1"
10751   [(set (reg:CCZ FLAGS_REG)
10752         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10753                              (const_int 32))
10754                      (const_int 0)))
10755    (set (match_operand:SI 0 "register_operand" "")
10756         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10757                          (match_operand:SI 1 "register_operand" "")
10758                          (match_dup 0)))
10759    (set (match_dup 1)
10760         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10761                          (match_operand:SI 3 "register_operand" "r")
10762                          (match_dup 1)))]
10763   "TARGET_CMOVE"
10764   "")
10765
10766 (define_expand "x86_shift_adj_2"
10767   [(use (match_operand:SI 0 "register_operand" ""))
10768    (use (match_operand:SI 1 "register_operand" ""))
10769    (use (match_operand:QI 2 "register_operand" ""))]
10770   ""
10771 {
10772   rtx label = gen_label_rtx ();
10773   rtx tmp;
10774
10775   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10776
10777   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10778   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10779   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10780                               gen_rtx_LABEL_REF (VOIDmode, label),
10781                               pc_rtx);
10782   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10783   JUMP_LABEL (tmp) = label;
10784
10785   emit_move_insn (operands[0], operands[1]);
10786   emit_move_insn (operands[1], const0_rtx);
10787
10788   emit_label (label);
10789   LABEL_NUSES (label) = 1;
10790
10791   DONE;
10792 })
10793
10794 (define_expand "ashlsi3"
10795   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10796         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10797                    (match_operand:QI 2 "nonmemory_operand" "")))
10798    (clobber (reg:CC FLAGS_REG))]
10799   ""
10800   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10801
10802 (define_insn "*ashlsi3_1"
10803   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10804         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10805                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10806    (clobber (reg:CC FLAGS_REG))]
10807   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10808 {
10809   switch (get_attr_type (insn))
10810     {
10811     case TYPE_ALU:
10812       if (operands[2] != const1_rtx)
10813         abort ();
10814       if (!rtx_equal_p (operands[0], operands[1]))
10815         abort ();
10816       return "add{l}\t{%0, %0|%0, %0}";
10817
10818     case TYPE_LEA:
10819       return "#";
10820
10821     default:
10822       if (REG_P (operands[2]))
10823         return "sal{l}\t{%b2, %0|%0, %b2}";
10824       else if (operands[2] == const1_rtx
10825                && (TARGET_SHIFT1 || optimize_size))
10826         return "sal{l}\t%0";
10827       else
10828         return "sal{l}\t{%2, %0|%0, %2}";
10829     }
10830 }
10831   [(set (attr "type")
10832      (cond [(eq_attr "alternative" "1")
10833               (const_string "lea")
10834             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10835                           (const_int 0))
10836                       (match_operand 0 "register_operand" ""))
10837                  (match_operand 2 "const1_operand" ""))
10838               (const_string "alu")
10839            ]
10840            (const_string "ishift")))
10841    (set_attr "mode" "SI")])
10842
10843 ;; Convert lea to the lea pattern to avoid flags dependency.
10844 (define_split
10845   [(set (match_operand 0 "register_operand" "")
10846         (ashift (match_operand 1 "index_register_operand" "")
10847                 (match_operand:QI 2 "const_int_operand" "")))
10848    (clobber (reg:CC FLAGS_REG))]
10849   "reload_completed
10850    && true_regnum (operands[0]) != true_regnum (operands[1])"
10851   [(const_int 0)]
10852 {
10853   rtx pat;
10854   operands[0] = gen_lowpart (SImode, operands[0]);
10855   operands[1] = gen_lowpart (Pmode, operands[1]);
10856   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10857   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10858   if (Pmode != SImode)
10859     pat = gen_rtx_SUBREG (SImode, pat, 0);
10860   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10861   DONE;
10862 })
10863
10864 ;; Rare case of shifting RSP is handled by generating move and shift
10865 (define_split
10866   [(set (match_operand 0 "register_operand" "")
10867         (ashift (match_operand 1 "register_operand" "")
10868                 (match_operand:QI 2 "const_int_operand" "")))
10869    (clobber (reg:CC FLAGS_REG))]
10870   "reload_completed
10871    && true_regnum (operands[0]) != true_regnum (operands[1])"
10872   [(const_int 0)]
10873 {
10874   rtx pat, clob;
10875   emit_move_insn (operands[1], operands[0]);
10876   pat = gen_rtx_SET (VOIDmode, operands[0],
10877                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10878                                      operands[0], operands[2]));
10879   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10880   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10881   DONE;
10882 })
10883
10884 (define_insn "*ashlsi3_1_zext"
10885   [(set (match_operand:DI 0 "register_operand" "=r,r")
10886         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10887                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10888    (clobber (reg:CC FLAGS_REG))]
10889   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10890 {
10891   switch (get_attr_type (insn))
10892     {
10893     case TYPE_ALU:
10894       if (operands[2] != const1_rtx)
10895         abort ();
10896       return "add{l}\t{%k0, %k0|%k0, %k0}";
10897
10898     case TYPE_LEA:
10899       return "#";
10900
10901     default:
10902       if (REG_P (operands[2]))
10903         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10904       else if (operands[2] == const1_rtx
10905                && (TARGET_SHIFT1 || optimize_size))
10906         return "sal{l}\t%k0";
10907       else
10908         return "sal{l}\t{%2, %k0|%k0, %2}";
10909     }
10910 }
10911   [(set (attr "type")
10912      (cond [(eq_attr "alternative" "1")
10913               (const_string "lea")
10914             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10915                      (const_int 0))
10916                  (match_operand 2 "const1_operand" ""))
10917               (const_string "alu")
10918            ]
10919            (const_string "ishift")))
10920    (set_attr "mode" "SI")])
10921
10922 ;; Convert lea to the lea pattern to avoid flags dependency.
10923 (define_split
10924   [(set (match_operand:DI 0 "register_operand" "")
10925         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10926                                 (match_operand:QI 2 "const_int_operand" ""))))
10927    (clobber (reg:CC FLAGS_REG))]
10928   "TARGET_64BIT && reload_completed
10929    && true_regnum (operands[0]) != true_regnum (operands[1])"
10930   [(set (match_dup 0) (zero_extend:DI
10931                         (subreg:SI (mult:SI (match_dup 1)
10932                                             (match_dup 2)) 0)))]
10933 {
10934   operands[1] = gen_lowpart (Pmode, operands[1]);
10935   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10936 })
10937
10938 ;; This pattern can't accept a variable shift count, since shifts by
10939 ;; zero don't affect the flags.  We assume that shifts by constant
10940 ;; zero are optimized away.
10941 (define_insn "*ashlsi3_cmp"
10942   [(set (reg 17)
10943         (compare
10944           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10945                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10946           (const_int 0)))
10947    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10948         (ashift:SI (match_dup 1) (match_dup 2)))]
10949   "ix86_match_ccmode (insn, CCGOCmode)
10950    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10951 {
10952   switch (get_attr_type (insn))
10953     {
10954     case TYPE_ALU:
10955       if (operands[2] != const1_rtx)
10956         abort ();
10957       return "add{l}\t{%0, %0|%0, %0}";
10958
10959     default:
10960       if (REG_P (operands[2]))
10961         return "sal{l}\t{%b2, %0|%0, %b2}";
10962       else if (operands[2] == const1_rtx
10963                && (TARGET_SHIFT1 || optimize_size))
10964         return "sal{l}\t%0";
10965       else
10966         return "sal{l}\t{%2, %0|%0, %2}";
10967     }
10968 }
10969   [(set (attr "type")
10970      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10971                           (const_int 0))
10972                       (match_operand 0 "register_operand" ""))
10973                  (match_operand 2 "const1_operand" ""))
10974               (const_string "alu")
10975            ]
10976            (const_string "ishift")))
10977    (set_attr "mode" "SI")])
10978
10979 (define_insn "*ashlsi3_cmp_zext"
10980   [(set (reg 17)
10981         (compare
10982           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10983                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10984           (const_int 0)))
10985    (set (match_operand:DI 0 "register_operand" "=r")
10986         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10987   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10988    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10989 {
10990   switch (get_attr_type (insn))
10991     {
10992     case TYPE_ALU:
10993       if (operands[2] != const1_rtx)
10994         abort ();
10995       return "add{l}\t{%k0, %k0|%k0, %k0}";
10996
10997     default:
10998       if (REG_P (operands[2]))
10999         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11000       else if (operands[2] == const1_rtx
11001                && (TARGET_SHIFT1 || optimize_size))
11002         return "sal{l}\t%k0";
11003       else
11004         return "sal{l}\t{%2, %k0|%k0, %2}";
11005     }
11006 }
11007   [(set (attr "type")
11008      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11009                      (const_int 0))
11010                  (match_operand 2 "const1_operand" ""))
11011               (const_string "alu")
11012            ]
11013            (const_string "ishift")))
11014    (set_attr "mode" "SI")])
11015
11016 (define_expand "ashlhi3"
11017   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11018         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11019                    (match_operand:QI 2 "nonmemory_operand" "")))
11020    (clobber (reg:CC FLAGS_REG))]
11021   "TARGET_HIMODE_MATH"
11022   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11023
11024 (define_insn "*ashlhi3_1_lea"
11025   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11026         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11027                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11028    (clobber (reg:CC FLAGS_REG))]
11029   "!TARGET_PARTIAL_REG_STALL
11030    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11031 {
11032   switch (get_attr_type (insn))
11033     {
11034     case TYPE_LEA:
11035       return "#";
11036     case TYPE_ALU:
11037       if (operands[2] != const1_rtx)
11038         abort ();
11039       return "add{w}\t{%0, %0|%0, %0}";
11040
11041     default:
11042       if (REG_P (operands[2]))
11043         return "sal{w}\t{%b2, %0|%0, %b2}";
11044       else if (operands[2] == const1_rtx
11045                && (TARGET_SHIFT1 || optimize_size))
11046         return "sal{w}\t%0";
11047       else
11048         return "sal{w}\t{%2, %0|%0, %2}";
11049     }
11050 }
11051   [(set (attr "type")
11052      (cond [(eq_attr "alternative" "1")
11053               (const_string "lea")
11054             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11055                           (const_int 0))
11056                       (match_operand 0 "register_operand" ""))
11057                  (match_operand 2 "const1_operand" ""))
11058               (const_string "alu")
11059            ]
11060            (const_string "ishift")))
11061    (set_attr "mode" "HI,SI")])
11062
11063 (define_insn "*ashlhi3_1"
11064   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11065         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11066                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11067    (clobber (reg:CC FLAGS_REG))]
11068   "TARGET_PARTIAL_REG_STALL
11069    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11070 {
11071   switch (get_attr_type (insn))
11072     {
11073     case TYPE_ALU:
11074       if (operands[2] != const1_rtx)
11075         abort ();
11076       return "add{w}\t{%0, %0|%0, %0}";
11077
11078     default:
11079       if (REG_P (operands[2]))
11080         return "sal{w}\t{%b2, %0|%0, %b2}";
11081       else if (operands[2] == const1_rtx
11082                && (TARGET_SHIFT1 || optimize_size))
11083         return "sal{w}\t%0";
11084       else
11085         return "sal{w}\t{%2, %0|%0, %2}";
11086     }
11087 }
11088   [(set (attr "type")
11089      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11090                           (const_int 0))
11091                       (match_operand 0 "register_operand" ""))
11092                  (match_operand 2 "const1_operand" ""))
11093               (const_string "alu")
11094            ]
11095            (const_string "ishift")))
11096    (set_attr "mode" "HI")])
11097
11098 ;; This pattern can't accept a variable shift count, since shifts by
11099 ;; zero don't affect the flags.  We assume that shifts by constant
11100 ;; zero are optimized away.
11101 (define_insn "*ashlhi3_cmp"
11102   [(set (reg 17)
11103         (compare
11104           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11105                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11106           (const_int 0)))
11107    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11108         (ashift:HI (match_dup 1) (match_dup 2)))]
11109   "ix86_match_ccmode (insn, CCGOCmode)
11110    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11111 {
11112   switch (get_attr_type (insn))
11113     {
11114     case TYPE_ALU:
11115       if (operands[2] != const1_rtx)
11116         abort ();
11117       return "add{w}\t{%0, %0|%0, %0}";
11118
11119     default:
11120       if (REG_P (operands[2]))
11121         return "sal{w}\t{%b2, %0|%0, %b2}";
11122       else if (operands[2] == const1_rtx
11123                && (TARGET_SHIFT1 || optimize_size))
11124         return "sal{w}\t%0";
11125       else
11126         return "sal{w}\t{%2, %0|%0, %2}";
11127     }
11128 }
11129   [(set (attr "type")
11130      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11131                           (const_int 0))
11132                       (match_operand 0 "register_operand" ""))
11133                  (match_operand 2 "const1_operand" ""))
11134               (const_string "alu")
11135            ]
11136            (const_string "ishift")))
11137    (set_attr "mode" "HI")])
11138
11139 (define_expand "ashlqi3"
11140   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11141         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11142                    (match_operand:QI 2 "nonmemory_operand" "")))
11143    (clobber (reg:CC FLAGS_REG))]
11144   "TARGET_QIMODE_MATH"
11145   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11146
11147 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11148
11149 (define_insn "*ashlqi3_1_lea"
11150   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11151         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11152                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11153    (clobber (reg:CC FLAGS_REG))]
11154   "!TARGET_PARTIAL_REG_STALL
11155    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11156 {
11157   switch (get_attr_type (insn))
11158     {
11159     case TYPE_LEA:
11160       return "#";
11161     case TYPE_ALU:
11162       if (operands[2] != const1_rtx)
11163         abort ();
11164       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11165         return "add{l}\t{%k0, %k0|%k0, %k0}";
11166       else
11167         return "add{b}\t{%0, %0|%0, %0}";
11168
11169     default:
11170       if (REG_P (operands[2]))
11171         {
11172           if (get_attr_mode (insn) == MODE_SI)
11173             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11174           else
11175             return "sal{b}\t{%b2, %0|%0, %b2}";
11176         }
11177       else if (operands[2] == const1_rtx
11178                && (TARGET_SHIFT1 || optimize_size))
11179         {
11180           if (get_attr_mode (insn) == MODE_SI)
11181             return "sal{l}\t%0";
11182           else
11183             return "sal{b}\t%0";
11184         }
11185       else
11186         {
11187           if (get_attr_mode (insn) == MODE_SI)
11188             return "sal{l}\t{%2, %k0|%k0, %2}";
11189           else
11190             return "sal{b}\t{%2, %0|%0, %2}";
11191         }
11192     }
11193 }
11194   [(set (attr "type")
11195      (cond [(eq_attr "alternative" "2")
11196               (const_string "lea")
11197             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11198                           (const_int 0))
11199                       (match_operand 0 "register_operand" ""))
11200                  (match_operand 2 "const1_operand" ""))
11201               (const_string "alu")
11202            ]
11203            (const_string "ishift")))
11204    (set_attr "mode" "QI,SI,SI")])
11205
11206 (define_insn "*ashlqi3_1"
11207   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11208         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11209                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11210    (clobber (reg:CC FLAGS_REG))]
11211   "TARGET_PARTIAL_REG_STALL
11212    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11213 {
11214   switch (get_attr_type (insn))
11215     {
11216     case TYPE_ALU:
11217       if (operands[2] != const1_rtx)
11218         abort ();
11219       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11220         return "add{l}\t{%k0, %k0|%k0, %k0}";
11221       else
11222         return "add{b}\t{%0, %0|%0, %0}";
11223
11224     default:
11225       if (REG_P (operands[2]))
11226         {
11227           if (get_attr_mode (insn) == MODE_SI)
11228             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11229           else
11230             return "sal{b}\t{%b2, %0|%0, %b2}";
11231         }
11232       else if (operands[2] == const1_rtx
11233                && (TARGET_SHIFT1 || optimize_size))
11234         {
11235           if (get_attr_mode (insn) == MODE_SI)
11236             return "sal{l}\t%0";
11237           else
11238             return "sal{b}\t%0";
11239         }
11240       else
11241         {
11242           if (get_attr_mode (insn) == MODE_SI)
11243             return "sal{l}\t{%2, %k0|%k0, %2}";
11244           else
11245             return "sal{b}\t{%2, %0|%0, %2}";
11246         }
11247     }
11248 }
11249   [(set (attr "type")
11250      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11251                           (const_int 0))
11252                       (match_operand 0 "register_operand" ""))
11253                  (match_operand 2 "const1_operand" ""))
11254               (const_string "alu")
11255            ]
11256            (const_string "ishift")))
11257    (set_attr "mode" "QI,SI")])
11258
11259 ;; This pattern can't accept a variable shift count, since shifts by
11260 ;; zero don't affect the flags.  We assume that shifts by constant
11261 ;; zero are optimized away.
11262 (define_insn "*ashlqi3_cmp"
11263   [(set (reg 17)
11264         (compare
11265           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11266                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11267           (const_int 0)))
11268    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11269         (ashift:QI (match_dup 1) (match_dup 2)))]
11270   "ix86_match_ccmode (insn, CCGOCmode)
11271    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11272 {
11273   switch (get_attr_type (insn))
11274     {
11275     case TYPE_ALU:
11276       if (operands[2] != const1_rtx)
11277         abort ();
11278       return "add{b}\t{%0, %0|%0, %0}";
11279
11280     default:
11281       if (REG_P (operands[2]))
11282         return "sal{b}\t{%b2, %0|%0, %b2}";
11283       else if (operands[2] == const1_rtx
11284                && (TARGET_SHIFT1 || optimize_size))
11285         return "sal{b}\t%0";
11286       else
11287         return "sal{b}\t{%2, %0|%0, %2}";
11288     }
11289 }
11290   [(set (attr "type")
11291      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11292                           (const_int 0))
11293                       (match_operand 0 "register_operand" ""))
11294                  (match_operand 2 "const1_operand" ""))
11295               (const_string "alu")
11296            ]
11297            (const_string "ishift")))
11298    (set_attr "mode" "QI")])
11299
11300 ;; See comment above `ashldi3' about how this works.
11301
11302 (define_expand "ashrdi3"
11303   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11304                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11305                                 (match_operand:QI 2 "nonmemory_operand" "")))
11306               (clobber (reg:CC FLAGS_REG))])]
11307   ""
11308 {
11309   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11310     {
11311       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11312       DONE;
11313     }
11314   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11315   DONE;
11316 })
11317
11318 (define_insn "ashrdi3_63_rex64"
11319   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11320         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11321                      (match_operand:DI 2 "const_int_operand" "i,i")))
11322    (clobber (reg:CC FLAGS_REG))]
11323   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11324    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11325   "@
11326    {cqto|cqo}
11327    sar{q}\t{%2, %0|%0, %2}"
11328   [(set_attr "type" "imovx,ishift")
11329    (set_attr "prefix_0f" "0,*")
11330    (set_attr "length_immediate" "0,*")
11331    (set_attr "modrm" "0,1")
11332    (set_attr "mode" "DI")])
11333
11334 (define_insn "*ashrdi3_1_one_bit_rex64"
11335   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11336         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11337                      (match_operand:QI 2 "const1_operand" "")))
11338    (clobber (reg:CC FLAGS_REG))]
11339   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11340    && (TARGET_SHIFT1 || optimize_size)"
11341   "sar{q}\t%0"
11342   [(set_attr "type" "ishift")
11343    (set (attr "length") 
11344      (if_then_else (match_operand:DI 0 "register_operand" "") 
11345         (const_string "2")
11346         (const_string "*")))])
11347
11348 (define_insn "*ashrdi3_1_rex64"
11349   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11350         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11351                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11352    (clobber (reg:CC FLAGS_REG))]
11353   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11354   "@
11355    sar{q}\t{%2, %0|%0, %2}
11356    sar{q}\t{%b2, %0|%0, %b2}"
11357   [(set_attr "type" "ishift")
11358    (set_attr "mode" "DI")])
11359
11360 ;; This pattern can't accept a variable shift count, since shifts by
11361 ;; zero don't affect the flags.  We assume that shifts by constant
11362 ;; zero are optimized away.
11363 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11364   [(set (reg 17)
11365         (compare
11366           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11367                        (match_operand:QI 2 "const1_operand" ""))
11368           (const_int 0)))
11369    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11370         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11371   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11372    && (TARGET_SHIFT1 || optimize_size)
11373    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11374   "sar{q}\t%0"
11375   [(set_attr "type" "ishift")
11376    (set (attr "length") 
11377      (if_then_else (match_operand:DI 0 "register_operand" "") 
11378         (const_string "2")
11379         (const_string "*")))])
11380
11381 ;; This pattern can't accept a variable shift count, since shifts by
11382 ;; zero don't affect the flags.  We assume that shifts by constant
11383 ;; zero are optimized away.
11384 (define_insn "*ashrdi3_cmp_rex64"
11385   [(set (reg 17)
11386         (compare
11387           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11388                        (match_operand:QI 2 "const_int_operand" "n"))
11389           (const_int 0)))
11390    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11391         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11392   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11393    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11394   "sar{q}\t{%2, %0|%0, %2}"
11395   [(set_attr "type" "ishift")
11396    (set_attr "mode" "DI")])
11397
11398
11399 (define_insn "ashrdi3_1"
11400   [(set (match_operand:DI 0 "register_operand" "=r")
11401         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11402                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11403    (clobber (match_scratch:SI 3 "=&r"))
11404    (clobber (reg:CC FLAGS_REG))]
11405   "!TARGET_64BIT && TARGET_CMOVE"
11406   "#"
11407   [(set_attr "type" "multi")])
11408
11409 (define_insn "*ashrdi3_2"
11410   [(set (match_operand:DI 0 "register_operand" "=r")
11411         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11412                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11413    (clobber (reg:CC FLAGS_REG))]
11414   "!TARGET_64BIT"
11415   "#"
11416   [(set_attr "type" "multi")])
11417
11418 (define_split
11419   [(set (match_operand:DI 0 "register_operand" "")
11420         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11421                      (match_operand:QI 2 "nonmemory_operand" "")))
11422    (clobber (match_scratch:SI 3 ""))
11423    (clobber (reg:CC FLAGS_REG))]
11424   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11425   [(const_int 0)]
11426   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11427
11428 (define_split
11429   [(set (match_operand:DI 0 "register_operand" "")
11430         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11431                      (match_operand:QI 2 "nonmemory_operand" "")))
11432    (clobber (reg:CC FLAGS_REG))]
11433   "!TARGET_64BIT && reload_completed"
11434   [(const_int 0)]
11435   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11436
11437 (define_insn "x86_shrd_1"
11438   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11439         (ior:SI (ashiftrt:SI (match_dup 0)
11440                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11441                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11442                   (minus:QI (const_int 32) (match_dup 2)))))
11443    (clobber (reg:CC FLAGS_REG))]
11444   ""
11445   "@
11446    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11447    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11448   [(set_attr "type" "ishift")
11449    (set_attr "prefix_0f" "1")
11450    (set_attr "pent_pair" "np")
11451    (set_attr "mode" "SI")])
11452
11453 (define_expand "x86_shift_adj_3"
11454   [(use (match_operand:SI 0 "register_operand" ""))
11455    (use (match_operand:SI 1 "register_operand" ""))
11456    (use (match_operand:QI 2 "register_operand" ""))]
11457   ""
11458 {
11459   rtx label = gen_label_rtx ();
11460   rtx tmp;
11461
11462   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11463
11464   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11465   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11466   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11467                               gen_rtx_LABEL_REF (VOIDmode, label),
11468                               pc_rtx);
11469   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11470   JUMP_LABEL (tmp) = label;
11471
11472   emit_move_insn (operands[0], operands[1]);
11473   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11474
11475   emit_label (label);
11476   LABEL_NUSES (label) = 1;
11477
11478   DONE;
11479 })
11480
11481 (define_insn "ashrsi3_31"
11482   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11483         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11484                      (match_operand:SI 2 "const_int_operand" "i,i")))
11485    (clobber (reg:CC FLAGS_REG))]
11486   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11487    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11488   "@
11489    {cltd|cdq}
11490    sar{l}\t{%2, %0|%0, %2}"
11491   [(set_attr "type" "imovx,ishift")
11492    (set_attr "prefix_0f" "0,*")
11493    (set_attr "length_immediate" "0,*")
11494    (set_attr "modrm" "0,1")
11495    (set_attr "mode" "SI")])
11496
11497 (define_insn "*ashrsi3_31_zext"
11498   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11499         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11500                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11501    (clobber (reg:CC FLAGS_REG))]
11502   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11503    && INTVAL (operands[2]) == 31
11504    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11505   "@
11506    {cltd|cdq}
11507    sar{l}\t{%2, %k0|%k0, %2}"
11508   [(set_attr "type" "imovx,ishift")
11509    (set_attr "prefix_0f" "0,*")
11510    (set_attr "length_immediate" "0,*")
11511    (set_attr "modrm" "0,1")
11512    (set_attr "mode" "SI")])
11513
11514 (define_expand "ashrsi3"
11515   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11516         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11517                      (match_operand:QI 2 "nonmemory_operand" "")))
11518    (clobber (reg:CC FLAGS_REG))]
11519   ""
11520   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11521
11522 (define_insn "*ashrsi3_1_one_bit"
11523   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11524         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11525                      (match_operand:QI 2 "const1_operand" "")))
11526    (clobber (reg:CC FLAGS_REG))]
11527   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11528    && (TARGET_SHIFT1 || optimize_size)"
11529   "sar{l}\t%0"
11530   [(set_attr "type" "ishift")
11531    (set (attr "length") 
11532      (if_then_else (match_operand:SI 0 "register_operand" "") 
11533         (const_string "2")
11534         (const_string "*")))])
11535
11536 (define_insn "*ashrsi3_1_one_bit_zext"
11537   [(set (match_operand:DI 0 "register_operand" "=r")
11538         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11539                                      (match_operand:QI 2 "const1_operand" ""))))
11540    (clobber (reg:CC FLAGS_REG))]
11541   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11542    && (TARGET_SHIFT1 || optimize_size)"
11543   "sar{l}\t%k0"
11544   [(set_attr "type" "ishift")
11545    (set_attr "length" "2")])
11546
11547 (define_insn "*ashrsi3_1"
11548   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11549         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11550                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11551    (clobber (reg:CC FLAGS_REG))]
11552   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11553   "@
11554    sar{l}\t{%2, %0|%0, %2}
11555    sar{l}\t{%b2, %0|%0, %b2}"
11556   [(set_attr "type" "ishift")
11557    (set_attr "mode" "SI")])
11558
11559 (define_insn "*ashrsi3_1_zext"
11560   [(set (match_operand:DI 0 "register_operand" "=r,r")
11561         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11562                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11563    (clobber (reg:CC FLAGS_REG))]
11564   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11565   "@
11566    sar{l}\t{%2, %k0|%k0, %2}
11567    sar{l}\t{%b2, %k0|%k0, %b2}"
11568   [(set_attr "type" "ishift")
11569    (set_attr "mode" "SI")])
11570
11571 ;; This pattern can't accept a variable shift count, since shifts by
11572 ;; zero don't affect the flags.  We assume that shifts by constant
11573 ;; zero are optimized away.
11574 (define_insn "*ashrsi3_one_bit_cmp"
11575   [(set (reg 17)
11576         (compare
11577           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11578                        (match_operand:QI 2 "const1_operand" ""))
11579           (const_int 0)))
11580    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11581         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11582   "ix86_match_ccmode (insn, CCGOCmode)
11583    && (TARGET_SHIFT1 || optimize_size)
11584    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11585   "sar{l}\t%0"
11586   [(set_attr "type" "ishift")
11587    (set (attr "length") 
11588      (if_then_else (match_operand:SI 0 "register_operand" "") 
11589         (const_string "2")
11590         (const_string "*")))])
11591
11592 (define_insn "*ashrsi3_one_bit_cmp_zext"
11593   [(set (reg 17)
11594         (compare
11595           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11596                        (match_operand:QI 2 "const1_operand" ""))
11597           (const_int 0)))
11598    (set (match_operand:DI 0 "register_operand" "=r")
11599         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11600   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11601    && (TARGET_SHIFT1 || optimize_size)
11602    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11603   "sar{l}\t%k0"
11604   [(set_attr "type" "ishift")
11605    (set_attr "length" "2")])
11606
11607 ;; This pattern can't accept a variable shift count, since shifts by
11608 ;; zero don't affect the flags.  We assume that shifts by constant
11609 ;; zero are optimized away.
11610 (define_insn "*ashrsi3_cmp"
11611   [(set (reg 17)
11612         (compare
11613           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11614                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11615           (const_int 0)))
11616    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11617         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11618   "ix86_match_ccmode (insn, CCGOCmode)
11619    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11620   "sar{l}\t{%2, %0|%0, %2}"
11621   [(set_attr "type" "ishift")
11622    (set_attr "mode" "SI")])
11623
11624 (define_insn "*ashrsi3_cmp_zext"
11625   [(set (reg 17)
11626         (compare
11627           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11628                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11629           (const_int 0)))
11630    (set (match_operand:DI 0 "register_operand" "=r")
11631         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11632   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11633    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11634   "sar{l}\t{%2, %k0|%k0, %2}"
11635   [(set_attr "type" "ishift")
11636    (set_attr "mode" "SI")])
11637
11638 (define_expand "ashrhi3"
11639   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11640         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11641                      (match_operand:QI 2 "nonmemory_operand" "")))
11642    (clobber (reg:CC FLAGS_REG))]
11643   "TARGET_HIMODE_MATH"
11644   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11645
11646 (define_insn "*ashrhi3_1_one_bit"
11647   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11648         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11649                      (match_operand:QI 2 "const1_operand" "")))
11650    (clobber (reg:CC FLAGS_REG))]
11651   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11652    && (TARGET_SHIFT1 || optimize_size)"
11653   "sar{w}\t%0"
11654   [(set_attr "type" "ishift")
11655    (set (attr "length") 
11656      (if_then_else (match_operand 0 "register_operand" "") 
11657         (const_string "2")
11658         (const_string "*")))])
11659
11660 (define_insn "*ashrhi3_1"
11661   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11662         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11663                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11664    (clobber (reg:CC FLAGS_REG))]
11665   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11666   "@
11667    sar{w}\t{%2, %0|%0, %2}
11668    sar{w}\t{%b2, %0|%0, %b2}"
11669   [(set_attr "type" "ishift")
11670    (set_attr "mode" "HI")])
11671
11672 ;; This pattern can't accept a variable shift count, since shifts by
11673 ;; zero don't affect the flags.  We assume that shifts by constant
11674 ;; zero are optimized away.
11675 (define_insn "*ashrhi3_one_bit_cmp"
11676   [(set (reg 17)
11677         (compare
11678           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11679                        (match_operand:QI 2 "const1_operand" ""))
11680           (const_int 0)))
11681    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11682         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11683   "ix86_match_ccmode (insn, CCGOCmode)
11684    && (TARGET_SHIFT1 || optimize_size)
11685    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11686   "sar{w}\t%0"
11687   [(set_attr "type" "ishift")
11688    (set (attr "length") 
11689      (if_then_else (match_operand 0 "register_operand" "") 
11690         (const_string "2")
11691         (const_string "*")))])
11692
11693 ;; This pattern can't accept a variable shift count, since shifts by
11694 ;; zero don't affect the flags.  We assume that shifts by constant
11695 ;; zero are optimized away.
11696 (define_insn "*ashrhi3_cmp"
11697   [(set (reg 17)
11698         (compare
11699           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11700                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11701           (const_int 0)))
11702    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11703         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11704   "ix86_match_ccmode (insn, CCGOCmode)
11705    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11706   "sar{w}\t{%2, %0|%0, %2}"
11707   [(set_attr "type" "ishift")
11708    (set_attr "mode" "HI")])
11709
11710 (define_expand "ashrqi3"
11711   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11712         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11713                      (match_operand:QI 2 "nonmemory_operand" "")))
11714    (clobber (reg:CC FLAGS_REG))]
11715   "TARGET_QIMODE_MATH"
11716   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11717
11718 (define_insn "*ashrqi3_1_one_bit"
11719   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11720         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11721                      (match_operand:QI 2 "const1_operand" "")))
11722    (clobber (reg:CC FLAGS_REG))]
11723   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11724    && (TARGET_SHIFT1 || optimize_size)"
11725   "sar{b}\t%0"
11726   [(set_attr "type" "ishift")
11727    (set (attr "length") 
11728      (if_then_else (match_operand 0 "register_operand" "") 
11729         (const_string "2")
11730         (const_string "*")))])
11731
11732 (define_insn "*ashrqi3_1_one_bit_slp"
11733   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11734         (ashiftrt:QI (match_dup 0)
11735                      (match_operand:QI 1 "const1_operand" "")))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11738    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11739    && (TARGET_SHIFT1 || optimize_size)"
11740   "sar{b}\t%0"
11741   [(set_attr "type" "ishift1")
11742    (set (attr "length") 
11743      (if_then_else (match_operand 0 "register_operand" "") 
11744         (const_string "2")
11745         (const_string "*")))])
11746
11747 (define_insn "*ashrqi3_1"
11748   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11749         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11750                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11751    (clobber (reg:CC FLAGS_REG))]
11752   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11753   "@
11754    sar{b}\t{%2, %0|%0, %2}
11755    sar{b}\t{%b2, %0|%0, %b2}"
11756   [(set_attr "type" "ishift")
11757    (set_attr "mode" "QI")])
11758
11759 (define_insn "*ashrqi3_1_slp"
11760   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11761         (ashiftrt:QI (match_dup 0)
11762                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11763    (clobber (reg:CC FLAGS_REG))]
11764   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11765    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11766   "@
11767    sar{b}\t{%1, %0|%0, %1}
11768    sar{b}\t{%b1, %0|%0, %b1}"
11769   [(set_attr "type" "ishift1")
11770    (set_attr "mode" "QI")])
11771
11772 ;; This pattern can't accept a variable shift count, since shifts by
11773 ;; zero don't affect the flags.  We assume that shifts by constant
11774 ;; zero are optimized away.
11775 (define_insn "*ashrqi3_one_bit_cmp"
11776   [(set (reg 17)
11777         (compare
11778           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11779                        (match_operand:QI 2 "const1_operand" "I"))
11780           (const_int 0)))
11781    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11782         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11783   "ix86_match_ccmode (insn, CCGOCmode)
11784    && (TARGET_SHIFT1 || optimize_size)
11785    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11786   "sar{b}\t%0"
11787   [(set_attr "type" "ishift")
11788    (set (attr "length") 
11789      (if_then_else (match_operand 0 "register_operand" "") 
11790         (const_string "2")
11791         (const_string "*")))])
11792
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags.  We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashrqi3_cmp"
11797   [(set (reg 17)
11798         (compare
11799           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11800                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11801           (const_int 0)))
11802    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11803         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11804   "ix86_match_ccmode (insn, CCGOCmode)
11805    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11806   "sar{b}\t{%2, %0|%0, %2}"
11807   [(set_attr "type" "ishift")
11808    (set_attr "mode" "QI")])
11809 \f
11810 ;; Logical shift instructions
11811
11812 ;; See comment above `ashldi3' about how this works.
11813
11814 (define_expand "lshrdi3"
11815   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11816                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11817                                 (match_operand:QI 2 "nonmemory_operand" "")))
11818               (clobber (reg:CC FLAGS_REG))])]
11819   ""
11820 {
11821   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11822     {
11823       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11824       DONE;
11825     }
11826   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11827   DONE;
11828 })
11829
11830 (define_insn "*lshrdi3_1_one_bit_rex64"
11831   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11832         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11833                      (match_operand:QI 2 "const1_operand" "")))
11834    (clobber (reg:CC FLAGS_REG))]
11835   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11836    && (TARGET_SHIFT1 || optimize_size)"
11837   "shr{q}\t%0"
11838   [(set_attr "type" "ishift")
11839    (set (attr "length") 
11840      (if_then_else (match_operand:DI 0 "register_operand" "") 
11841         (const_string "2")
11842         (const_string "*")))])
11843
11844 (define_insn "*lshrdi3_1_rex64"
11845   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11846         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11847                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11848    (clobber (reg:CC FLAGS_REG))]
11849   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11850   "@
11851    shr{q}\t{%2, %0|%0, %2}
11852    shr{q}\t{%b2, %0|%0, %b2}"
11853   [(set_attr "type" "ishift")
11854    (set_attr "mode" "DI")])
11855
11856 ;; This pattern can't accept a variable shift count, since shifts by
11857 ;; zero don't affect the flags.  We assume that shifts by constant
11858 ;; zero are optimized away.
11859 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11860   [(set (reg 17)
11861         (compare
11862           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11863                        (match_operand:QI 2 "const1_operand" ""))
11864           (const_int 0)))
11865    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11866         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11867   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11868    && (TARGET_SHIFT1 || optimize_size)
11869    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11870   "shr{q}\t%0"
11871   [(set_attr "type" "ishift")
11872    (set (attr "length") 
11873      (if_then_else (match_operand:DI 0 "register_operand" "") 
11874         (const_string "2")
11875         (const_string "*")))])
11876
11877 ;; This pattern can't accept a variable shift count, since shifts by
11878 ;; zero don't affect the flags.  We assume that shifts by constant
11879 ;; zero are optimized away.
11880 (define_insn "*lshrdi3_cmp_rex64"
11881   [(set (reg 17)
11882         (compare
11883           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11884                        (match_operand:QI 2 "const_int_operand" "e"))
11885           (const_int 0)))
11886    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11887         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11888   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11889    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11890   "shr{q}\t{%2, %0|%0, %2}"
11891   [(set_attr "type" "ishift")
11892    (set_attr "mode" "DI")])
11893
11894 (define_insn "lshrdi3_1"
11895   [(set (match_operand:DI 0 "register_operand" "=r")
11896         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11897                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11898    (clobber (match_scratch:SI 3 "=&r"))
11899    (clobber (reg:CC FLAGS_REG))]
11900   "!TARGET_64BIT && TARGET_CMOVE"
11901   "#"
11902   [(set_attr "type" "multi")])
11903
11904 (define_insn "*lshrdi3_2"
11905   [(set (match_operand:DI 0 "register_operand" "=r")
11906         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11907                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11908    (clobber (reg:CC FLAGS_REG))]
11909   "!TARGET_64BIT"
11910   "#"
11911   [(set_attr "type" "multi")])
11912
11913 (define_split 
11914   [(set (match_operand:DI 0 "register_operand" "")
11915         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11916                      (match_operand:QI 2 "nonmemory_operand" "")))
11917    (clobber (match_scratch:SI 3 ""))
11918    (clobber (reg:CC FLAGS_REG))]
11919   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11920   [(const_int 0)]
11921   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11922
11923 (define_split 
11924   [(set (match_operand:DI 0 "register_operand" "")
11925         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11926                      (match_operand:QI 2 "nonmemory_operand" "")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "!TARGET_64BIT && reload_completed"
11929   [(const_int 0)]
11930   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11931
11932 (define_expand "lshrsi3"
11933   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11934         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11935                      (match_operand:QI 2 "nonmemory_operand" "")))
11936    (clobber (reg:CC FLAGS_REG))]
11937   ""
11938   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11939
11940 (define_insn "*lshrsi3_1_one_bit"
11941   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11942         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11943                      (match_operand:QI 2 "const1_operand" "")))
11944    (clobber (reg:CC FLAGS_REG))]
11945   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11946    && (TARGET_SHIFT1 || optimize_size)"
11947   "shr{l}\t%0"
11948   [(set_attr "type" "ishift")
11949    (set (attr "length") 
11950      (if_then_else (match_operand:SI 0 "register_operand" "") 
11951         (const_string "2")
11952         (const_string "*")))])
11953
11954 (define_insn "*lshrsi3_1_one_bit_zext"
11955   [(set (match_operand:DI 0 "register_operand" "=r")
11956         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11957                      (match_operand:QI 2 "const1_operand" "")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11960    && (TARGET_SHIFT1 || optimize_size)"
11961   "shr{l}\t%k0"
11962   [(set_attr "type" "ishift")
11963    (set_attr "length" "2")])
11964
11965 (define_insn "*lshrsi3_1"
11966   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11967         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11968                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11971   "@
11972    shr{l}\t{%2, %0|%0, %2}
11973    shr{l}\t{%b2, %0|%0, %b2}"
11974   [(set_attr "type" "ishift")
11975    (set_attr "mode" "SI")])
11976
11977 (define_insn "*lshrsi3_1_zext"
11978   [(set (match_operand:DI 0 "register_operand" "=r,r")
11979         (zero_extend:DI
11980           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11981                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11982    (clobber (reg:CC FLAGS_REG))]
11983   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11984   "@
11985    shr{l}\t{%2, %k0|%k0, %2}
11986    shr{l}\t{%b2, %k0|%k0, %b2}"
11987   [(set_attr "type" "ishift")
11988    (set_attr "mode" "SI")])
11989
11990 ;; This pattern can't accept a variable shift count, since shifts by
11991 ;; zero don't affect the flags.  We assume that shifts by constant
11992 ;; zero are optimized away.
11993 (define_insn "*lshrsi3_one_bit_cmp"
11994   [(set (reg 17)
11995         (compare
11996           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11997                        (match_operand:QI 2 "const1_operand" ""))
11998           (const_int 0)))
11999    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12000         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12001   "ix86_match_ccmode (insn, CCGOCmode)
12002    && (TARGET_SHIFT1 || optimize_size)
12003    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12004   "shr{l}\t%0"
12005   [(set_attr "type" "ishift")
12006    (set (attr "length") 
12007      (if_then_else (match_operand:SI 0 "register_operand" "") 
12008         (const_string "2")
12009         (const_string "*")))])
12010
12011 (define_insn "*lshrsi3_cmp_one_bit_zext"
12012   [(set (reg 17)
12013         (compare
12014           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12015                        (match_operand:QI 2 "const1_operand" ""))
12016           (const_int 0)))
12017    (set (match_operand:DI 0 "register_operand" "=r")
12018         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12019   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12020    && (TARGET_SHIFT1 || optimize_size)
12021    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12022   "shr{l}\t%k0"
12023   [(set_attr "type" "ishift")
12024    (set_attr "length" "2")])
12025
12026 ;; This pattern can't accept a variable shift count, since shifts by
12027 ;; zero don't affect the flags.  We assume that shifts by constant
12028 ;; zero are optimized away.
12029 (define_insn "*lshrsi3_cmp"
12030   [(set (reg 17)
12031         (compare
12032           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12033                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12034           (const_int 0)))
12035    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12036         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12037   "ix86_match_ccmode (insn, CCGOCmode)
12038    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12039   "shr{l}\t{%2, %0|%0, %2}"
12040   [(set_attr "type" "ishift")
12041    (set_attr "mode" "SI")])
12042
12043 (define_insn "*lshrsi3_cmp_zext"
12044   [(set (reg 17)
12045         (compare
12046           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12047                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12048           (const_int 0)))
12049    (set (match_operand:DI 0 "register_operand" "=r")
12050         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12051   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12052    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12053   "shr{l}\t{%2, %k0|%k0, %2}"
12054   [(set_attr "type" "ishift")
12055    (set_attr "mode" "SI")])
12056
12057 (define_expand "lshrhi3"
12058   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12059         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12060                      (match_operand:QI 2 "nonmemory_operand" "")))
12061    (clobber (reg:CC FLAGS_REG))]
12062   "TARGET_HIMODE_MATH"
12063   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12064
12065 (define_insn "*lshrhi3_1_one_bit"
12066   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12067         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12068                      (match_operand:QI 2 "const1_operand" "")))
12069    (clobber (reg:CC FLAGS_REG))]
12070   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12071    && (TARGET_SHIFT1 || optimize_size)"
12072   "shr{w}\t%0"
12073   [(set_attr "type" "ishift")
12074    (set (attr "length") 
12075      (if_then_else (match_operand 0 "register_operand" "") 
12076         (const_string "2")
12077         (const_string "*")))])
12078
12079 (define_insn "*lshrhi3_1"
12080   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12081         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12082                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12085   "@
12086    shr{w}\t{%2, %0|%0, %2}
12087    shr{w}\t{%b2, %0|%0, %b2}"
12088   [(set_attr "type" "ishift")
12089    (set_attr "mode" "HI")])
12090
12091 ;; This pattern can't accept a variable shift count, since shifts by
12092 ;; zero don't affect the flags.  We assume that shifts by constant
12093 ;; zero are optimized away.
12094 (define_insn "*lshrhi3_one_bit_cmp"
12095   [(set (reg 17)
12096         (compare
12097           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12098                        (match_operand:QI 2 "const1_operand" ""))
12099           (const_int 0)))
12100    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12101         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12102   "ix86_match_ccmode (insn, CCGOCmode)
12103    && (TARGET_SHIFT1 || optimize_size)
12104    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12105   "shr{w}\t%0"
12106   [(set_attr "type" "ishift")
12107    (set (attr "length") 
12108      (if_then_else (match_operand:SI 0 "register_operand" "") 
12109         (const_string "2")
12110         (const_string "*")))])
12111
12112 ;; This pattern can't accept a variable shift count, since shifts by
12113 ;; zero don't affect the flags.  We assume that shifts by constant
12114 ;; zero are optimized away.
12115 (define_insn "*lshrhi3_cmp"
12116   [(set (reg 17)
12117         (compare
12118           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12119                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12120           (const_int 0)))
12121    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12122         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12123   "ix86_match_ccmode (insn, CCGOCmode)
12124    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12125   "shr{w}\t{%2, %0|%0, %2}"
12126   [(set_attr "type" "ishift")
12127    (set_attr "mode" "HI")])
12128
12129 (define_expand "lshrqi3"
12130   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12131         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12132                      (match_operand:QI 2 "nonmemory_operand" "")))
12133    (clobber (reg:CC FLAGS_REG))]
12134   "TARGET_QIMODE_MATH"
12135   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12136
12137 (define_insn "*lshrqi3_1_one_bit"
12138   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12139         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12140                      (match_operand:QI 2 "const1_operand" "")))
12141    (clobber (reg:CC FLAGS_REG))]
12142   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12143    && (TARGET_SHIFT1 || optimize_size)"
12144   "shr{b}\t%0"
12145   [(set_attr "type" "ishift")
12146    (set (attr "length") 
12147      (if_then_else (match_operand 0 "register_operand" "") 
12148         (const_string "2")
12149         (const_string "*")))])
12150
12151 (define_insn "*lshrqi3_1_one_bit_slp"
12152   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12153         (lshiftrt:QI (match_dup 0)
12154                      (match_operand:QI 1 "const1_operand" "")))
12155    (clobber (reg:CC FLAGS_REG))]
12156   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12157    && (TARGET_SHIFT1 || optimize_size)"
12158   "shr{b}\t%0"
12159   [(set_attr "type" "ishift1")
12160    (set (attr "length") 
12161      (if_then_else (match_operand 0 "register_operand" "") 
12162         (const_string "2")
12163         (const_string "*")))])
12164
12165 (define_insn "*lshrqi3_1"
12166   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12167         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12168                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12169    (clobber (reg:CC FLAGS_REG))]
12170   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12171   "@
12172    shr{b}\t{%2, %0|%0, %2}
12173    shr{b}\t{%b2, %0|%0, %b2}"
12174   [(set_attr "type" "ishift")
12175    (set_attr "mode" "QI")])
12176
12177 (define_insn "*lshrqi3_1_slp"
12178   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12179         (lshiftrt:QI (match_dup 0)
12180                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12181    (clobber (reg:CC FLAGS_REG))]
12182   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12183    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12184   "@
12185    shr{b}\t{%1, %0|%0, %1}
12186    shr{b}\t{%b1, %0|%0, %b1}"
12187   [(set_attr "type" "ishift1")
12188    (set_attr "mode" "QI")])
12189
12190 ;; This pattern can't accept a variable shift count, since shifts by
12191 ;; zero don't affect the flags.  We assume that shifts by constant
12192 ;; zero are optimized away.
12193 (define_insn "*lshrqi2_one_bit_cmp"
12194   [(set (reg 17)
12195         (compare
12196           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12197                        (match_operand:QI 2 "const1_operand" ""))
12198           (const_int 0)))
12199    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12200         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12201   "ix86_match_ccmode (insn, CCGOCmode)
12202    && (TARGET_SHIFT1 || optimize_size)
12203    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12204   "shr{b}\t%0"
12205   [(set_attr "type" "ishift")
12206    (set (attr "length") 
12207      (if_then_else (match_operand:SI 0 "register_operand" "") 
12208         (const_string "2")
12209         (const_string "*")))])
12210
12211 ;; This pattern can't accept a variable shift count, since shifts by
12212 ;; zero don't affect the flags.  We assume that shifts by constant
12213 ;; zero are optimized away.
12214 (define_insn "*lshrqi2_cmp"
12215   [(set (reg 17)
12216         (compare
12217           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12218                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12219           (const_int 0)))
12220    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12221         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12222   "ix86_match_ccmode (insn, CCGOCmode)
12223    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12224   "shr{b}\t{%2, %0|%0, %2}"
12225   [(set_attr "type" "ishift")
12226    (set_attr "mode" "QI")])
12227 \f
12228 ;; Rotate instructions
12229
12230 (define_expand "rotldi3"
12231   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12232         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12233                    (match_operand:QI 2 "nonmemory_operand" "")))
12234    (clobber (reg:CC FLAGS_REG))]
12235   "TARGET_64BIT"
12236   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12237
12238 (define_insn "*rotlsi3_1_one_bit_rex64"
12239   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12240         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12241                    (match_operand:QI 2 "const1_operand" "")))
12242    (clobber (reg:CC FLAGS_REG))]
12243   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12244    && (TARGET_SHIFT1 || optimize_size)"
12245   "rol{q}\t%0"
12246   [(set_attr "type" "rotate")
12247    (set (attr "length") 
12248      (if_then_else (match_operand:DI 0 "register_operand" "") 
12249         (const_string "2")
12250         (const_string "*")))])
12251
12252 (define_insn "*rotldi3_1_rex64"
12253   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12254         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12255                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12256    (clobber (reg:CC FLAGS_REG))]
12257   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12258   "@
12259    rol{q}\t{%2, %0|%0, %2}
12260    rol{q}\t{%b2, %0|%0, %b2}"
12261   [(set_attr "type" "rotate")
12262    (set_attr "mode" "DI")])
12263
12264 (define_expand "rotlsi3"
12265   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12266         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12267                    (match_operand:QI 2 "nonmemory_operand" "")))
12268    (clobber (reg:CC FLAGS_REG))]
12269   ""
12270   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12271
12272 (define_insn "*rotlsi3_1_one_bit"
12273   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12274         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12275                    (match_operand:QI 2 "const1_operand" "")))
12276    (clobber (reg:CC FLAGS_REG))]
12277   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12278    && (TARGET_SHIFT1 || optimize_size)"
12279   "rol{l}\t%0"
12280   [(set_attr "type" "rotate")
12281    (set (attr "length") 
12282      (if_then_else (match_operand:SI 0 "register_operand" "") 
12283         (const_string "2")
12284         (const_string "*")))])
12285
12286 (define_insn "*rotlsi3_1_one_bit_zext"
12287   [(set (match_operand:DI 0 "register_operand" "=r")
12288         (zero_extend:DI
12289           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12290                      (match_operand:QI 2 "const1_operand" ""))))
12291    (clobber (reg:CC FLAGS_REG))]
12292   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12293    && (TARGET_SHIFT1 || optimize_size)"
12294   "rol{l}\t%k0"
12295   [(set_attr "type" "rotate")
12296    (set_attr "length" "2")])
12297
12298 (define_insn "*rotlsi3_1"
12299   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12300         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12301                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12302    (clobber (reg:CC FLAGS_REG))]
12303   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12304   "@
12305    rol{l}\t{%2, %0|%0, %2}
12306    rol{l}\t{%b2, %0|%0, %b2}"
12307   [(set_attr "type" "rotate")
12308    (set_attr "mode" "SI")])
12309
12310 (define_insn "*rotlsi3_1_zext"
12311   [(set (match_operand:DI 0 "register_operand" "=r,r")
12312         (zero_extend:DI
12313           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12314                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12315    (clobber (reg:CC FLAGS_REG))]
12316   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12317   "@
12318    rol{l}\t{%2, %k0|%k0, %2}
12319    rol{l}\t{%b2, %k0|%k0, %b2}"
12320   [(set_attr "type" "rotate")
12321    (set_attr "mode" "SI")])
12322
12323 (define_expand "rotlhi3"
12324   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12325         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12326                    (match_operand:QI 2 "nonmemory_operand" "")))
12327    (clobber (reg:CC FLAGS_REG))]
12328   "TARGET_HIMODE_MATH"
12329   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12330
12331 (define_insn "*rotlhi3_1_one_bit"
12332   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12333         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12334                    (match_operand:QI 2 "const1_operand" "")))
12335    (clobber (reg:CC FLAGS_REG))]
12336   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12337    && (TARGET_SHIFT1 || optimize_size)"
12338   "rol{w}\t%0"
12339   [(set_attr "type" "rotate")
12340    (set (attr "length") 
12341      (if_then_else (match_operand 0 "register_operand" "") 
12342         (const_string "2")
12343         (const_string "*")))])
12344
12345 (define_insn "*rotlhi3_1"
12346   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12347         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12348                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12349    (clobber (reg:CC FLAGS_REG))]
12350   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12351   "@
12352    rol{w}\t{%2, %0|%0, %2}
12353    rol{w}\t{%b2, %0|%0, %b2}"
12354   [(set_attr "type" "rotate")
12355    (set_attr "mode" "HI")])
12356
12357 (define_expand "rotlqi3"
12358   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12359         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12360                    (match_operand:QI 2 "nonmemory_operand" "")))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "TARGET_QIMODE_MATH"
12363   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12364
12365 (define_insn "*rotlqi3_1_one_bit_slp"
12366   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12367         (rotate:QI (match_dup 0)
12368                    (match_operand:QI 1 "const1_operand" "")))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12371    && (TARGET_SHIFT1 || optimize_size)"
12372   "rol{b}\t%0"
12373   [(set_attr "type" "rotate1")
12374    (set (attr "length") 
12375      (if_then_else (match_operand 0 "register_operand" "") 
12376         (const_string "2")
12377         (const_string "*")))])
12378
12379 (define_insn "*rotlqi3_1_one_bit"
12380   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12381         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12382                    (match_operand:QI 2 "const1_operand" "")))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12385    && (TARGET_SHIFT1 || optimize_size)"
12386   "rol{b}\t%0"
12387   [(set_attr "type" "rotate")
12388    (set (attr "length") 
12389      (if_then_else (match_operand 0 "register_operand" "") 
12390         (const_string "2")
12391         (const_string "*")))])
12392
12393 (define_insn "*rotlqi3_1_slp"
12394   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12395         (rotate:QI (match_dup 0)
12396                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12397    (clobber (reg:CC FLAGS_REG))]
12398   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12399    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12400   "@
12401    rol{b}\t{%1, %0|%0, %1}
12402    rol{b}\t{%b1, %0|%0, %b1}"
12403   [(set_attr "type" "rotate1")
12404    (set_attr "mode" "QI")])
12405
12406 (define_insn "*rotlqi3_1"
12407   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12408         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12409                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12410    (clobber (reg:CC FLAGS_REG))]
12411   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12412   "@
12413    rol{b}\t{%2, %0|%0, %2}
12414    rol{b}\t{%b2, %0|%0, %b2}"
12415   [(set_attr "type" "rotate")
12416    (set_attr "mode" "QI")])
12417
12418 (define_expand "rotrdi3"
12419   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12420         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12421                      (match_operand:QI 2 "nonmemory_operand" "")))
12422    (clobber (reg:CC FLAGS_REG))]
12423   "TARGET_64BIT"
12424   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12425
12426 (define_insn "*rotrdi3_1_one_bit_rex64"
12427   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12428         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12429                      (match_operand:QI 2 "const1_operand" "")))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12432    && (TARGET_SHIFT1 || optimize_size)"
12433   "ror{q}\t%0"
12434   [(set_attr "type" "rotate")
12435    (set (attr "length") 
12436      (if_then_else (match_operand:DI 0 "register_operand" "") 
12437         (const_string "2")
12438         (const_string "*")))])
12439
12440 (define_insn "*rotrdi3_1_rex64"
12441   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12442         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12443                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12444    (clobber (reg:CC FLAGS_REG))]
12445   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12446   "@
12447    ror{q}\t{%2, %0|%0, %2}
12448    ror{q}\t{%b2, %0|%0, %b2}"
12449   [(set_attr "type" "rotate")
12450    (set_attr "mode" "DI")])
12451
12452 (define_expand "rotrsi3"
12453   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12454         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12455                      (match_operand:QI 2 "nonmemory_operand" "")))
12456    (clobber (reg:CC FLAGS_REG))]
12457   ""
12458   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12459
12460 (define_insn "*rotrsi3_1_one_bit"
12461   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12462         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12463                      (match_operand:QI 2 "const1_operand" "")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12466    && (TARGET_SHIFT1 || optimize_size)"
12467   "ror{l}\t%0"
12468   [(set_attr "type" "rotate")
12469    (set (attr "length") 
12470      (if_then_else (match_operand:SI 0 "register_operand" "") 
12471         (const_string "2")
12472         (const_string "*")))])
12473
12474 (define_insn "*rotrsi3_1_one_bit_zext"
12475   [(set (match_operand:DI 0 "register_operand" "=r")
12476         (zero_extend:DI
12477           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12478                        (match_operand:QI 2 "const1_operand" ""))))
12479    (clobber (reg:CC FLAGS_REG))]
12480   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12481    && (TARGET_SHIFT1 || optimize_size)"
12482   "ror{l}\t%k0"
12483   [(set_attr "type" "rotate")
12484    (set (attr "length") 
12485      (if_then_else (match_operand:SI 0 "register_operand" "") 
12486         (const_string "2")
12487         (const_string "*")))])
12488
12489 (define_insn "*rotrsi3_1"
12490   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12491         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12492                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12493    (clobber (reg:CC FLAGS_REG))]
12494   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12495   "@
12496    ror{l}\t{%2, %0|%0, %2}
12497    ror{l}\t{%b2, %0|%0, %b2}"
12498   [(set_attr "type" "rotate")
12499    (set_attr "mode" "SI")])
12500
12501 (define_insn "*rotrsi3_1_zext"
12502   [(set (match_operand:DI 0 "register_operand" "=r,r")
12503         (zero_extend:DI
12504           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12505                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12506    (clobber (reg:CC FLAGS_REG))]
12507   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12508   "@
12509    ror{l}\t{%2, %k0|%k0, %2}
12510    ror{l}\t{%b2, %k0|%k0, %b2}"
12511   [(set_attr "type" "rotate")
12512    (set_attr "mode" "SI")])
12513
12514 (define_expand "rotrhi3"
12515   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12516         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12517                      (match_operand:QI 2 "nonmemory_operand" "")))
12518    (clobber (reg:CC FLAGS_REG))]
12519   "TARGET_HIMODE_MATH"
12520   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12521
12522 (define_insn "*rotrhi3_one_bit"
12523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12524         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12525                      (match_operand:QI 2 "const1_operand" "")))
12526    (clobber (reg:CC FLAGS_REG))]
12527   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12528    && (TARGET_SHIFT1 || optimize_size)"
12529   "ror{w}\t%0"
12530   [(set_attr "type" "rotate")
12531    (set (attr "length") 
12532      (if_then_else (match_operand 0 "register_operand" "") 
12533         (const_string "2")
12534         (const_string "*")))])
12535
12536 (define_insn "*rotrhi3"
12537   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12538         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12539                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12540    (clobber (reg:CC FLAGS_REG))]
12541   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12542   "@
12543    ror{w}\t{%2, %0|%0, %2}
12544    ror{w}\t{%b2, %0|%0, %b2}"
12545   [(set_attr "type" "rotate")
12546    (set_attr "mode" "HI")])
12547
12548 (define_expand "rotrqi3"
12549   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12550         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12551                      (match_operand:QI 2 "nonmemory_operand" "")))
12552    (clobber (reg:CC FLAGS_REG))]
12553   "TARGET_QIMODE_MATH"
12554   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12555
12556 (define_insn "*rotrqi3_1_one_bit"
12557   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12558         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12559                      (match_operand:QI 2 "const1_operand" "")))
12560    (clobber (reg:CC FLAGS_REG))]
12561   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12562    && (TARGET_SHIFT1 || optimize_size)"
12563   "ror{b}\t%0"
12564   [(set_attr "type" "rotate")
12565    (set (attr "length") 
12566      (if_then_else (match_operand 0 "register_operand" "") 
12567         (const_string "2")
12568         (const_string "*")))])
12569
12570 (define_insn "*rotrqi3_1_one_bit_slp"
12571   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12572         (rotatert:QI (match_dup 0)
12573                      (match_operand:QI 1 "const1_operand" "")))
12574    (clobber (reg:CC FLAGS_REG))]
12575   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12576    && (TARGET_SHIFT1 || optimize_size)"
12577   "ror{b}\t%0"
12578   [(set_attr "type" "rotate1")
12579    (set (attr "length") 
12580      (if_then_else (match_operand 0 "register_operand" "") 
12581         (const_string "2")
12582         (const_string "*")))])
12583
12584 (define_insn "*rotrqi3_1"
12585   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12586         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12587                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12588    (clobber (reg:CC FLAGS_REG))]
12589   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12590   "@
12591    ror{b}\t{%2, %0|%0, %2}
12592    ror{b}\t{%b2, %0|%0, %b2}"
12593   [(set_attr "type" "rotate")
12594    (set_attr "mode" "QI")])
12595
12596 (define_insn "*rotrqi3_1_slp"
12597   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12598         (rotatert:QI (match_dup 0)
12599                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12600    (clobber (reg:CC FLAGS_REG))]
12601   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12602    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12603   "@
12604    ror{b}\t{%1, %0|%0, %1}
12605    ror{b}\t{%b1, %0|%0, %b1}"
12606   [(set_attr "type" "rotate1")
12607    (set_attr "mode" "QI")])
12608 \f
12609 ;; Bit set / bit test instructions
12610
12611 (define_expand "extv"
12612   [(set (match_operand:SI 0 "register_operand" "")
12613         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12614                          (match_operand:SI 2 "immediate_operand" "")
12615                          (match_operand:SI 3 "immediate_operand" "")))]
12616   ""
12617 {
12618   /* Handle extractions from %ah et al.  */
12619   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12620     FAIL;
12621
12622   /* From mips.md: extract_bit_field doesn't verify that our source
12623      matches the predicate, so check it again here.  */
12624   if (! register_operand (operands[1], VOIDmode))
12625     FAIL;
12626 })
12627
12628 (define_expand "extzv"
12629   [(set (match_operand:SI 0 "register_operand" "")
12630         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12631                          (match_operand:SI 2 "immediate_operand" "")
12632                          (match_operand:SI 3 "immediate_operand" "")))]
12633   ""
12634 {
12635   /* Handle extractions from %ah et al.  */
12636   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12637     FAIL;
12638
12639   /* From mips.md: extract_bit_field doesn't verify that our source
12640      matches the predicate, so check it again here.  */
12641   if (! register_operand (operands[1], VOIDmode))
12642     FAIL;
12643 })
12644
12645 (define_expand "insv"
12646   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12647                       (match_operand 1 "immediate_operand" "")
12648                       (match_operand 2 "immediate_operand" ""))
12649         (match_operand 3 "register_operand" ""))]
12650   ""
12651 {
12652   /* Handle extractions from %ah et al.  */
12653   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12654     FAIL;
12655
12656   /* From mips.md: insert_bit_field doesn't verify that our source
12657      matches the predicate, so check it again here.  */
12658   if (! register_operand (operands[0], VOIDmode))
12659     FAIL;
12660
12661   if (TARGET_64BIT)
12662     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12663   else
12664     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12665
12666   DONE;
12667 })
12668
12669 ;; %%% bts, btr, btc, bt.
12670 \f
12671 ;; Store-flag instructions.
12672
12673 ;; For all sCOND expanders, also expand the compare or test insn that
12674 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12675
12676 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12677 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12678 ;; way, which can later delete the movzx if only QImode is needed.
12679
12680 (define_expand "seq"
12681   [(set (match_operand:QI 0 "register_operand" "")
12682         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12683   ""
12684   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12685
12686 (define_expand "sne"
12687   [(set (match_operand:QI 0 "register_operand" "")
12688         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12689   ""
12690   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12691
12692 (define_expand "sgt"
12693   [(set (match_operand:QI 0 "register_operand" "")
12694         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12695   ""
12696   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12697
12698 (define_expand "sgtu"
12699   [(set (match_operand:QI 0 "register_operand" "")
12700         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12701   ""
12702   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12703
12704 (define_expand "slt"
12705   [(set (match_operand:QI 0 "register_operand" "")
12706         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12707   ""
12708   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12709
12710 (define_expand "sltu"
12711   [(set (match_operand:QI 0 "register_operand" "")
12712         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713   ""
12714   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "sge"
12717   [(set (match_operand:QI 0 "register_operand" "")
12718         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719   ""
12720   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sgeu"
12723   [(set (match_operand:QI 0 "register_operand" "")
12724         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725   ""
12726   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sle"
12729   [(set (match_operand:QI 0 "register_operand" "")
12730         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731   ""
12732   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "sleu"
12735   [(set (match_operand:QI 0 "register_operand" "")
12736         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737   ""
12738   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sunordered"
12741   [(set (match_operand:QI 0 "register_operand" "")
12742         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12743   "TARGET_80387 || TARGET_SSE"
12744   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12745
12746 (define_expand "sordered"
12747   [(set (match_operand:QI 0 "register_operand" "")
12748         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12749   "TARGET_80387"
12750   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12751
12752 (define_expand "suneq"
12753   [(set (match_operand:QI 0 "register_operand" "")
12754         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12755   "TARGET_80387 || TARGET_SSE"
12756   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12757
12758 (define_expand "sunge"
12759   [(set (match_operand:QI 0 "register_operand" "")
12760         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12761   "TARGET_80387 || TARGET_SSE"
12762   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12763
12764 (define_expand "sungt"
12765   [(set (match_operand:QI 0 "register_operand" "")
12766         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12767   "TARGET_80387 || TARGET_SSE"
12768   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12769
12770 (define_expand "sunle"
12771   [(set (match_operand:QI 0 "register_operand" "")
12772         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12773   "TARGET_80387 || TARGET_SSE"
12774   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12775
12776 (define_expand "sunlt"
12777   [(set (match_operand:QI 0 "register_operand" "")
12778         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12779   "TARGET_80387 || TARGET_SSE"
12780   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12781
12782 (define_expand "sltgt"
12783   [(set (match_operand:QI 0 "register_operand" "")
12784         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12785   "TARGET_80387 || TARGET_SSE"
12786   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12787
12788 (define_insn "*setcc_1"
12789   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12790         (match_operator:QI 1 "ix86_comparison_operator"
12791           [(reg 17) (const_int 0)]))]
12792   ""
12793   "set%C1\t%0"
12794   [(set_attr "type" "setcc")
12795    (set_attr "mode" "QI")])
12796
12797 (define_insn "setcc_2"
12798   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12799         (match_operator:QI 1 "ix86_comparison_operator"
12800           [(reg 17) (const_int 0)]))]
12801   ""
12802   "set%C1\t%0"
12803   [(set_attr "type" "setcc")
12804    (set_attr "mode" "QI")])
12805
12806 ;; In general it is not safe to assume too much about CCmode registers,
12807 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12808 ;; conditions this is safe on x86, so help combine not create
12809 ;;
12810 ;;      seta    %al
12811 ;;      testb   %al, %al
12812 ;;      sete    %al
12813
12814 (define_split 
12815   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12816         (ne:QI (match_operator 1 "ix86_comparison_operator"
12817                  [(reg 17) (const_int 0)])
12818             (const_int 0)))]
12819   ""
12820   [(set (match_dup 0) (match_dup 1))]
12821 {
12822   PUT_MODE (operands[1], QImode);
12823 })
12824
12825 (define_split 
12826   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12827         (ne:QI (match_operator 1 "ix86_comparison_operator"
12828                  [(reg 17) (const_int 0)])
12829             (const_int 0)))]
12830   ""
12831   [(set (match_dup 0) (match_dup 1))]
12832 {
12833   PUT_MODE (operands[1], QImode);
12834 })
12835
12836 (define_split 
12837   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12838         (eq:QI (match_operator 1 "ix86_comparison_operator"
12839                  [(reg 17) (const_int 0)])
12840             (const_int 0)))]
12841   ""
12842   [(set (match_dup 0) (match_dup 1))]
12843 {
12844   rtx new_op1 = copy_rtx (operands[1]);
12845   operands[1] = new_op1;
12846   PUT_MODE (new_op1, QImode);
12847   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12848                                              GET_MODE (XEXP (new_op1, 0))));
12849
12850   /* Make sure that (a) the CCmode we have for the flags is strong
12851      enough for the reversed compare or (b) we have a valid FP compare.  */
12852   if (! ix86_comparison_operator (new_op1, VOIDmode))
12853     FAIL;
12854 })
12855
12856 (define_split 
12857   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12858         (eq:QI (match_operator 1 "ix86_comparison_operator"
12859                  [(reg 17) (const_int 0)])
12860             (const_int 0)))]
12861   ""
12862   [(set (match_dup 0) (match_dup 1))]
12863 {
12864   rtx new_op1 = copy_rtx (operands[1]);
12865   operands[1] = new_op1;
12866   PUT_MODE (new_op1, QImode);
12867   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12868                                              GET_MODE (XEXP (new_op1, 0))));
12869
12870   /* Make sure that (a) the CCmode we have for the flags is strong
12871      enough for the reversed compare or (b) we have a valid FP compare.  */
12872   if (! ix86_comparison_operator (new_op1, VOIDmode))
12873     FAIL;
12874 })
12875
12876 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12877 ;; subsequent logical operations are used to imitate conditional moves.
12878 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12879 ;; it directly.  Further holding this value in pseudo register might bring
12880 ;; problem in implicit normalization in spill code.
12881 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12882 ;; instructions after reload by splitting the conditional move patterns.
12883
12884 (define_insn "*sse_setccsf"
12885   [(set (match_operand:SF 0 "register_operand" "=x")
12886         (match_operator:SF 1 "sse_comparison_operator"
12887           [(match_operand:SF 2 "register_operand" "0")
12888            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12889   "TARGET_SSE && reload_completed"
12890   "cmp%D1ss\t{%3, %0|%0, %3}"
12891   [(set_attr "type" "ssecmp")
12892    (set_attr "mode" "SF")])
12893
12894 (define_insn "*sse_setccdf"
12895   [(set (match_operand:DF 0 "register_operand" "=Y")
12896         (match_operator:DF 1 "sse_comparison_operator"
12897           [(match_operand:DF 2 "register_operand" "0")
12898            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12899   "TARGET_SSE2 && reload_completed"
12900   "cmp%D1sd\t{%3, %0|%0, %3}"
12901   [(set_attr "type" "ssecmp")
12902    (set_attr "mode" "DF")])
12903 \f
12904 ;; Basic conditional jump instructions.
12905 ;; We ignore the overflow flag for signed branch instructions.
12906
12907 ;; For all bCOND expanders, also expand the compare or test insn that
12908 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12909
12910 (define_expand "beq"
12911   [(set (pc)
12912         (if_then_else (match_dup 1)
12913                       (label_ref (match_operand 0 "" ""))
12914                       (pc)))]
12915   ""
12916   "ix86_expand_branch (EQ, operands[0]); DONE;")
12917
12918 (define_expand "bne"
12919   [(set (pc)
12920         (if_then_else (match_dup 1)
12921                       (label_ref (match_operand 0 "" ""))
12922                       (pc)))]
12923   ""
12924   "ix86_expand_branch (NE, operands[0]); DONE;")
12925
12926 (define_expand "bgt"
12927   [(set (pc)
12928         (if_then_else (match_dup 1)
12929                       (label_ref (match_operand 0 "" ""))
12930                       (pc)))]
12931   ""
12932   "ix86_expand_branch (GT, operands[0]); DONE;")
12933
12934 (define_expand "bgtu"
12935   [(set (pc)
12936         (if_then_else (match_dup 1)
12937                       (label_ref (match_operand 0 "" ""))
12938                       (pc)))]
12939   ""
12940   "ix86_expand_branch (GTU, operands[0]); DONE;")
12941
12942 (define_expand "blt"
12943   [(set (pc)
12944         (if_then_else (match_dup 1)
12945                       (label_ref (match_operand 0 "" ""))
12946                       (pc)))]
12947   ""
12948   "ix86_expand_branch (LT, operands[0]); DONE;")
12949
12950 (define_expand "bltu"
12951   [(set (pc)
12952         (if_then_else (match_dup 1)
12953                       (label_ref (match_operand 0 "" ""))
12954                       (pc)))]
12955   ""
12956   "ix86_expand_branch (LTU, operands[0]); DONE;")
12957
12958 (define_expand "bge"
12959   [(set (pc)
12960         (if_then_else (match_dup 1)
12961                       (label_ref (match_operand 0 "" ""))
12962                       (pc)))]
12963   ""
12964   "ix86_expand_branch (GE, operands[0]); DONE;")
12965
12966 (define_expand "bgeu"
12967   [(set (pc)
12968         (if_then_else (match_dup 1)
12969                       (label_ref (match_operand 0 "" ""))
12970                       (pc)))]
12971   ""
12972   "ix86_expand_branch (GEU, operands[0]); DONE;")
12973
12974 (define_expand "ble"
12975   [(set (pc)
12976         (if_then_else (match_dup 1)
12977                       (label_ref (match_operand 0 "" ""))
12978                       (pc)))]
12979   ""
12980   "ix86_expand_branch (LE, operands[0]); DONE;")
12981
12982 (define_expand "bleu"
12983   [(set (pc)
12984         (if_then_else (match_dup 1)
12985                       (label_ref (match_operand 0 "" ""))
12986                       (pc)))]
12987   ""
12988   "ix86_expand_branch (LEU, operands[0]); DONE;")
12989
12990 (define_expand "bunordered"
12991   [(set (pc)
12992         (if_then_else (match_dup 1)
12993                       (label_ref (match_operand 0 "" ""))
12994                       (pc)))]
12995   "TARGET_80387 || TARGET_SSE"
12996   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12997
12998 (define_expand "bordered"
12999   [(set (pc)
13000         (if_then_else (match_dup 1)
13001                       (label_ref (match_operand 0 "" ""))
13002                       (pc)))]
13003   "TARGET_80387 || TARGET_SSE"
13004   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13005
13006 (define_expand "buneq"
13007   [(set (pc)
13008         (if_then_else (match_dup 1)
13009                       (label_ref (match_operand 0 "" ""))
13010                       (pc)))]
13011   "TARGET_80387 || TARGET_SSE"
13012   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13013
13014 (define_expand "bunge"
13015   [(set (pc)
13016         (if_then_else (match_dup 1)
13017                       (label_ref (match_operand 0 "" ""))
13018                       (pc)))]
13019   "TARGET_80387 || TARGET_SSE"
13020   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13021
13022 (define_expand "bungt"
13023   [(set (pc)
13024         (if_then_else (match_dup 1)
13025                       (label_ref (match_operand 0 "" ""))
13026                       (pc)))]
13027   "TARGET_80387 || TARGET_SSE"
13028   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13029
13030 (define_expand "bunle"
13031   [(set (pc)
13032         (if_then_else (match_dup 1)
13033                       (label_ref (match_operand 0 "" ""))
13034                       (pc)))]
13035   "TARGET_80387 || TARGET_SSE"
13036   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13037
13038 (define_expand "bunlt"
13039   [(set (pc)
13040         (if_then_else (match_dup 1)
13041                       (label_ref (match_operand 0 "" ""))
13042                       (pc)))]
13043   "TARGET_80387 || TARGET_SSE"
13044   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13045
13046 (define_expand "bltgt"
13047   [(set (pc)
13048         (if_then_else (match_dup 1)
13049                       (label_ref (match_operand 0 "" ""))
13050                       (pc)))]
13051   "TARGET_80387 || TARGET_SSE"
13052   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13053
13054 (define_insn "*jcc_1"
13055   [(set (pc)
13056         (if_then_else (match_operator 1 "ix86_comparison_operator"
13057                                       [(reg 17) (const_int 0)])
13058                       (label_ref (match_operand 0 "" ""))
13059                       (pc)))]
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 (define_insn "*jcc_2"
13073   [(set (pc)
13074         (if_then_else (match_operator 1 "ix86_comparison_operator"
13075                                       [(reg 17) (const_int 0)])
13076                       (pc)
13077                       (label_ref (match_operand 0 "" ""))))]
13078   ""
13079   "%+j%c1\t%l0"
13080   [(set_attr "type" "ibr")
13081    (set_attr "modrm" "0")
13082    (set (attr "length")
13083            (if_then_else (and (ge (minus (match_dup 0) (pc))
13084                                   (const_int -126))
13085                               (lt (minus (match_dup 0) (pc))
13086                                   (const_int 128)))
13087              (const_int 2)
13088              (const_int 6)))])
13089
13090 ;; In general it is not safe to assume too much about CCmode registers,
13091 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13092 ;; conditions this is safe on x86, so help combine not create
13093 ;;
13094 ;;      seta    %al
13095 ;;      testb   %al, %al
13096 ;;      je      Lfoo
13097
13098 (define_split 
13099   [(set (pc)
13100         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13101                                       [(reg 17) (const_int 0)])
13102                           (const_int 0))
13103                       (label_ref (match_operand 1 "" ""))
13104                       (pc)))]
13105   ""
13106   [(set (pc)
13107         (if_then_else (match_dup 0)
13108                       (label_ref (match_dup 1))
13109                       (pc)))]
13110 {
13111   PUT_MODE (operands[0], VOIDmode);
13112 })
13113   
13114 (define_split 
13115   [(set (pc)
13116         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13117                                       [(reg 17) (const_int 0)])
13118                           (const_int 0))
13119                       (label_ref (match_operand 1 "" ""))
13120                       (pc)))]
13121   ""
13122   [(set (pc)
13123         (if_then_else (match_dup 0)
13124                       (label_ref (match_dup 1))
13125                       (pc)))]
13126 {
13127   rtx new_op0 = copy_rtx (operands[0]);
13128   operands[0] = new_op0;
13129   PUT_MODE (new_op0, VOIDmode);
13130   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13131                                              GET_MODE (XEXP (new_op0, 0))));
13132
13133   /* Make sure that (a) the CCmode we have for the flags is strong
13134      enough for the reversed compare or (b) we have a valid FP compare.  */
13135   if (! ix86_comparison_operator (new_op0, VOIDmode))
13136     FAIL;
13137 })
13138
13139 ;; Define combination compare-and-branch fp compare instructions to use
13140 ;; during early optimization.  Splitting the operation apart early makes
13141 ;; for bad code when we want to reverse the operation.
13142
13143 (define_insn "*fp_jcc_1"
13144   [(set (pc)
13145         (if_then_else (match_operator 0 "comparison_operator"
13146                         [(match_operand 1 "register_operand" "f")
13147                          (match_operand 2 "register_operand" "f")])
13148           (label_ref (match_operand 3 "" ""))
13149           (pc)))
13150    (clobber (reg:CCFP FPSR_REG))
13151    (clobber (reg:CCFP FLAGS_REG))]
13152   "TARGET_CMOVE && TARGET_80387
13153    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13154    && FLOAT_MODE_P (GET_MODE (operands[1]))
13155    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13156    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13157   "#")
13158
13159 (define_insn "*fp_jcc_1_sse"
13160   [(set (pc)
13161         (if_then_else (match_operator 0 "comparison_operator"
13162                         [(match_operand 1 "register_operand" "f#x,x#f")
13163                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13164           (label_ref (match_operand 3 "" ""))
13165           (pc)))
13166    (clobber (reg:CCFP FPSR_REG))
13167    (clobber (reg:CCFP FLAGS_REG))]
13168   "TARGET_80387
13169    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13170    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13171    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13172   "#")
13173
13174 (define_insn "*fp_jcc_1_sse_only"
13175   [(set (pc)
13176         (if_then_else (match_operator 0 "comparison_operator"
13177                         [(match_operand 1 "register_operand" "x")
13178                          (match_operand 2 "nonimmediate_operand" "xm")])
13179           (label_ref (match_operand 3 "" ""))
13180           (pc)))
13181    (clobber (reg:CCFP FPSR_REG))
13182    (clobber (reg:CCFP FLAGS_REG))]
13183   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13184    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13185    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13186   "#")
13187
13188 (define_insn "*fp_jcc_2"
13189   [(set (pc)
13190         (if_then_else (match_operator 0 "comparison_operator"
13191                         [(match_operand 1 "register_operand" "f")
13192                          (match_operand 2 "register_operand" "f")])
13193           (pc)
13194           (label_ref (match_operand 3 "" ""))))
13195    (clobber (reg:CCFP FPSR_REG))
13196    (clobber (reg:CCFP FLAGS_REG))]
13197   "TARGET_CMOVE && TARGET_80387
13198    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13199    && FLOAT_MODE_P (GET_MODE (operands[1]))
13200    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13201    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13202   "#")
13203
13204 (define_insn "*fp_jcc_2_sse"
13205   [(set (pc)
13206         (if_then_else (match_operator 0 "comparison_operator"
13207                         [(match_operand 1 "register_operand" "f#x,x#f")
13208                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13209           (pc)
13210           (label_ref (match_operand 3 "" ""))))
13211    (clobber (reg:CCFP FPSR_REG))
13212    (clobber (reg:CCFP FLAGS_REG))]
13213   "TARGET_80387
13214    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13215    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13216    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13217   "#")
13218
13219 (define_insn "*fp_jcc_2_sse_only"
13220   [(set (pc)
13221         (if_then_else (match_operator 0 "comparison_operator"
13222                         [(match_operand 1 "register_operand" "x")
13223                          (match_operand 2 "nonimmediate_operand" "xm")])
13224           (pc)
13225           (label_ref (match_operand 3 "" ""))))
13226    (clobber (reg:CCFP FPSR_REG))
13227    (clobber (reg:CCFP FLAGS_REG))]
13228   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13229    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13230    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13231   "#")
13232
13233 (define_insn "*fp_jcc_3"
13234   [(set (pc)
13235         (if_then_else (match_operator 0 "comparison_operator"
13236                         [(match_operand 1 "register_operand" "f")
13237                          (match_operand 2 "nonimmediate_operand" "fm")])
13238           (label_ref (match_operand 3 "" ""))
13239           (pc)))
13240    (clobber (reg:CCFP FPSR_REG))
13241    (clobber (reg:CCFP FLAGS_REG))
13242    (clobber (match_scratch:HI 4 "=a"))]
13243   "TARGET_80387
13244    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13245    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13246    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13247    && SELECT_CC_MODE (GET_CODE (operands[0]),
13248                       operands[1], operands[2]) == CCFPmode
13249    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13250   "#")
13251
13252 (define_insn "*fp_jcc_4"
13253   [(set (pc)
13254         (if_then_else (match_operator 0 "comparison_operator"
13255                         [(match_operand 1 "register_operand" "f")
13256                          (match_operand 2 "nonimmediate_operand" "fm")])
13257           (pc)
13258           (label_ref (match_operand 3 "" ""))))
13259    (clobber (reg:CCFP FPSR_REG))
13260    (clobber (reg:CCFP FLAGS_REG))
13261    (clobber (match_scratch:HI 4 "=a"))]
13262   "TARGET_80387
13263    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13264    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13265    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13266    && SELECT_CC_MODE (GET_CODE (operands[0]),
13267                       operands[1], operands[2]) == CCFPmode
13268    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13269   "#")
13270
13271 (define_insn "*fp_jcc_5"
13272   [(set (pc)
13273         (if_then_else (match_operator 0 "comparison_operator"
13274                         [(match_operand 1 "register_operand" "f")
13275                          (match_operand 2 "register_operand" "f")])
13276           (label_ref (match_operand 3 "" ""))
13277           (pc)))
13278    (clobber (reg:CCFP FPSR_REG))
13279    (clobber (reg:CCFP FLAGS_REG))
13280    (clobber (match_scratch:HI 4 "=a"))]
13281   "TARGET_80387
13282    && FLOAT_MODE_P (GET_MODE (operands[1]))
13283    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13284    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13285   "#")
13286
13287 (define_insn "*fp_jcc_6"
13288   [(set (pc)
13289         (if_then_else (match_operator 0 "comparison_operator"
13290                         [(match_operand 1 "register_operand" "f")
13291                          (match_operand 2 "register_operand" "f")])
13292           (pc)
13293           (label_ref (match_operand 3 "" ""))))
13294    (clobber (reg:CCFP FPSR_REG))
13295    (clobber (reg:CCFP FLAGS_REG))
13296    (clobber (match_scratch:HI 4 "=a"))]
13297   "TARGET_80387
13298    && FLOAT_MODE_P (GET_MODE (operands[1]))
13299    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13300    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13301   "#")
13302
13303 (define_split
13304   [(set (pc)
13305         (if_then_else (match_operator 0 "comparison_operator"
13306                         [(match_operand 1 "register_operand" "")
13307                          (match_operand 2 "nonimmediate_operand" "")])
13308           (match_operand 3 "" "")
13309           (match_operand 4 "" "")))
13310    (clobber (reg:CCFP FPSR_REG))
13311    (clobber (reg:CCFP FLAGS_REG))]
13312   "reload_completed"
13313   [(const_int 0)]
13314 {
13315   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13316                         operands[3], operands[4], NULL_RTX);
13317   DONE;
13318 })
13319
13320 (define_split
13321   [(set (pc)
13322         (if_then_else (match_operator 0 "comparison_operator"
13323                         [(match_operand 1 "register_operand" "")
13324                          (match_operand 2 "nonimmediate_operand" "")])
13325           (match_operand 3 "" "")
13326           (match_operand 4 "" "")))
13327    (clobber (reg:CCFP FPSR_REG))
13328    (clobber (reg:CCFP FLAGS_REG))
13329    (clobber (match_scratch:HI 5 "=a"))]
13330   "reload_completed"
13331   [(set (pc)
13332         (if_then_else (match_dup 6)
13333           (match_dup 3)
13334           (match_dup 4)))]
13335 {
13336   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13337                         operands[3], operands[4], operands[5]);
13338   DONE;
13339 })
13340 \f
13341 ;; Unconditional and other jump instructions
13342
13343 (define_insn "jump"
13344   [(set (pc)
13345         (label_ref (match_operand 0 "" "")))]
13346   ""
13347   "jmp\t%l0"
13348   [(set_attr "type" "ibr")
13349    (set (attr "length")
13350            (if_then_else (and (ge (minus (match_dup 0) (pc))
13351                                   (const_int -126))
13352                               (lt (minus (match_dup 0) (pc))
13353                                   (const_int 128)))
13354              (const_int 2)
13355              (const_int 5)))
13356    (set_attr "modrm" "0")])
13357
13358 (define_expand "indirect_jump"
13359   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13360   ""
13361   "")
13362
13363 (define_insn "*indirect_jump"
13364   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13365   "!TARGET_64BIT"
13366   "jmp\t%A0"
13367   [(set_attr "type" "ibr")
13368    (set_attr "length_immediate" "0")])
13369
13370 (define_insn "*indirect_jump_rtx64"
13371   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13372   "TARGET_64BIT"
13373   "jmp\t%A0"
13374   [(set_attr "type" "ibr")
13375    (set_attr "length_immediate" "0")])
13376
13377 (define_expand "tablejump"
13378   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13379               (use (label_ref (match_operand 1 "" "")))])]
13380   ""
13381 {
13382   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13383      relative.  Convert the relative address to an absolute address.  */
13384   if (flag_pic)
13385     {
13386       rtx op0, op1;
13387       enum rtx_code code;
13388
13389       if (TARGET_64BIT)
13390         {
13391           code = PLUS;
13392           op0 = operands[0];
13393           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13394         }
13395       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13396         {
13397           code = PLUS;
13398           op0 = operands[0];
13399           op1 = pic_offset_table_rtx;
13400         }
13401       else
13402         {
13403           code = MINUS;
13404           op0 = pic_offset_table_rtx;
13405           op1 = operands[0];
13406         }
13407
13408       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13409                                          OPTAB_DIRECT);
13410     }
13411 })
13412
13413 (define_insn "*tablejump_1"
13414   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13415    (use (label_ref (match_operand 1 "" "")))]
13416   "!TARGET_64BIT"
13417   "jmp\t%A0"
13418   [(set_attr "type" "ibr")
13419    (set_attr "length_immediate" "0")])
13420
13421 (define_insn "*tablejump_1_rtx64"
13422   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13423    (use (label_ref (match_operand 1 "" "")))]
13424   "TARGET_64BIT"
13425   "jmp\t%A0"
13426   [(set_attr "type" "ibr")
13427    (set_attr "length_immediate" "0")])
13428 \f
13429 ;; Loop instruction
13430 ;;
13431 ;; This is all complicated by the fact that since this is a jump insn
13432 ;; we must handle our own reloads.
13433
13434 (define_expand "doloop_end"
13435   [(use (match_operand 0 "" ""))        ; loop pseudo
13436    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13437    (use (match_operand 2 "" ""))        ; max iterations
13438    (use (match_operand 3 "" ""))        ; loop level 
13439    (use (match_operand 4 "" ""))]       ; label
13440   "!TARGET_64BIT && TARGET_USE_LOOP"
13441   "                                 
13442 {
13443   /* Only use cloop on innermost loops.  */
13444   if (INTVAL (operands[3]) > 1)
13445     FAIL;
13446   if (GET_MODE (operands[0]) != SImode)
13447     FAIL;
13448   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13449                                            operands[0]));
13450   DONE;
13451 }")
13452
13453 (define_insn "doloop_end_internal"
13454   [(set (pc)
13455         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13456                           (const_int 1))
13457                       (label_ref (match_operand 0 "" ""))
13458                       (pc)))
13459    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13460         (plus:SI (match_dup 1)
13461                  (const_int -1)))
13462    (clobber (match_scratch:SI 3 "=X,X,r"))
13463    (clobber (reg:CC FLAGS_REG))]
13464   "!TARGET_64BIT && TARGET_USE_LOOP
13465    && (reload_in_progress || reload_completed
13466        || register_operand (operands[2], VOIDmode))"
13467 {
13468   if (which_alternative != 0)
13469     return "#";
13470   if (get_attr_length (insn) == 2)
13471     return "%+loop\t%l0";
13472   else
13473     return "dec{l}\t%1\;%+jne\t%l0";
13474 }
13475   [(set (attr "length")
13476         (if_then_else (and (eq_attr "alternative" "0")
13477                            (and (ge (minus (match_dup 0) (pc))
13478                                     (const_int -126))
13479                                 (lt (minus (match_dup 0) (pc))
13480                                     (const_int 128))))
13481                       (const_int 2)
13482                       (const_int 16)))
13483    ;; We don't know the type before shorten branches.  Optimistically expect
13484    ;; the loop instruction to match.
13485    (set (attr "type") (const_string "ibr"))])
13486
13487 (define_split
13488   [(set (pc)
13489         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13490                           (const_int 1))
13491                       (match_operand 0 "" "")
13492                       (pc)))
13493    (set (match_dup 1)
13494         (plus:SI (match_dup 1)
13495                  (const_int -1)))
13496    (clobber (match_scratch:SI 2 ""))
13497    (clobber (reg:CC FLAGS_REG))]
13498   "!TARGET_64BIT && TARGET_USE_LOOP
13499    && reload_completed
13500    && REGNO (operands[1]) != 2"
13501   [(parallel [(set (reg:CCZ FLAGS_REG)
13502                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13503                                  (const_int 0)))
13504               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13505    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13506                            (match_dup 0)
13507                            (pc)))]
13508   "")
13509   
13510 (define_split
13511   [(set (pc)
13512         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13513                           (const_int 1))
13514                       (match_operand 0 "" "")
13515                       (pc)))
13516    (set (match_operand:SI 2 "nonimmediate_operand" "")
13517         (plus:SI (match_dup 1)
13518                  (const_int -1)))
13519    (clobber (match_scratch:SI 3 ""))
13520    (clobber (reg:CC FLAGS_REG))]
13521   "!TARGET_64BIT && TARGET_USE_LOOP
13522    && reload_completed
13523    && (! REG_P (operands[2])
13524        || ! rtx_equal_p (operands[1], operands[2]))"
13525   [(set (match_dup 3) (match_dup 1))
13526    (parallel [(set (reg:CCZ FLAGS_REG)
13527                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13528                                 (const_int 0)))
13529               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13530    (set (match_dup 2) (match_dup 3))
13531    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13532                            (match_dup 0)
13533                            (pc)))]
13534   "")
13535
13536 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13537
13538 (define_peephole2
13539   [(set (reg 17) (match_operand 0 "" ""))
13540    (set (match_operand:QI 1 "register_operand" "")
13541         (match_operator:QI 2 "ix86_comparison_operator"
13542           [(reg 17) (const_int 0)]))
13543    (set (match_operand 3 "q_regs_operand" "")
13544         (zero_extend (match_dup 1)))]
13545   "(peep2_reg_dead_p (3, operands[1])
13546     || operands_match_p (operands[1], operands[3]))
13547    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13548   [(set (match_dup 4) (match_dup 0))
13549    (set (strict_low_part (match_dup 5))
13550         (match_dup 2))]
13551 {
13552   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13553   operands[5] = gen_lowpart (QImode, operands[3]);
13554   ix86_expand_clear (operands[3]);
13555 })
13556
13557 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13558
13559 (define_peephole2
13560   [(set (reg 17) (match_operand 0 "" ""))
13561    (set (match_operand:QI 1 "register_operand" "")
13562         (match_operator:QI 2 "ix86_comparison_operator"
13563           [(reg 17) (const_int 0)]))
13564    (parallel [(set (match_operand 3 "q_regs_operand" "")
13565                    (zero_extend (match_dup 1)))
13566               (clobber (reg:CC FLAGS_REG))])]
13567   "(peep2_reg_dead_p (3, operands[1])
13568     || operands_match_p (operands[1], operands[3]))
13569    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13570   [(set (match_dup 4) (match_dup 0))
13571    (set (strict_low_part (match_dup 5))
13572         (match_dup 2))]
13573 {
13574   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13575   operands[5] = gen_lowpart (QImode, operands[3]);
13576   ix86_expand_clear (operands[3]);
13577 })
13578 \f
13579 ;; Call instructions.
13580
13581 ;; The predicates normally associated with named expanders are not properly
13582 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13583 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13584
13585 ;; Call subroutine returning no value.
13586
13587 (define_expand "call_pop"
13588   [(parallel [(call (match_operand:QI 0 "" "")
13589                     (match_operand:SI 1 "" ""))
13590               (set (reg:SI SP_REG)
13591                    (plus:SI (reg:SI SP_REG)
13592                             (match_operand:SI 3 "" "")))])]
13593   "!TARGET_64BIT"
13594 {
13595   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13596   DONE;
13597 })
13598
13599 (define_insn "*call_pop_0"
13600   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13601          (match_operand:SI 1 "" ""))
13602    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13603                             (match_operand:SI 2 "immediate_operand" "")))]
13604   "!TARGET_64BIT"
13605 {
13606   if (SIBLING_CALL_P (insn))
13607     return "jmp\t%P0";
13608   else
13609     return "call\t%P0";
13610 }
13611   [(set_attr "type" "call")])
13612   
13613 (define_insn "*call_pop_1"
13614   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13615          (match_operand:SI 1 "" ""))
13616    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13617                             (match_operand:SI 2 "immediate_operand" "i")))]
13618   "!TARGET_64BIT"
13619 {
13620   if (constant_call_address_operand (operands[0], Pmode))
13621     {
13622       if (SIBLING_CALL_P (insn))
13623         return "jmp\t%P0";
13624       else
13625         return "call\t%P0";
13626     }
13627   if (SIBLING_CALL_P (insn))
13628     return "jmp\t%A0";
13629   else
13630     return "call\t%A0";
13631 }
13632   [(set_attr "type" "call")])
13633
13634 (define_expand "call"
13635   [(call (match_operand:QI 0 "" "")
13636          (match_operand 1 "" ""))
13637    (use (match_operand 2 "" ""))]
13638   ""
13639 {
13640   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13641   DONE;
13642 })
13643
13644 (define_expand "sibcall"
13645   [(call (match_operand:QI 0 "" "")
13646          (match_operand 1 "" ""))
13647    (use (match_operand 2 "" ""))]
13648   ""
13649 {
13650   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13651   DONE;
13652 })
13653
13654 (define_insn "*call_0"
13655   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13656          (match_operand 1 "" ""))]
13657   ""
13658 {
13659   if (SIBLING_CALL_P (insn))
13660     return "jmp\t%P0";
13661   else
13662     return "call\t%P0";
13663 }
13664   [(set_attr "type" "call")])
13665
13666 (define_insn "*call_1"
13667   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13668          (match_operand 1 "" ""))]
13669   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13670 {
13671   if (constant_call_address_operand (operands[0], QImode))
13672     return "call\t%P0";
13673   return "call\t%A0";
13674 }
13675   [(set_attr "type" "call")])
13676
13677 (define_insn "*sibcall_1"
13678   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13679          (match_operand 1 "" ""))]
13680   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13681 {
13682   if (constant_call_address_operand (operands[0], QImode))
13683     return "jmp\t%P0";
13684   return "jmp\t%A0";
13685 }
13686   [(set_attr "type" "call")])
13687
13688 (define_insn "*call_1_rex64"
13689   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13690          (match_operand 1 "" ""))]
13691   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13692 {
13693   if (constant_call_address_operand (operands[0], QImode))
13694     return "call\t%P0";
13695   return "call\t%A0";
13696 }
13697   [(set_attr "type" "call")])
13698
13699 (define_insn "*sibcall_1_rex64"
13700   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13701          (match_operand 1 "" ""))]
13702   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13703   "jmp\t%P0"
13704   [(set_attr "type" "call")])
13705
13706 (define_insn "*sibcall_1_rex64_v"
13707   [(call (mem:QI (reg:DI 40))
13708          (match_operand 0 "" ""))]
13709   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13710   "jmp\t*%%r11"
13711   [(set_attr "type" "call")])
13712
13713
13714 ;; Call subroutine, returning value in operand 0
13715
13716 (define_expand "call_value_pop"
13717   [(parallel [(set (match_operand 0 "" "")
13718                    (call (match_operand:QI 1 "" "")
13719                          (match_operand:SI 2 "" "")))
13720               (set (reg:SI SP_REG)
13721                    (plus:SI (reg:SI SP_REG)
13722                             (match_operand:SI 4 "" "")))])]
13723   "!TARGET_64BIT"
13724 {
13725   ix86_expand_call (operands[0], operands[1], operands[2],
13726                     operands[3], operands[4], 0);
13727   DONE;
13728 })
13729
13730 (define_expand "call_value"
13731   [(set (match_operand 0 "" "")
13732         (call (match_operand:QI 1 "" "")
13733               (match_operand:SI 2 "" "")))
13734    (use (match_operand:SI 3 "" ""))]
13735   ;; Operand 2 not used on the i386.
13736   ""
13737 {
13738   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13739   DONE;
13740 })
13741
13742 (define_expand "sibcall_value"
13743   [(set (match_operand 0 "" "")
13744         (call (match_operand:QI 1 "" "")
13745               (match_operand:SI 2 "" "")))
13746    (use (match_operand:SI 3 "" ""))]
13747   ;; Operand 2 not used on the i386.
13748   ""
13749 {
13750   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13751   DONE;
13752 })
13753
13754 ;; Call subroutine returning any type.
13755
13756 (define_expand "untyped_call"
13757   [(parallel [(call (match_operand 0 "" "")
13758                     (const_int 0))
13759               (match_operand 1 "" "")
13760               (match_operand 2 "" "")])]
13761   ""
13762 {
13763   int i;
13764
13765   /* In order to give reg-stack an easier job in validating two
13766      coprocessor registers as containing a possible return value,
13767      simply pretend the untyped call returns a complex long double
13768      value.  */
13769
13770   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13771                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13772                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13773                     NULL, 0);
13774
13775   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13776     {
13777       rtx set = XVECEXP (operands[2], 0, i);
13778       emit_move_insn (SET_DEST (set), SET_SRC (set));
13779     }
13780
13781   /* The optimizer does not know that the call sets the function value
13782      registers we stored in the result block.  We avoid problems by
13783      claiming that all hard registers are used and clobbered at this
13784      point.  */
13785   emit_insn (gen_blockage (const0_rtx));
13786
13787   DONE;
13788 })
13789 \f
13790 ;; Prologue and epilogue instructions
13791
13792 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13793 ;; all of memory.  This blocks insns from being moved across this point.
13794
13795 (define_insn "blockage"
13796   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13797   ""
13798   ""
13799   [(set_attr "length" "0")])
13800
13801 ;; Insn emitted into the body of a function to return from a function.
13802 ;; This is only done if the function's epilogue is known to be simple.
13803 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13804
13805 (define_expand "return"
13806   [(return)]
13807   "ix86_can_use_return_insn_p ()"
13808 {
13809   if (current_function_pops_args)
13810     {
13811       rtx popc = GEN_INT (current_function_pops_args);
13812       emit_jump_insn (gen_return_pop_internal (popc));
13813       DONE;
13814     }
13815 })
13816
13817 (define_insn "return_internal"
13818   [(return)]
13819   "reload_completed"
13820   "ret"
13821   [(set_attr "length" "1")
13822    (set_attr "length_immediate" "0")
13823    (set_attr "modrm" "0")])
13824
13825 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13826 ;; instruction Athlon and K8 have.
13827
13828 (define_insn "return_internal_long"
13829   [(return)
13830    (unspec [(const_int 0)] UNSPEC_REP)]
13831   "reload_completed"
13832   "rep {;} ret"
13833   [(set_attr "length" "1")
13834    (set_attr "length_immediate" "0")
13835    (set_attr "prefix_rep" "1")
13836    (set_attr "modrm" "0")])
13837
13838 (define_insn "return_pop_internal"
13839   [(return)
13840    (use (match_operand:SI 0 "const_int_operand" ""))]
13841   "reload_completed"
13842   "ret\t%0"
13843   [(set_attr "length" "3")
13844    (set_attr "length_immediate" "2")
13845    (set_attr "modrm" "0")])
13846
13847 (define_insn "return_indirect_internal"
13848   [(return)
13849    (use (match_operand:SI 0 "register_operand" "r"))]
13850   "reload_completed"
13851   "jmp\t%A0"
13852   [(set_attr "type" "ibr")
13853    (set_attr "length_immediate" "0")])
13854
13855 (define_insn "nop"
13856   [(const_int 0)]
13857   ""
13858   "nop"
13859   [(set_attr "length" "1")
13860    (set_attr "length_immediate" "0")
13861    (set_attr "modrm" "0")])
13862
13863 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13864 ;; branch prediction penalty for the third jump in a 16-byte
13865 ;; block on K8.
13866
13867 (define_insn "align"
13868   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13869   ""
13870 {
13871 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13872   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13873 #else
13874   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13875      The align insn is used to avoid 3 jump instructions in the row to improve
13876      branch prediction and the benefits hardly outweight the cost of extra 8
13877      nops on the average inserted by full alignment pseudo operation.  */
13878 #endif
13879   return "";
13880 }
13881   [(set_attr "length" "16")])
13882
13883 (define_expand "prologue"
13884   [(const_int 1)]
13885   ""
13886   "ix86_expand_prologue (); DONE;")
13887
13888 (define_insn "set_got"
13889   [(set (match_operand:SI 0 "register_operand" "=r")
13890         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13891    (clobber (reg:CC FLAGS_REG))]
13892   "!TARGET_64BIT"
13893   { return output_set_got (operands[0]); }
13894   [(set_attr "type" "multi")
13895    (set_attr "length" "12")])
13896
13897 (define_expand "epilogue"
13898   [(const_int 1)]
13899   ""
13900   "ix86_expand_epilogue (1); DONE;")
13901
13902 (define_expand "sibcall_epilogue"
13903   [(const_int 1)]
13904   ""
13905   "ix86_expand_epilogue (0); DONE;")
13906
13907 (define_expand "eh_return"
13908   [(use (match_operand 0 "register_operand" ""))]
13909   ""
13910 {
13911   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13912
13913   /* Tricky bit: we write the address of the handler to which we will
13914      be returning into someone else's stack frame, one word below the
13915      stack address we wish to restore.  */
13916   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13917   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13918   tmp = gen_rtx_MEM (Pmode, tmp);
13919   emit_move_insn (tmp, ra);
13920
13921   if (Pmode == SImode)
13922     emit_jump_insn (gen_eh_return_si (sa));
13923   else
13924     emit_jump_insn (gen_eh_return_di (sa));
13925   emit_barrier ();
13926   DONE;
13927 })
13928
13929 (define_insn_and_split "eh_return_si"
13930   [(set (pc) 
13931         (unspec [(match_operand:SI 0 "register_operand" "c")]
13932                  UNSPEC_EH_RETURN))]
13933   "!TARGET_64BIT"
13934   "#"
13935   "reload_completed"
13936   [(const_int 1)]
13937   "ix86_expand_epilogue (2); DONE;")
13938
13939 (define_insn_and_split "eh_return_di"
13940   [(set (pc) 
13941         (unspec [(match_operand:DI 0 "register_operand" "c")]
13942                  UNSPEC_EH_RETURN))]
13943   "TARGET_64BIT"
13944   "#"
13945   "reload_completed"
13946   [(const_int 1)]
13947   "ix86_expand_epilogue (2); DONE;")
13948
13949 (define_insn "leave"
13950   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13951    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13952    (clobber (mem:BLK (scratch)))]
13953   "!TARGET_64BIT"
13954   "leave"
13955   [(set_attr "type" "leave")])
13956
13957 (define_insn "leave_rex64"
13958   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13959    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13960    (clobber (mem:BLK (scratch)))]
13961   "TARGET_64BIT"
13962   "leave"
13963   [(set_attr "type" "leave")])
13964 \f
13965 (define_expand "ffssi2"
13966   [(parallel
13967      [(set (match_operand:SI 0 "register_operand" "") 
13968            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13969       (clobber (match_scratch:SI 2 ""))
13970       (clobber (reg:CC FLAGS_REG))])]
13971   ""
13972   "")
13973
13974 (define_insn_and_split "*ffs_cmove"
13975   [(set (match_operand:SI 0 "register_operand" "=r") 
13976         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13977    (clobber (match_scratch:SI 2 "=&r"))
13978    (clobber (reg:CC FLAGS_REG))]
13979   "TARGET_CMOVE"
13980   "#"
13981   "&& reload_completed"
13982   [(set (match_dup 2) (const_int -1))
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 (match_dup 0) (if_then_else:SI
13986                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13987                         (match_dup 2)
13988                         (match_dup 0)))
13989    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13990               (clobber (reg:CC FLAGS_REG))])]
13991   "")
13992
13993 (define_insn_and_split "*ffs_no_cmove"
13994   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13995         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13996    (clobber (match_scratch:SI 2 "=&q"))
13997    (clobber (reg:CC FLAGS_REG))]
13998   ""
13999   "#"
14000   "reload_completed"
14001   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14002               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14003    (set (strict_low_part (match_dup 3))
14004         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14005    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14006               (clobber (reg:CC FLAGS_REG))])
14007    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14008               (clobber (reg:CC FLAGS_REG))])
14009    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14010               (clobber (reg:CC FLAGS_REG))])]
14011 {
14012   operands[3] = gen_lowpart (QImode, operands[2]);
14013   ix86_expand_clear (operands[2]);
14014 })
14015
14016 (define_insn "*ffssi_1"
14017   [(set (reg:CCZ FLAGS_REG)
14018         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14019                      (const_int 0)))
14020    (set (match_operand:SI 0 "register_operand" "=r")
14021         (ctz:SI (match_dup 1)))]
14022   ""
14023   "bsf{l}\t{%1, %0|%0, %1}"
14024   [(set_attr "prefix_0f" "1")])
14025
14026 (define_expand "ffsdi2"
14027   [(parallel
14028      [(set (match_operand:DI 0 "register_operand" "") 
14029            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14030       (clobber (match_scratch:DI 2 ""))
14031       (clobber (reg:CC 17))])]
14032   "TARGET_64BIT && TARGET_CMOVE"
14033   "")
14034
14035 (define_insn_and_split "*ffs_rex64"
14036   [(set (match_operand:DI 0 "register_operand" "=r") 
14037         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14038    (clobber (match_scratch:DI 2 "=&r"))
14039    (clobber (reg:CC 17))]
14040   "TARGET_64BIT && TARGET_CMOVE"
14041   "#"
14042   "&& reload_completed"
14043   [(set (match_dup 2) (const_int -1))
14044    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14045               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14046    (set (match_dup 0) (if_then_else:DI
14047                         (eq (reg:CCZ 17) (const_int 0))
14048                         (match_dup 2)
14049                         (match_dup 0)))
14050    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14051               (clobber (reg:CC 17))])]
14052   "")
14053
14054 (define_insn "*ffsdi_1"
14055   [(set (reg:CCZ 17)
14056         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14057                      (const_int 0)))
14058    (set (match_operand:DI 0 "register_operand" "=r")
14059         (ctz:DI (match_dup 1)))]
14060   "TARGET_64BIT"
14061   "bsf{q}\t{%1, %0|%0, %1}"
14062   [(set_attr "prefix_0f" "1")])
14063
14064 (define_insn "ctzsi2"
14065   [(set (match_operand:SI 0 "register_operand" "=r")
14066         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14067    (clobber (reg:CC FLAGS_REG))]
14068   ""
14069   "bsf{l}\t{%1, %0|%0, %1}"
14070   [(set_attr "prefix_0f" "1")])
14071
14072 (define_insn "ctzdi2"
14073   [(set (match_operand:DI 0 "register_operand" "=r")
14074         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14075    (clobber (reg:CC 17))]
14076   "TARGET_64BIT"
14077   "bsf{q}\t{%1, %0|%0, %1}"
14078   [(set_attr "prefix_0f" "1")])
14079
14080 (define_expand "clzsi2"
14081   [(parallel
14082      [(set (match_operand:SI 0 "register_operand" "")
14083            (minus:SI (const_int 31)
14084                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14085       (clobber (reg:CC FLAGS_REG))])
14086    (parallel
14087      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14088       (clobber (reg:CC FLAGS_REG))])]
14089   ""
14090   "")
14091
14092 (define_insn "*bsr"
14093   [(set (match_operand:SI 0 "register_operand" "=r")
14094         (minus:SI (const_int 31)
14095                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14096    (clobber (reg:CC FLAGS_REG))]
14097   ""
14098   "bsr{l}\t{%1, %0|%0, %1}"
14099   [(set_attr "prefix_0f" "1")])
14100
14101 (define_expand "clzdi2"
14102   [(parallel
14103      [(set (match_operand:DI 0 "register_operand" "")
14104            (minus:DI (const_int 63)
14105                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14106       (clobber (reg:CC 17))])
14107    (parallel
14108      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14109       (clobber (reg:CC 17))])]
14110   "TARGET_64BIT"
14111   "")
14112
14113 (define_insn "*bsr_rex64"
14114   [(set (match_operand:DI 0 "register_operand" "=r")
14115         (minus:DI (const_int 63)
14116                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14117    (clobber (reg:CC 17))]
14118   "TARGET_64BIT"
14119   "bsr{q}\t{%1, %0|%0, %1}"
14120   [(set_attr "prefix_0f" "1")])
14121 \f
14122 ;; Thread-local storage patterns for ELF.
14123 ;;
14124 ;; Note that these code sequences must appear exactly as shown
14125 ;; in order to allow linker relaxation.
14126
14127 (define_insn "*tls_global_dynamic_32_gnu"
14128   [(set (match_operand:SI 0 "register_operand" "=a")
14129         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14130                     (match_operand:SI 2 "tls_symbolic_operand" "")
14131                     (match_operand:SI 3 "call_insn_operand" "")]
14132                     UNSPEC_TLS_GD))
14133    (clobber (match_scratch:SI 4 "=d"))
14134    (clobber (match_scratch:SI 5 "=c"))
14135    (clobber (reg:CC FLAGS_REG))]
14136   "!TARGET_64BIT && TARGET_GNU_TLS"
14137   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14138   [(set_attr "type" "multi")
14139    (set_attr "length" "12")])
14140
14141 (define_insn "*tls_global_dynamic_32_sun"
14142   [(set (match_operand:SI 0 "register_operand" "=a")
14143         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14144                     (match_operand:SI 2 "tls_symbolic_operand" "")
14145                     (match_operand:SI 3 "call_insn_operand" "")]
14146                     UNSPEC_TLS_GD))
14147    (clobber (match_scratch:SI 4 "=d"))
14148    (clobber (match_scratch:SI 5 "=c"))
14149    (clobber (reg:CC FLAGS_REG))]
14150   "!TARGET_64BIT && TARGET_SUN_TLS"
14151   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14152         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14153   [(set_attr "type" "multi")
14154    (set_attr "length" "14")])
14155
14156 (define_expand "tls_global_dynamic_32"
14157   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14158                    (unspec:SI
14159                     [(match_dup 2)
14160                      (match_operand:SI 1 "tls_symbolic_operand" "")
14161                      (match_dup 3)]
14162                     UNSPEC_TLS_GD))
14163               (clobber (match_scratch:SI 4 ""))
14164               (clobber (match_scratch:SI 5 ""))
14165               (clobber (reg:CC FLAGS_REG))])]
14166   ""
14167 {
14168   if (flag_pic)
14169     operands[2] = pic_offset_table_rtx;
14170   else
14171     {
14172       operands[2] = gen_reg_rtx (Pmode);
14173       emit_insn (gen_set_got (operands[2]));
14174     }
14175   operands[3] = ix86_tls_get_addr ();
14176 })
14177
14178 (define_insn "*tls_global_dynamic_64"
14179   [(set (match_operand:DI 0 "register_operand" "=a")
14180         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14181                       (match_operand:DI 3 "" "")))
14182    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14183               UNSPEC_TLS_GD)]
14184   "TARGET_64BIT"
14185   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14186   [(set_attr "type" "multi")
14187    (set_attr "length" "16")])
14188
14189 (define_expand "tls_global_dynamic_64"
14190   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14191                    (call (mem:QI (match_dup 2)) (const_int 0)))
14192               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14193                          UNSPEC_TLS_GD)])]
14194   ""
14195 {
14196   operands[2] = ix86_tls_get_addr ();
14197 })
14198
14199 (define_insn "*tls_local_dynamic_base_32_gnu"
14200   [(set (match_operand:SI 0 "register_operand" "=a")
14201         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14202                     (match_operand:SI 2 "call_insn_operand" "")]
14203                    UNSPEC_TLS_LD_BASE))
14204    (clobber (match_scratch:SI 3 "=d"))
14205    (clobber (match_scratch:SI 4 "=c"))
14206    (clobber (reg:CC FLAGS_REG))]
14207   "!TARGET_64BIT && TARGET_GNU_TLS"
14208   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14209   [(set_attr "type" "multi")
14210    (set_attr "length" "11")])
14211
14212 (define_insn "*tls_local_dynamic_base_32_sun"
14213   [(set (match_operand:SI 0 "register_operand" "=a")
14214         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14215                     (match_operand:SI 2 "call_insn_operand" "")]
14216                    UNSPEC_TLS_LD_BASE))
14217    (clobber (match_scratch:SI 3 "=d"))
14218    (clobber (match_scratch:SI 4 "=c"))
14219    (clobber (reg:CC FLAGS_REG))]
14220   "!TARGET_64BIT && TARGET_SUN_TLS"
14221   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14222         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14223   [(set_attr "type" "multi")
14224    (set_attr "length" "13")])
14225
14226 (define_expand "tls_local_dynamic_base_32"
14227   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14228                    (unspec:SI [(match_dup 1) (match_dup 2)]
14229                               UNSPEC_TLS_LD_BASE))
14230               (clobber (match_scratch:SI 3 ""))
14231               (clobber (match_scratch:SI 4 ""))
14232               (clobber (reg:CC FLAGS_REG))])]
14233   ""
14234 {
14235   if (flag_pic)
14236     operands[1] = pic_offset_table_rtx;
14237   else
14238     {
14239       operands[1] = gen_reg_rtx (Pmode);
14240       emit_insn (gen_set_got (operands[1]));
14241     }
14242   operands[2] = ix86_tls_get_addr ();
14243 })
14244
14245 (define_insn "*tls_local_dynamic_base_64"
14246   [(set (match_operand:DI 0 "register_operand" "=a")
14247         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14248                       (match_operand:DI 2 "" "")))
14249    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14250   "TARGET_64BIT"
14251   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14252   [(set_attr "type" "multi")
14253    (set_attr "length" "12")])
14254
14255 (define_expand "tls_local_dynamic_base_64"
14256   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14257                    (call (mem:QI (match_dup 1)) (const_int 0)))
14258               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14259   ""
14260 {
14261   operands[1] = ix86_tls_get_addr ();
14262 })
14263
14264 ;; Local dynamic of a single variable is a lose.  Show combine how
14265 ;; to convert that back to global dynamic.
14266
14267 (define_insn_and_split "*tls_local_dynamic_32_once"
14268   [(set (match_operand:SI 0 "register_operand" "=a")
14269         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14270                              (match_operand:SI 2 "call_insn_operand" "")]
14271                             UNSPEC_TLS_LD_BASE)
14272                  (const:SI (unspec:SI
14273                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14274                             UNSPEC_DTPOFF))))
14275    (clobber (match_scratch:SI 4 "=d"))
14276    (clobber (match_scratch:SI 5 "=c"))
14277    (clobber (reg:CC FLAGS_REG))]
14278   ""
14279   "#"
14280   ""
14281   [(parallel [(set (match_dup 0)
14282                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14283                               UNSPEC_TLS_GD))
14284               (clobber (match_dup 4))
14285               (clobber (match_dup 5))
14286               (clobber (reg:CC FLAGS_REG))])]
14287   "")
14288
14289 ;; Load and add the thread base pointer from %gs:0.
14290
14291 (define_insn "*load_tp_si"
14292   [(set (match_operand:SI 0 "register_operand" "=r")
14293         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14294   "!TARGET_64BIT"
14295   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14296   [(set_attr "type" "imov")
14297    (set_attr "modrm" "0")
14298    (set_attr "length" "7")
14299    (set_attr "memory" "load")
14300    (set_attr "imm_disp" "false")])
14301
14302 (define_insn "*add_tp_si"
14303   [(set (match_operand:SI 0 "register_operand" "=r")
14304         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14305                  (match_operand:SI 1 "register_operand" "0")))
14306    (clobber (reg:CC FLAGS_REG))]
14307   "!TARGET_64BIT"
14308   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14309   [(set_attr "type" "alu")
14310    (set_attr "modrm" "0")
14311    (set_attr "length" "7")
14312    (set_attr "memory" "load")
14313    (set_attr "imm_disp" "false")])
14314
14315 (define_insn "*load_tp_di"
14316   [(set (match_operand:DI 0 "register_operand" "=r")
14317         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14318   "TARGET_64BIT"
14319   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14320   [(set_attr "type" "imov")
14321    (set_attr "modrm" "0")
14322    (set_attr "length" "7")
14323    (set_attr "memory" "load")
14324    (set_attr "imm_disp" "false")])
14325
14326 (define_insn "*add_tp_di"
14327   [(set (match_operand:DI 0 "register_operand" "=r")
14328         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14329                  (match_operand:DI 1 "register_operand" "0")))
14330    (clobber (reg:CC FLAGS_REG))]
14331   "TARGET_64BIT"
14332   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14333   [(set_attr "type" "alu")
14334    (set_attr "modrm" "0")
14335    (set_attr "length" "7")
14336    (set_attr "memory" "load")
14337    (set_attr "imm_disp" "false")])
14338 \f
14339 ;; These patterns match the binary 387 instructions for addM3, subM3,
14340 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14341 ;; SFmode.  The first is the normal insn, the second the same insn but
14342 ;; with one operand a conversion, and the third the same insn but with
14343 ;; the other operand a conversion.  The conversion may be SFmode or
14344 ;; SImode if the target mode DFmode, but only SImode if the target mode
14345 ;; is SFmode.
14346
14347 ;; Gcc is slightly more smart about handling normal two address instructions
14348 ;; so use special patterns for add and mull.
14349 (define_insn "*fop_sf_comm_nosse"
14350   [(set (match_operand:SF 0 "register_operand" "=f")
14351         (match_operator:SF 3 "binary_fp_operator"
14352                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14353                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14354   "TARGET_80387 && !TARGET_SSE_MATH
14355    && COMMUTATIVE_ARITH_P (operands[3])
14356    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14357   "* return output_387_binary_op (insn, operands);"
14358   [(set (attr "type") 
14359         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14360            (const_string "fmul")
14361            (const_string "fop")))
14362    (set_attr "mode" "SF")])
14363
14364 (define_insn "*fop_sf_comm"
14365   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14366         (match_operator:SF 3 "binary_fp_operator"
14367                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14368                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14369   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14370    && 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 (eq_attr "alternative" "1")
14375            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14376               (const_string "ssemul")
14377               (const_string "sseadd"))
14378            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14379               (const_string "fmul")
14380               (const_string "fop"))))
14381    (set_attr "mode" "SF")])
14382
14383 (define_insn "*fop_sf_comm_sse"
14384   [(set (match_operand:SF 0 "register_operand" "=x")
14385         (match_operator:SF 3 "binary_fp_operator"
14386                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14387                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14388   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14389    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14390   "* return output_387_binary_op (insn, operands);"
14391   [(set (attr "type") 
14392         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14393            (const_string "ssemul")
14394            (const_string "sseadd")))
14395    (set_attr "mode" "SF")])
14396
14397 (define_insn "*fop_df_comm_nosse"
14398   [(set (match_operand:DF 0 "register_operand" "=f")
14399         (match_operator:DF 3 "binary_fp_operator"
14400                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14401                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14402   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14403    && COMMUTATIVE_ARITH_P (operands[3])
14404    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14405   "* return output_387_binary_op (insn, operands);"
14406   [(set (attr "type") 
14407         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14408            (const_string "fmul")
14409            (const_string "fop")))
14410    (set_attr "mode" "DF")])
14411
14412 (define_insn "*fop_df_comm"
14413   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14414         (match_operator:DF 3 "binary_fp_operator"
14415                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14416                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14417   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14418    && COMMUTATIVE_ARITH_P (operands[3])
14419    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14420   "* return output_387_binary_op (insn, operands);"
14421   [(set (attr "type") 
14422         (if_then_else (eq_attr "alternative" "1")
14423            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14424               (const_string "ssemul")
14425               (const_string "sseadd"))
14426            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14427               (const_string "fmul")
14428               (const_string "fop"))))
14429    (set_attr "mode" "DF")])
14430
14431 (define_insn "*fop_df_comm_sse"
14432   [(set (match_operand:DF 0 "register_operand" "=Y")
14433         (match_operator:DF 3 "binary_fp_operator"
14434                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14435                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14436   "TARGET_SSE2 && TARGET_SSE_MATH
14437    && COMMUTATIVE_ARITH_P (operands[3])
14438    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14439   "* return output_387_binary_op (insn, operands);"
14440   [(set (attr "type") 
14441         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14442            (const_string "ssemul")
14443            (const_string "sseadd")))
14444    (set_attr "mode" "DF")])
14445
14446 (define_insn "*fop_xf_comm"
14447   [(set (match_operand:XF 0 "register_operand" "=f")
14448         (match_operator:XF 3 "binary_fp_operator"
14449                         [(match_operand:XF 1 "register_operand" "%0")
14450                          (match_operand:XF 2 "register_operand" "f")]))]
14451   "TARGET_80387
14452    && COMMUTATIVE_ARITH_P (operands[3])"
14453   "* return output_387_binary_op (insn, operands);"
14454   [(set (attr "type") 
14455         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14456            (const_string "fmul")
14457            (const_string "fop")))
14458    (set_attr "mode" "XF")])
14459
14460 (define_insn "*fop_sf_1_nosse"
14461   [(set (match_operand:SF 0 "register_operand" "=f,f")
14462         (match_operator:SF 3 "binary_fp_operator"
14463                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14464                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14465   "TARGET_80387 && !TARGET_SSE_MATH
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 [(match_operand:SF 3 "mult_operator" "") 
14471                  (const_string "fmul")
14472                (match_operand:SF 3 "div_operator" "") 
14473                  (const_string "fdiv")
14474               ]
14475               (const_string "fop")))
14476    (set_attr "mode" "SF")])
14477
14478 (define_insn "*fop_sf_1"
14479   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14480         (match_operator:SF 3 "binary_fp_operator"
14481                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14482                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14483   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14484    && !COMMUTATIVE_ARITH_P (operands[3])
14485    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14486   "* return output_387_binary_op (insn, operands);"
14487   [(set (attr "type") 
14488         (cond [(and (eq_attr "alternative" "2")
14489                     (match_operand:SF 3 "mult_operator" ""))
14490                  (const_string "ssemul")
14491                (and (eq_attr "alternative" "2")
14492                     (match_operand:SF 3 "div_operator" ""))
14493                  (const_string "ssediv")
14494                (eq_attr "alternative" "2")
14495                  (const_string "sseadd")
14496                (match_operand:SF 3 "mult_operator" "") 
14497                  (const_string "fmul")
14498                (match_operand:SF 3 "div_operator" "") 
14499                  (const_string "fdiv")
14500               ]
14501               (const_string "fop")))
14502    (set_attr "mode" "SF")])
14503
14504 (define_insn "*fop_sf_1_sse"
14505   [(set (match_operand:SF 0 "register_operand" "=x")
14506         (match_operator:SF 3 "binary_fp_operator"
14507                         [(match_operand:SF 1 "register_operand" "0")
14508                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14509   "TARGET_SSE_MATH
14510    && !COMMUTATIVE_ARITH_P (operands[3])"
14511   "* return output_387_binary_op (insn, operands);"
14512   [(set (attr "type") 
14513         (cond [(match_operand:SF 3 "mult_operator" "")
14514                  (const_string "ssemul")
14515                (match_operand:SF 3 "div_operator" "")
14516                  (const_string "ssediv")
14517               ]
14518               (const_string "sseadd")))
14519    (set_attr "mode" "SF")])
14520
14521 ;; ??? Add SSE splitters for these!
14522 (define_insn "*fop_sf_2"
14523   [(set (match_operand:SF 0 "register_operand" "=f,f")
14524         (match_operator:SF 3 "binary_fp_operator"
14525           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14526            (match_operand:SF 2 "register_operand" "0,0")]))]
14527   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14528   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14529   [(set (attr "type") 
14530         (cond [(match_operand:SF 3 "mult_operator" "") 
14531                  (const_string "fmul")
14532                (match_operand:SF 3 "div_operator" "") 
14533                  (const_string "fdiv")
14534               ]
14535               (const_string "fop")))
14536    (set_attr "fp_int_src" "true")
14537    (set_attr "mode" "SI")])
14538
14539 (define_insn "*fop_sf_3"
14540   [(set (match_operand:SF 0 "register_operand" "=f,f")
14541         (match_operator:SF 3 "binary_fp_operator"
14542           [(match_operand:SF 1 "register_operand" "0,0")
14543            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14544   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14545   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14546   [(set (attr "type") 
14547         (cond [(match_operand:SF 3 "mult_operator" "") 
14548                  (const_string "fmul")
14549                (match_operand:SF 3 "div_operator" "") 
14550                  (const_string "fdiv")
14551               ]
14552               (const_string "fop")))
14553    (set_attr "fp_int_src" "true")
14554    (set_attr "mode" "SI")])
14555
14556 (define_insn "*fop_df_1_nosse"
14557   [(set (match_operand:DF 0 "register_operand" "=f,f")
14558         (match_operator:DF 3 "binary_fp_operator"
14559                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14560                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14561   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14562    && !COMMUTATIVE_ARITH_P (operands[3])
14563    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14564   "* return output_387_binary_op (insn, operands);"
14565   [(set (attr "type") 
14566         (cond [(match_operand:DF 3 "mult_operator" "") 
14567                  (const_string "fmul")
14568                (match_operand:DF 3 "div_operator" "")
14569                  (const_string "fdiv")
14570               ]
14571               (const_string "fop")))
14572    (set_attr "mode" "DF")])
14573
14574
14575 (define_insn "*fop_df_1"
14576   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14577         (match_operator:DF 3 "binary_fp_operator"
14578                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14579                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14580   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14581    && !COMMUTATIVE_ARITH_P (operands[3])
14582    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14583   "* return output_387_binary_op (insn, operands);"
14584   [(set (attr "type") 
14585         (cond [(and (eq_attr "alternative" "2")
14586                     (match_operand:SF 3 "mult_operator" ""))
14587                  (const_string "ssemul")
14588                (and (eq_attr "alternative" "2")
14589                     (match_operand:SF 3 "div_operator" ""))
14590                  (const_string "ssediv")
14591                (eq_attr "alternative" "2")
14592                  (const_string "sseadd")
14593                (match_operand:DF 3 "mult_operator" "") 
14594                  (const_string "fmul")
14595                (match_operand:DF 3 "div_operator" "") 
14596                  (const_string "fdiv")
14597               ]
14598               (const_string "fop")))
14599    (set_attr "mode" "DF")])
14600
14601 (define_insn "*fop_df_1_sse"
14602   [(set (match_operand:DF 0 "register_operand" "=Y")
14603         (match_operator:DF 3 "binary_fp_operator"
14604                         [(match_operand:DF 1 "register_operand" "0")
14605                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14606   "TARGET_SSE2 && TARGET_SSE_MATH
14607    && !COMMUTATIVE_ARITH_P (operands[3])"
14608   "* return output_387_binary_op (insn, operands);"
14609   [(set_attr "mode" "DF")
14610    (set (attr "type") 
14611         (cond [(match_operand:SF 3 "mult_operator" "")
14612                  (const_string "ssemul")
14613                (match_operand:SF 3 "div_operator" "")
14614                  (const_string "ssediv")
14615               ]
14616               (const_string "sseadd")))])
14617
14618 ;; ??? Add SSE splitters for these!
14619 (define_insn "*fop_df_2"
14620   [(set (match_operand:DF 0 "register_operand" "=f,f")
14621         (match_operator:DF 3 "binary_fp_operator"
14622            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14623             (match_operand:DF 2 "register_operand" "0,0")]))]
14624   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14625   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14626   [(set (attr "type") 
14627         (cond [(match_operand:DF 3 "mult_operator" "") 
14628                  (const_string "fmul")
14629                (match_operand:DF 3 "div_operator" "") 
14630                  (const_string "fdiv")
14631               ]
14632               (const_string "fop")))
14633    (set_attr "fp_int_src" "true")
14634    (set_attr "mode" "SI")])
14635
14636 (define_insn "*fop_df_3"
14637   [(set (match_operand:DF 0 "register_operand" "=f,f")
14638         (match_operator:DF 3 "binary_fp_operator"
14639            [(match_operand:DF 1 "register_operand" "0,0")
14640             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14641   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14642   "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
14651    (set_attr "mode" "SI")])
14652
14653 (define_insn "*fop_df_4"
14654   [(set (match_operand:DF 0 "register_operand" "=f,f")
14655         (match_operator:DF 3 "binary_fp_operator"
14656            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14657             (match_operand:DF 2 "register_operand" "0,f")]))]
14658   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14659    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14660   "* return output_387_binary_op (insn, operands);"
14661   [(set (attr "type") 
14662         (cond [(match_operand:DF 3 "mult_operator" "") 
14663                  (const_string "fmul")
14664                (match_operand:DF 3 "div_operator" "") 
14665                  (const_string "fdiv")
14666               ]
14667               (const_string "fop")))
14668    (set_attr "mode" "SF")])
14669
14670 (define_insn "*fop_df_5"
14671   [(set (match_operand:DF 0 "register_operand" "=f,f")
14672         (match_operator:DF 3 "binary_fp_operator"
14673           [(match_operand:DF 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_df_6"
14688   [(set (match_operand:DF 0 "register_operand" "=f,f")
14689         (match_operator:DF 3 "binary_fp_operator"
14690           [(float_extend:DF
14691             (match_operand:SF 1 "register_operand" "0,f"))
14692            (float_extend:DF
14693             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14694   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14695   "* return output_387_binary_op (insn, operands);"
14696   [(set (attr "type") 
14697         (cond [(match_operand:DF 3 "mult_operator" "") 
14698                  (const_string "fmul")
14699                (match_operand:DF 3 "div_operator" "") 
14700                  (const_string "fdiv")
14701               ]
14702               (const_string "fop")))
14703    (set_attr "mode" "SF")])
14704
14705 (define_insn "*fop_xf_1"
14706   [(set (match_operand:XF 0 "register_operand" "=f,f")
14707         (match_operator:XF 3 "binary_fp_operator"
14708                         [(match_operand:XF 1 "register_operand" "0,f")
14709                          (match_operand:XF 2 "register_operand" "f,0")]))]
14710   "TARGET_80387
14711    && !COMMUTATIVE_ARITH_P (operands[3])"
14712   "* return output_387_binary_op (insn, operands);"
14713   [(set (attr "type") 
14714         (cond [(match_operand:XF 3 "mult_operator" "") 
14715                  (const_string "fmul")
14716                (match_operand:XF 3 "div_operator" "") 
14717                  (const_string "fdiv")
14718               ]
14719               (const_string "fop")))
14720    (set_attr "mode" "XF")])
14721
14722 (define_insn "*fop_xf_2"
14723   [(set (match_operand:XF 0 "register_operand" "=f,f")
14724         (match_operator:XF 3 "binary_fp_operator"
14725            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14726             (match_operand:XF 2 "register_operand" "0,0")]))]
14727   "TARGET_80387 && TARGET_USE_FIOP"
14728   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14729   [(set (attr "type") 
14730         (cond [(match_operand:XF 3 "mult_operator" "") 
14731                  (const_string "fmul")
14732                (match_operand:XF 3 "div_operator" "") 
14733                  (const_string "fdiv")
14734               ]
14735               (const_string "fop")))
14736    (set_attr "fp_int_src" "true")
14737    (set_attr "mode" "SI")])
14738
14739 (define_insn "*fop_xf_3"
14740   [(set (match_operand:XF 0 "register_operand" "=f,f")
14741         (match_operator:XF 3 "binary_fp_operator"
14742           [(match_operand:XF 1 "register_operand" "0,0")
14743            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14744   "TARGET_80387 && TARGET_USE_FIOP"
14745   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14746   [(set (attr "type") 
14747         (cond [(match_operand:XF 3 "mult_operator" "") 
14748                  (const_string "fmul")
14749                (match_operand:XF 3 "div_operator" "") 
14750                  (const_string "fdiv")
14751               ]
14752               (const_string "fop")))
14753    (set_attr "fp_int_src" "true")
14754    (set_attr "mode" "SI")])
14755
14756 (define_insn "*fop_xf_4"
14757   [(set (match_operand:XF 0 "register_operand" "=f,f")
14758         (match_operator:XF 3 "binary_fp_operator"
14759            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14760             (match_operand:XF 2 "register_operand" "0,f")]))]
14761   "TARGET_80387"
14762   "* return output_387_binary_op (insn, operands);"
14763   [(set (attr "type") 
14764         (cond [(match_operand:XF 3 "mult_operator" "") 
14765                  (const_string "fmul")
14766                (match_operand:XF 3 "div_operator" "") 
14767                  (const_string "fdiv")
14768               ]
14769               (const_string "fop")))
14770    (set_attr "mode" "SF")])
14771
14772 (define_insn "*fop_xf_5"
14773   [(set (match_operand:XF 0 "register_operand" "=f,f")
14774         (match_operator:XF 3 "binary_fp_operator"
14775           [(match_operand:XF 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_insn "*fop_xf_6"
14790   [(set (match_operand:XF 0 "register_operand" "=f,f")
14791         (match_operator:XF 3 "binary_fp_operator"
14792           [(float_extend:XF
14793             (match_operand 1 "register_operand" "0,f"))
14794            (float_extend:XF
14795             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14796   "TARGET_80387"
14797   "* return output_387_binary_op (insn, operands);"
14798   [(set (attr "type") 
14799         (cond [(match_operand:XF 3 "mult_operator" "") 
14800                  (const_string "fmul")
14801                (match_operand:XF 3 "div_operator" "") 
14802                  (const_string "fdiv")
14803               ]
14804               (const_string "fop")))
14805    (set_attr "mode" "SF")])
14806
14807 (define_split
14808   [(set (match_operand 0 "register_operand" "")
14809         (match_operator 3 "binary_fp_operator"
14810            [(float (match_operand:SI 1 "register_operand" ""))
14811             (match_operand 2 "register_operand" "")]))]
14812   "TARGET_80387 && reload_completed
14813    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14814   [(const_int 0)]
14815
14816   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14817   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14818   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14819                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14820                                           GET_MODE (operands[3]),
14821                                           operands[4],
14822                                           operands[2])));
14823   ix86_free_from_memory (GET_MODE (operands[1]));
14824   DONE;
14825 })
14826
14827 (define_split
14828   [(set (match_operand 0 "register_operand" "")
14829         (match_operator 3 "binary_fp_operator"
14830            [(match_operand 1 "register_operand" "")
14831             (float (match_operand:SI 2 "register_operand" ""))]))]
14832   "TARGET_80387 && reload_completed
14833    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14834   [(const_int 0)]
14835 {
14836   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14837   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14838   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14839                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14840                                           GET_MODE (operands[3]),
14841                                           operands[1],
14842                                           operands[4])));
14843   ix86_free_from_memory (GET_MODE (operands[2]));
14844   DONE;
14845 })
14846 \f
14847 ;; FPU special functions.
14848
14849 (define_expand "sqrtsf2"
14850   [(set (match_operand:SF 0 "register_operand" "")
14851         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14852   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14853 {
14854   if (!TARGET_SSE_MATH)
14855     operands[1] = force_reg (SFmode, operands[1]);
14856 })
14857
14858 (define_insn "sqrtsf2_1"
14859   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14860         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14861   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14862    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14863   "@
14864    fsqrt
14865    sqrtss\t{%1, %0|%0, %1}"
14866   [(set_attr "type" "fpspc,sse")
14867    (set_attr "mode" "SF,SF")
14868    (set_attr "athlon_decode" "direct,*")])
14869
14870 (define_insn "sqrtsf2_1_sse_only"
14871   [(set (match_operand:SF 0 "register_operand" "=x")
14872         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14873   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14874   "sqrtss\t{%1, %0|%0, %1}"
14875   [(set_attr "type" "sse")
14876    (set_attr "mode" "SF")
14877    (set_attr "athlon_decode" "*")])
14878
14879 (define_insn "sqrtsf2_i387"
14880   [(set (match_operand:SF 0 "register_operand" "=f")
14881         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14882   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14883    && !TARGET_SSE_MATH"
14884   "fsqrt"
14885   [(set_attr "type" "fpspc")
14886    (set_attr "mode" "SF")
14887    (set_attr "athlon_decode" "direct")])
14888
14889 (define_expand "sqrtdf2"
14890   [(set (match_operand:DF 0 "register_operand" "")
14891         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14892   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14893    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14894 {
14895   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14896     operands[1] = force_reg (DFmode, operands[1]);
14897 })
14898
14899 (define_insn "sqrtdf2_1"
14900   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14901         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14902   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14903    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14904   "@
14905    fsqrt
14906    sqrtsd\t{%1, %0|%0, %1}"
14907   [(set_attr "type" "fpspc,sse")
14908    (set_attr "mode" "DF,DF")
14909    (set_attr "athlon_decode" "direct,*")])
14910
14911 (define_insn "sqrtdf2_1_sse_only"
14912   [(set (match_operand:DF 0 "register_operand" "=Y")
14913         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14914   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14915   "sqrtsd\t{%1, %0|%0, %1}"
14916   [(set_attr "type" "sse")
14917    (set_attr "mode" "DF")
14918    (set_attr "athlon_decode" "*")])
14919
14920 (define_insn "sqrtdf2_i387"
14921   [(set (match_operand:DF 0 "register_operand" "=f")
14922         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14923   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14924    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14925   "fsqrt"
14926   [(set_attr "type" "fpspc")
14927    (set_attr "mode" "DF")
14928    (set_attr "athlon_decode" "direct")])
14929
14930 (define_insn "*sqrtextendsfdf2"
14931   [(set (match_operand:DF 0 "register_operand" "=f")
14932         (sqrt:DF (float_extend:DF
14933                   (match_operand:SF 1 "register_operand" "0"))))]
14934   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14935    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14936   "fsqrt"
14937   [(set_attr "type" "fpspc")
14938    (set_attr "mode" "DF")
14939    (set_attr "athlon_decode" "direct")])
14940
14941 (define_insn "sqrtxf2"
14942   [(set (match_operand:XF 0 "register_operand" "=f")
14943         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14944   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14945    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14946   "fsqrt"
14947   [(set_attr "type" "fpspc")
14948    (set_attr "mode" "XF")
14949    (set_attr "athlon_decode" "direct")])
14950
14951 (define_insn "*sqrtextenddfxf2"
14952   [(set (match_operand:XF 0 "register_operand" "=f")
14953         (sqrt:XF (float_extend:XF
14954                   (match_operand:DF 1 "register_operand" "0"))))]
14955   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14956   "fsqrt"
14957   [(set_attr "type" "fpspc")
14958    (set_attr "mode" "XF")
14959    (set_attr "athlon_decode" "direct")])
14960
14961 (define_insn "*sqrtextendsfxf2"
14962   [(set (match_operand:XF 0 "register_operand" "=f")
14963         (sqrt:XF (float_extend:XF
14964                   (match_operand:SF 1 "register_operand" "0"))))]
14965   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14966   "fsqrt"
14967   [(set_attr "type" "fpspc")
14968    (set_attr "mode" "XF")
14969    (set_attr "athlon_decode" "direct")])
14970
14971 (define_insn "fpremxf4"
14972   [(set (match_operand:XF 0 "register_operand" "=f")
14973         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14974                     (match_operand:XF 3 "register_operand" "1")]
14975                    UNSPEC_FPREM_F))
14976    (set (match_operand:XF 1 "register_operand" "=u")
14977         (unspec:XF [(match_dup 2) (match_dup 3)]
14978                    UNSPEC_FPREM_U))
14979    (set (reg:CCFP FPSR_REG)
14980         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14981   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14982    && flag_unsafe_math_optimizations"
14983   "fprem"
14984   [(set_attr "type" "fpspc")
14985    (set_attr "mode" "XF")])
14986
14987 (define_expand "fmodsf3"
14988   [(use (match_operand:SF 0 "register_operand" ""))
14989    (use (match_operand:SF 1 "register_operand" ""))
14990    (use (match_operand:SF 2 "register_operand" ""))]
14991   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14992    && flag_unsafe_math_optimizations"
14993 {
14994   rtx label = gen_label_rtx ();
14995
14996   rtx op1 = gen_reg_rtx (XFmode);
14997   rtx op2 = gen_reg_rtx (XFmode);
14998
14999   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15000   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15001
15002   emit_label (label);
15003
15004   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15005   ix86_emit_fp_unordered_jump (label);
15006
15007   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15008   DONE;
15009 })
15010
15011 (define_expand "fmoddf3"
15012   [(use (match_operand:DF 0 "register_operand" ""))
15013    (use (match_operand:DF 1 "register_operand" ""))
15014    (use (match_operand:DF 2 "register_operand" ""))]
15015   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15016    && flag_unsafe_math_optimizations"
15017 {
15018   rtx label = gen_label_rtx ();
15019
15020   rtx op1 = gen_reg_rtx (XFmode);
15021   rtx op2 = gen_reg_rtx (XFmode);
15022
15023   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15024   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15025
15026   emit_label (label);
15027
15028   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15029   ix86_emit_fp_unordered_jump (label);
15030
15031   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15032   DONE;
15033 })
15034
15035 (define_expand "fmodxf3"
15036   [(use (match_operand:XF 0 "register_operand" ""))
15037    (use (match_operand:XF 1 "register_operand" ""))
15038    (use (match_operand:XF 2 "register_operand" ""))]
15039   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15040    && flag_unsafe_math_optimizations"
15041 {
15042   rtx label = gen_label_rtx ();
15043
15044   emit_label (label);
15045
15046   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15047                            operands[1], operands[2]));
15048   ix86_emit_fp_unordered_jump (label);
15049
15050   emit_move_insn (operands[0], operands[1]);
15051   DONE;
15052 })
15053
15054 (define_insn "fprem1xf4"
15055   [(set (match_operand:XF 0 "register_operand" "=f")
15056         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15057                     (match_operand:XF 3 "register_operand" "1")]
15058                    UNSPEC_FPREM1_F))
15059    (set (match_operand:XF 1 "register_operand" "=u")
15060         (unspec:XF [(match_dup 2) (match_dup 3)]
15061                    UNSPEC_FPREM1_U))
15062    (set (reg:CCFP FPSR_REG)
15063         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15064   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15065    && flag_unsafe_math_optimizations"
15066   "fprem1"
15067   [(set_attr "type" "fpspc")
15068    (set_attr "mode" "XF")])
15069
15070 (define_expand "dremsf3"
15071   [(use (match_operand:SF 0 "register_operand" ""))
15072    (use (match_operand:SF 1 "register_operand" ""))
15073    (use (match_operand:SF 2 "register_operand" ""))]
15074   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15075    && flag_unsafe_math_optimizations"
15076 {
15077   rtx label = gen_label_rtx ();
15078
15079   rtx op1 = gen_reg_rtx (XFmode);
15080   rtx op2 = gen_reg_rtx (XFmode);
15081
15082   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15083   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15084
15085   emit_label (label);
15086
15087   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15088   ix86_emit_fp_unordered_jump (label);
15089
15090   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15091   DONE;
15092 })
15093
15094 (define_expand "dremdf3"
15095   [(use (match_operand:DF 0 "register_operand" ""))
15096    (use (match_operand:DF 1 "register_operand" ""))
15097    (use (match_operand:DF 2 "register_operand" ""))]
15098   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15099    && flag_unsafe_math_optimizations"
15100 {
15101   rtx label = gen_label_rtx ();
15102
15103   rtx op1 = gen_reg_rtx (XFmode);
15104   rtx op2 = gen_reg_rtx (XFmode);
15105
15106   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15107   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15108
15109   emit_label (label);
15110
15111   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15112   ix86_emit_fp_unordered_jump (label);
15113
15114   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15115   DONE;
15116 })
15117
15118 (define_expand "dremxf3"
15119   [(use (match_operand:XF 0 "register_operand" ""))
15120    (use (match_operand:XF 1 "register_operand" ""))
15121    (use (match_operand:XF 2 "register_operand" ""))]
15122   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15123    && flag_unsafe_math_optimizations"
15124 {
15125   rtx label = gen_label_rtx ();
15126
15127   emit_label (label);
15128
15129   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15130                             operands[1], operands[2]));
15131   ix86_emit_fp_unordered_jump (label);
15132
15133   emit_move_insn (operands[0], operands[1]);
15134   DONE;
15135 })
15136
15137 (define_insn "*sindf2"
15138   [(set (match_operand:DF 0 "register_operand" "=f")
15139         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15140   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15141    && flag_unsafe_math_optimizations"
15142   "fsin"
15143   [(set_attr "type" "fpspc")
15144    (set_attr "mode" "DF")])
15145
15146 (define_insn "*sinsf2"
15147   [(set (match_operand:SF 0 "register_operand" "=f")
15148         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15149   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15150    && flag_unsafe_math_optimizations"
15151   "fsin"
15152   [(set_attr "type" "fpspc")
15153    (set_attr "mode" "SF")])
15154
15155 (define_insn "*sinextendsfdf2"
15156   [(set (match_operand:DF 0 "register_operand" "=f")
15157         (unspec:DF [(float_extend:DF
15158                      (match_operand:SF 1 "register_operand" "0"))]
15159                    UNSPEC_SIN))]
15160   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15161    && flag_unsafe_math_optimizations"
15162   "fsin"
15163   [(set_attr "type" "fpspc")
15164    (set_attr "mode" "DF")])
15165
15166 (define_insn "*sinxf2"
15167   [(set (match_operand:XF 0 "register_operand" "=f")
15168         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15169   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15170    && flag_unsafe_math_optimizations"
15171   "fsin"
15172   [(set_attr "type" "fpspc")
15173    (set_attr "mode" "XF")])
15174
15175 (define_insn "*cosdf2"
15176   [(set (match_operand:DF 0 "register_operand" "=f")
15177         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15178   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15179    && flag_unsafe_math_optimizations"
15180   "fcos"
15181   [(set_attr "type" "fpspc")
15182    (set_attr "mode" "DF")])
15183
15184 (define_insn "*cossf2"
15185   [(set (match_operand:SF 0 "register_operand" "=f")
15186         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15187   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15188    && flag_unsafe_math_optimizations"
15189   "fcos"
15190   [(set_attr "type" "fpspc")
15191    (set_attr "mode" "SF")])
15192
15193 (define_insn "*cosextendsfdf2"
15194   [(set (match_operand:DF 0 "register_operand" "=f")
15195         (unspec:DF [(float_extend:DF
15196                      (match_operand:SF 1 "register_operand" "0"))]
15197                    UNSPEC_COS))]
15198   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15199    && flag_unsafe_math_optimizations"
15200   "fcos"
15201   [(set_attr "type" "fpspc")
15202    (set_attr "mode" "DF")])
15203
15204 (define_insn "*cosxf2"
15205   [(set (match_operand:XF 0 "register_operand" "=f")
15206         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15207   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15208    && flag_unsafe_math_optimizations"
15209   "fcos"
15210   [(set_attr "type" "fpspc")
15211    (set_attr "mode" "XF")])
15212
15213 ;; With sincos pattern defined, sin and cos builtin function will be
15214 ;; expanded to sincos pattern with one of its outputs left unused. 
15215 ;; Cse pass  will detected, if two sincos patterns can be combined,
15216 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15217 ;; depending on the unused output.
15218
15219 (define_insn "sincosdf3"
15220   [(set (match_operand:DF 0 "register_operand" "=f")
15221         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15222                    UNSPEC_SINCOS_COS))
15223    (set (match_operand:DF 1 "register_operand" "=u")
15224         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15225   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15226    && flag_unsafe_math_optimizations"
15227   "fsincos"
15228   [(set_attr "type" "fpspc")
15229    (set_attr "mode" "DF")])
15230
15231 (define_split
15232   [(set (match_operand:DF 0 "register_operand" "")
15233         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15234                    UNSPEC_SINCOS_COS))
15235    (set (match_operand:DF 1 "register_operand" "")
15236         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15237   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15238    && !reload_completed && !reload_in_progress"
15239   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15240   "")
15241
15242 (define_split
15243   [(set (match_operand:DF 0 "register_operand" "")
15244         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15245                    UNSPEC_SINCOS_COS))
15246    (set (match_operand:DF 1 "register_operand" "")
15247         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15248   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15249    && !reload_completed && !reload_in_progress"
15250   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15251   "")
15252
15253 (define_insn "sincossf3"
15254   [(set (match_operand:SF 0 "register_operand" "=f")
15255         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15256                    UNSPEC_SINCOS_COS))
15257    (set (match_operand:SF 1 "register_operand" "=u")
15258         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15259   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15260    && flag_unsafe_math_optimizations"
15261   "fsincos"
15262   [(set_attr "type" "fpspc")
15263    (set_attr "mode" "SF")])
15264
15265 (define_split
15266   [(set (match_operand:SF 0 "register_operand" "")
15267         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15268                    UNSPEC_SINCOS_COS))
15269    (set (match_operand:SF 1 "register_operand" "")
15270         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15271   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15272    && !reload_completed && !reload_in_progress"
15273   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15274   "")
15275
15276 (define_split
15277   [(set (match_operand:SF 0 "register_operand" "")
15278         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15279                    UNSPEC_SINCOS_COS))
15280    (set (match_operand:SF 1 "register_operand" "")
15281         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15282   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15283    && !reload_completed && !reload_in_progress"
15284   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15285   "")
15286
15287 (define_insn "*sincosextendsfdf3"
15288   [(set (match_operand:DF 0 "register_operand" "=f")
15289         (unspec:DF [(float_extend:DF
15290                      (match_operand:SF 2 "register_operand" "0"))]
15291                    UNSPEC_SINCOS_COS))
15292    (set (match_operand:DF 1 "register_operand" "=u")
15293         (unspec:DF [(float_extend:DF
15294                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15295   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15296    && flag_unsafe_math_optimizations"
15297   "fsincos"
15298   [(set_attr "type" "fpspc")
15299    (set_attr "mode" "DF")])
15300
15301 (define_split
15302   [(set (match_operand:DF 0 "register_operand" "")
15303         (unspec:DF [(float_extend:DF
15304                      (match_operand:SF 2 "register_operand" ""))]
15305                    UNSPEC_SINCOS_COS))
15306    (set (match_operand:DF 1 "register_operand" "")
15307         (unspec:DF [(float_extend:DF
15308                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15309   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15310    && !reload_completed && !reload_in_progress"
15311   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15312                                    (match_dup 2))] UNSPEC_SIN))]
15313   "")
15314
15315 (define_split
15316   [(set (match_operand:DF 0 "register_operand" "")
15317         (unspec:DF [(float_extend:DF
15318                      (match_operand:SF 2 "register_operand" ""))]
15319                    UNSPEC_SINCOS_COS))
15320    (set (match_operand:DF 1 "register_operand" "")
15321         (unspec:DF [(float_extend:DF
15322                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15323   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15324    && !reload_completed && !reload_in_progress"
15325   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15326                                    (match_dup 2))] UNSPEC_COS))]
15327   "")
15328
15329 (define_insn "sincosxf3"
15330   [(set (match_operand:XF 0 "register_operand" "=f")
15331         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15332                    UNSPEC_SINCOS_COS))
15333    (set (match_operand:XF 1 "register_operand" "=u")
15334         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15335   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15336    && flag_unsafe_math_optimizations"
15337   "fsincos"
15338   [(set_attr "type" "fpspc")
15339    (set_attr "mode" "XF")])
15340
15341 (define_split
15342   [(set (match_operand:XF 0 "register_operand" "")
15343         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15344                    UNSPEC_SINCOS_COS))
15345    (set (match_operand:XF 1 "register_operand" "")
15346         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15347   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15348    && !reload_completed && !reload_in_progress"
15349   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15350   "")
15351
15352 (define_split
15353   [(set (match_operand:XF 0 "register_operand" "")
15354         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15355                    UNSPEC_SINCOS_COS))
15356    (set (match_operand:XF 1 "register_operand" "")
15357         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15358   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15359    && !reload_completed && !reload_in_progress"
15360   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15361   "")
15362
15363 (define_insn "*tandf3_1"
15364   [(set (match_operand:DF 0 "register_operand" "=f")
15365         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15366                    UNSPEC_TAN_ONE))
15367    (set (match_operand:DF 1 "register_operand" "=u")
15368         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15369   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15370    && flag_unsafe_math_optimizations"
15371   "fptan"
15372   [(set_attr "type" "fpspc")
15373    (set_attr "mode" "DF")])
15374
15375 ;; optimize sequence: fptan
15376 ;;                    fstp    %st(0)
15377 ;;                    fld1
15378 ;; into fptan insn.
15379
15380 (define_peephole2
15381   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15382                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15383                              UNSPEC_TAN_ONE))
15384              (set (match_operand:DF 1 "register_operand" "")
15385                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15386    (set (match_dup 0)
15387         (match_operand:DF 3 "immediate_operand" ""))]
15388   "standard_80387_constant_p (operands[3]) == 2"
15389   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15390              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15391   "")
15392
15393 (define_expand "tandf2"
15394   [(parallel [(set (match_dup 2)
15395                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15396                               UNSPEC_TAN_ONE))
15397               (set (match_operand:DF 0 "register_operand" "")
15398                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15399   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15400    && flag_unsafe_math_optimizations"
15401 {
15402   operands[2] = gen_reg_rtx (DFmode);
15403 })
15404
15405 (define_insn "*tansf3_1"
15406   [(set (match_operand:SF 0 "register_operand" "=f")
15407         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15408                    UNSPEC_TAN_ONE))
15409    (set (match_operand:SF 1 "register_operand" "=u")
15410         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15411   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15412    && flag_unsafe_math_optimizations"
15413   "fptan"
15414   [(set_attr "type" "fpspc")
15415    (set_attr "mode" "SF")])
15416
15417 ;; optimize sequence: fptan
15418 ;;                    fstp    %st(0)
15419 ;;                    fld1
15420 ;; into fptan insn.
15421
15422 (define_peephole2
15423   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15424                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15425                              UNSPEC_TAN_ONE))
15426              (set (match_operand:SF 1 "register_operand" "")
15427                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15428    (set (match_dup 0)
15429         (match_operand:SF 3 "immediate_operand" ""))]
15430   "standard_80387_constant_p (operands[3]) == 2"
15431   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15432              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15433   "")
15434
15435 (define_expand "tansf2"
15436   [(parallel [(set (match_dup 2)
15437                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15438                               UNSPEC_TAN_ONE))
15439               (set (match_operand:SF 0 "register_operand" "")
15440                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15441   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15442    && flag_unsafe_math_optimizations"
15443 {
15444   operands[2] = gen_reg_rtx (SFmode);
15445 })
15446
15447 (define_insn "*tanxf3_1"
15448   [(set (match_operand:XF 0 "register_operand" "=f")
15449         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15450                    UNSPEC_TAN_ONE))
15451    (set (match_operand:XF 1 "register_operand" "=u")
15452         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15453   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15454    && flag_unsafe_math_optimizations"
15455   "fptan"
15456   [(set_attr "type" "fpspc")
15457    (set_attr "mode" "XF")])
15458
15459 ;; optimize sequence: fptan
15460 ;;                    fstp    %st(0)
15461 ;;                    fld1
15462 ;; into fptan insn.
15463
15464 (define_peephole2
15465   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15466                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15467                              UNSPEC_TAN_ONE))
15468              (set (match_operand:XF 1 "register_operand" "")
15469                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15470    (set (match_dup 0)
15471         (match_operand:XF 3 "immediate_operand" ""))]
15472   "standard_80387_constant_p (operands[3]) == 2"
15473   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15474              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15475   "")
15476
15477 (define_expand "tanxf2"
15478   [(parallel [(set (match_dup 2)
15479                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15480                               UNSPEC_TAN_ONE))
15481               (set (match_operand:XF 0 "register_operand" "")
15482                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15483   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15484    && flag_unsafe_math_optimizations"
15485 {
15486   operands[2] = gen_reg_rtx (XFmode);
15487 })
15488
15489 (define_insn "atan2df3_1"
15490   [(set (match_operand:DF 0 "register_operand" "=f")
15491         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15492                     (match_operand:DF 1 "register_operand" "u")]
15493                    UNSPEC_FPATAN))
15494    (clobber (match_scratch:DF 3 "=1"))]
15495   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15496    && flag_unsafe_math_optimizations"
15497   "fpatan"
15498   [(set_attr "type" "fpspc")
15499    (set_attr "mode" "DF")])
15500
15501 (define_expand "atan2df3"
15502   [(use (match_operand:DF 0 "register_operand" "=f"))
15503    (use (match_operand:DF 2 "register_operand" "0"))
15504    (use (match_operand:DF 1 "register_operand" "u"))]
15505   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15506    && flag_unsafe_math_optimizations"
15507 {
15508   rtx copy = gen_reg_rtx (DFmode);
15509   emit_move_insn (copy, operands[1]);
15510   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15511   DONE;
15512 })
15513
15514 (define_expand "atandf2"
15515   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15516                    (unspec:DF [(match_dup 2)
15517                                (match_operand:DF 1 "register_operand" "")]
15518                     UNSPEC_FPATAN))
15519               (clobber (match_scratch:DF 3 ""))])]
15520   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15521    && flag_unsafe_math_optimizations"
15522 {
15523   operands[2] = gen_reg_rtx (DFmode);
15524   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15525 })
15526
15527 (define_insn "atan2sf3_1"
15528   [(set (match_operand:SF 0 "register_operand" "=f")
15529         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15530                     (match_operand:SF 1 "register_operand" "u")]
15531                    UNSPEC_FPATAN))
15532    (clobber (match_scratch:SF 3 "=1"))]
15533   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15534    && flag_unsafe_math_optimizations"
15535   "fpatan"
15536   [(set_attr "type" "fpspc")
15537    (set_attr "mode" "SF")])
15538
15539 (define_expand "atan2sf3"
15540   [(use (match_operand:SF 0 "register_operand" "=f"))
15541    (use (match_operand:SF 2 "register_operand" "0"))
15542    (use (match_operand:SF 1 "register_operand" "u"))]
15543   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15544    && flag_unsafe_math_optimizations"
15545 {
15546   rtx copy = gen_reg_rtx (SFmode);
15547   emit_move_insn (copy, operands[1]);
15548   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15549   DONE;
15550 })
15551
15552 (define_expand "atansf2"
15553   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15554                    (unspec:SF [(match_dup 2)
15555                                (match_operand:SF 1 "register_operand" "")]
15556                     UNSPEC_FPATAN))
15557               (clobber (match_scratch:SF 3 ""))])]
15558   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15559    && flag_unsafe_math_optimizations"
15560 {
15561   operands[2] = gen_reg_rtx (SFmode);
15562   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15563 })
15564
15565 (define_insn "atan2xf3_1"
15566   [(set (match_operand:XF 0 "register_operand" "=f")
15567         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15568                     (match_operand:XF 1 "register_operand" "u")]
15569                    UNSPEC_FPATAN))
15570    (clobber (match_scratch:XF 3 "=1"))]
15571   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15572    && flag_unsafe_math_optimizations"
15573   "fpatan"
15574   [(set_attr "type" "fpspc")
15575    (set_attr "mode" "XF")])
15576
15577 (define_expand "atan2xf3"
15578   [(use (match_operand:XF 0 "register_operand" "=f"))
15579    (use (match_operand:XF 2 "register_operand" "0"))
15580    (use (match_operand:XF 1 "register_operand" "u"))]
15581   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15582    && flag_unsafe_math_optimizations"
15583 {
15584   rtx copy = gen_reg_rtx (XFmode);
15585   emit_move_insn (copy, operands[1]);
15586   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15587   DONE;
15588 })
15589
15590 (define_expand "atanxf2"
15591   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15592                    (unspec:XF [(match_dup 2)
15593                                (match_operand:XF 1 "register_operand" "")]
15594                     UNSPEC_FPATAN))
15595               (clobber (match_scratch:XF 3 ""))])]
15596   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15597    && flag_unsafe_math_optimizations"
15598 {
15599   operands[2] = gen_reg_rtx (XFmode);
15600   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15601 })
15602
15603 (define_expand "asindf2"
15604   [(set (match_dup 2)
15605         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15606    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15607    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15608    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15609    (parallel [(set (match_dup 7)
15610                    (unspec:XF [(match_dup 6) (match_dup 2)]
15611                               UNSPEC_FPATAN))
15612               (clobber (match_scratch:XF 8 ""))])
15613    (set (match_operand:DF 0 "register_operand" "")
15614         (float_truncate:DF (match_dup 7)))]
15615   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15616    && flag_unsafe_math_optimizations"
15617 {
15618   int i;
15619
15620   for (i=2; i<8; i++)
15621     operands[i] = gen_reg_rtx (XFmode);
15622
15623   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15624 })
15625
15626 (define_expand "asinsf2"
15627   [(set (match_dup 2)
15628         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15629    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15630    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15631    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15632    (parallel [(set (match_dup 7)
15633                    (unspec:XF [(match_dup 6) (match_dup 2)]
15634                               UNSPEC_FPATAN))
15635               (clobber (match_scratch:XF 8 ""))])
15636    (set (match_operand:SF 0 "register_operand" "")
15637         (float_truncate:SF (match_dup 7)))]
15638   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15639    && flag_unsafe_math_optimizations"
15640 {
15641   int i;
15642
15643   for (i=2; i<8; i++)
15644     operands[i] = gen_reg_rtx (XFmode);
15645
15646   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15647 })
15648
15649 (define_expand "asinxf2"
15650   [(set (match_dup 2)
15651         (mult:XF (match_operand:XF 1 "register_operand" "")
15652                  (match_dup 1)))
15653    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15654    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15655    (parallel [(set (match_operand:XF 0 "register_operand" "")
15656                    (unspec:XF [(match_dup 5) (match_dup 1)]
15657                               UNSPEC_FPATAN))
15658               (clobber (match_scratch:XF 6 ""))])]
15659   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15660    && flag_unsafe_math_optimizations"
15661 {
15662   int i;
15663
15664   for (i=2; i<6; i++)
15665     operands[i] = gen_reg_rtx (XFmode);
15666
15667   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15668 })
15669
15670 (define_expand "acosdf2"
15671   [(set (match_dup 2)
15672         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15673    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15674    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15675    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15676    (parallel [(set (match_dup 7)
15677                    (unspec:XF [(match_dup 2) (match_dup 6)]
15678                               UNSPEC_FPATAN))
15679               (clobber (match_scratch:XF 8 ""))])
15680    (set (match_operand:DF 0 "register_operand" "")
15681         (float_truncate:DF (match_dup 7)))]
15682   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15683    && flag_unsafe_math_optimizations"
15684 {
15685   int i;
15686
15687   for (i=2; i<8; i++)
15688     operands[i] = gen_reg_rtx (XFmode);
15689
15690   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15691 })
15692
15693 (define_expand "acossf2"
15694   [(set (match_dup 2)
15695         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15696    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15697    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15698    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15699    (parallel [(set (match_dup 7)
15700                    (unspec:XF [(match_dup 2) (match_dup 6)]
15701                               UNSPEC_FPATAN))
15702               (clobber (match_scratch:XF 8 ""))])
15703    (set (match_operand:SF 0 "register_operand" "")
15704         (float_truncate:SF (match_dup 7)))]
15705   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15706    && flag_unsafe_math_optimizations"
15707 {
15708   int i;
15709
15710   for (i=2; i<8; i++)
15711     operands[i] = gen_reg_rtx (XFmode);
15712
15713   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15714 })
15715
15716 (define_expand "acosxf2"
15717   [(set (match_dup 2)
15718         (mult:XF (match_operand:XF 1 "register_operand" "")
15719                  (match_dup 1)))
15720    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15721    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15722    (parallel [(set (match_operand:XF 0 "register_operand" "")
15723                    (unspec:XF [(match_dup 1) (match_dup 5)]
15724                               UNSPEC_FPATAN))
15725               (clobber (match_scratch:XF 6 ""))])]
15726   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15727    && flag_unsafe_math_optimizations"
15728 {
15729   int i;
15730
15731   for (i=2; i<6; i++)
15732     operands[i] = gen_reg_rtx (XFmode);
15733
15734   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15735 })
15736
15737 (define_insn "fyl2x_xf3"
15738   [(set (match_operand:XF 0 "register_operand" "=f")
15739         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15740                     (match_operand:XF 1 "register_operand" "u")]
15741                    UNSPEC_FYL2X))
15742    (clobber (match_scratch:XF 3 "=1"))]
15743   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15744    && flag_unsafe_math_optimizations"
15745   "fyl2x"
15746   [(set_attr "type" "fpspc")
15747    (set_attr "mode" "XF")])
15748
15749 (define_expand "logsf2"
15750   [(set (match_dup 2)
15751         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15752    (parallel [(set (match_dup 4)
15753                    (unspec:XF [(match_dup 2)
15754                                (match_dup 3)] UNSPEC_FYL2X))
15755               (clobber (match_scratch:XF 5 ""))])
15756    (set (match_operand:SF 0 "register_operand" "")
15757         (float_truncate:SF (match_dup 4)))]
15758   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15759    && flag_unsafe_math_optimizations"
15760 {
15761   rtx temp;
15762
15763   operands[2] = gen_reg_rtx (XFmode);
15764   operands[3] = gen_reg_rtx (XFmode);
15765   operands[4] = gen_reg_rtx (XFmode);
15766
15767   temp = standard_80387_constant_rtx (4); /* fldln2 */
15768   emit_move_insn (operands[3], temp);
15769 })
15770
15771 (define_expand "logdf2"
15772   [(set (match_dup 2)
15773         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15774    (parallel [(set (match_dup 4)
15775                    (unspec:XF [(match_dup 2)
15776                                (match_dup 3)] UNSPEC_FYL2X))
15777               (clobber (match_scratch:XF 5 ""))])
15778    (set (match_operand:DF 0 "register_operand" "")
15779         (float_truncate:DF (match_dup 4)))]
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   operands[3] = gen_reg_rtx (XFmode);
15787   operands[4] = gen_reg_rtx (XFmode);
15788
15789   temp = standard_80387_constant_rtx (4); /* fldln2 */
15790   emit_move_insn (operands[3], temp);
15791 })
15792
15793 (define_expand "logxf2"
15794   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15795                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15796                                (match_dup 2)] UNSPEC_FYL2X))
15797               (clobber (match_scratch:XF 3 ""))])]
15798   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15799    && flag_unsafe_math_optimizations"
15800 {
15801   rtx temp;
15802
15803   operands[2] = gen_reg_rtx (XFmode);
15804   temp = standard_80387_constant_rtx (4); /* fldln2 */
15805   emit_move_insn (operands[2], temp);
15806 })
15807
15808 (define_expand "log10sf2"
15809   [(set (match_dup 2)
15810         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15811    (parallel [(set (match_dup 4)
15812                    (unspec:XF [(match_dup 2)
15813                                (match_dup 3)] UNSPEC_FYL2X))
15814               (clobber (match_scratch:XF 5 ""))])
15815    (set (match_operand:SF 0 "register_operand" "")
15816         (float_truncate:SF (match_dup 4)))]
15817   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15818    && flag_unsafe_math_optimizations"
15819 {
15820   rtx temp;
15821
15822   operands[2] = gen_reg_rtx (XFmode);
15823   operands[3] = gen_reg_rtx (XFmode);
15824   operands[4] = gen_reg_rtx (XFmode);
15825
15826   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15827   emit_move_insn (operands[3], temp);
15828 })
15829
15830 (define_expand "log10df2"
15831   [(set (match_dup 2)
15832         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15833    (parallel [(set (match_dup 4)
15834                    (unspec:XF [(match_dup 2)
15835                                (match_dup 3)] UNSPEC_FYL2X))
15836               (clobber (match_scratch:XF 5 ""))])
15837    (set (match_operand:DF 0 "register_operand" "")
15838         (float_truncate:DF (match_dup 4)))]
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   operands[3] = gen_reg_rtx (XFmode);
15846   operands[4] = gen_reg_rtx (XFmode);
15847
15848   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15849   emit_move_insn (operands[3], temp);
15850 })
15851
15852 (define_expand "log10xf2"
15853   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15854                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15855                                (match_dup 2)] UNSPEC_FYL2X))
15856               (clobber (match_scratch:XF 3 ""))])]
15857   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15858    && flag_unsafe_math_optimizations"
15859 {
15860   rtx temp;
15861
15862   operands[2] = gen_reg_rtx (XFmode);
15863   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15864   emit_move_insn (operands[2], temp);
15865 })
15866
15867 (define_expand "log2sf2"
15868   [(set (match_dup 2)
15869         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15870    (parallel [(set (match_dup 4)
15871                    (unspec:XF [(match_dup 2)
15872                                (match_dup 3)] UNSPEC_FYL2X))
15873               (clobber (match_scratch:XF 5 ""))])
15874    (set (match_operand:SF 0 "register_operand" "")
15875         (float_truncate:SF (match_dup 4)))]
15876   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15877    && flag_unsafe_math_optimizations"
15878 {
15879   operands[2] = gen_reg_rtx (XFmode);
15880   operands[3] = gen_reg_rtx (XFmode);
15881   operands[4] = gen_reg_rtx (XFmode);
15882
15883   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15884 })
15885
15886 (define_expand "log2df2"
15887   [(set (match_dup 2)
15888         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15889    (parallel [(set (match_dup 4)
15890                    (unspec:XF [(match_dup 2)
15891                                (match_dup 3)] UNSPEC_FYL2X))
15892               (clobber (match_scratch:XF 5 ""))])
15893    (set (match_operand:DF 0 "register_operand" "")
15894         (float_truncate:DF (match_dup 4)))]
15895   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15896    && flag_unsafe_math_optimizations"
15897 {
15898   operands[2] = gen_reg_rtx (XFmode);
15899   operands[3] = gen_reg_rtx (XFmode);
15900   operands[4] = gen_reg_rtx (XFmode);
15901
15902   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15903 })
15904
15905 (define_expand "log2xf2"
15906   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15907                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15908                                (match_dup 2)] UNSPEC_FYL2X))
15909               (clobber (match_scratch:XF 3 ""))])]
15910   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15911    && flag_unsafe_math_optimizations"
15912 {
15913   operands[2] = gen_reg_rtx (XFmode);
15914   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15915 })
15916
15917 (define_insn "fyl2xp1_xf3"
15918   [(set (match_operand:XF 0 "register_operand" "=f")
15919         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15920                     (match_operand:XF 1 "register_operand" "u")]
15921                    UNSPEC_FYL2XP1))
15922    (clobber (match_scratch:XF 3 "=1"))]
15923   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15924    && flag_unsafe_math_optimizations"
15925   "fyl2xp1"
15926   [(set_attr "type" "fpspc")
15927    (set_attr "mode" "XF")])
15928
15929 (define_expand "log1psf2"
15930   [(use (match_operand:XF 0 "register_operand" ""))
15931    (use (match_operand:XF 1 "register_operand" ""))]
15932   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15933    && flag_unsafe_math_optimizations"
15934 {
15935   rtx op0 = gen_reg_rtx (XFmode);
15936   rtx op1 = gen_reg_rtx (XFmode);
15937
15938   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15939   ix86_emit_i387_log1p (op0, op1);
15940   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15941   DONE;
15942 })
15943
15944 (define_expand "log1pdf2"
15945   [(use (match_operand:XF 0 "register_operand" ""))
15946    (use (match_operand:XF 1 "register_operand" ""))]
15947   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15948    && flag_unsafe_math_optimizations"
15949 {
15950   rtx op0 = gen_reg_rtx (XFmode);
15951   rtx op1 = gen_reg_rtx (XFmode);
15952
15953   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15954   ix86_emit_i387_log1p (op0, op1);
15955   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15956   DONE;
15957 })
15958
15959 (define_expand "log1pxf2"
15960   [(use (match_operand:XF 0 "register_operand" ""))
15961    (use (match_operand:XF 1 "register_operand" ""))]
15962   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15963    && flag_unsafe_math_optimizations"
15964 {
15965   ix86_emit_i387_log1p (operands[0], operands[1]);
15966   DONE;
15967 })
15968
15969 (define_insn "*fxtractxf3"
15970   [(set (match_operand:XF 0 "register_operand" "=f")
15971         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15972                    UNSPEC_XTRACT_FRACT))
15973    (set (match_operand:XF 1 "register_operand" "=u")
15974         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15975   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15976    && flag_unsafe_math_optimizations"
15977   "fxtract"
15978   [(set_attr "type" "fpspc")
15979    (set_attr "mode" "XF")])
15980
15981 (define_expand "logbsf2"
15982   [(set (match_dup 2)
15983         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15984    (parallel [(set (match_dup 3)
15985                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15986               (set (match_dup 4)
15987                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15988    (set (match_operand:SF 0 "register_operand" "")
15989         (float_truncate:SF (match_dup 4)))]
15990   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15991    && flag_unsafe_math_optimizations"
15992 {
15993   operands[2] = gen_reg_rtx (XFmode);
15994   operands[3] = gen_reg_rtx (XFmode);
15995   operands[4] = gen_reg_rtx (XFmode);
15996 })
15997
15998 (define_expand "logbdf2"
15999   [(set (match_dup 2)
16000         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16001    (parallel [(set (match_dup 3)
16002                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16003               (set (match_dup 4)
16004                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16005    (set (match_operand:DF 0 "register_operand" "")
16006         (float_truncate:DF (match_dup 4)))]
16007   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16008    && flag_unsafe_math_optimizations"
16009 {
16010   operands[2] = gen_reg_rtx (XFmode);
16011   operands[3] = gen_reg_rtx (XFmode);
16012   operands[4] = gen_reg_rtx (XFmode);
16013 })
16014
16015 (define_expand "logbxf2"
16016   [(parallel [(set (match_dup 2)
16017                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16018                               UNSPEC_XTRACT_FRACT))
16019               (set (match_operand:XF 0 "register_operand" "")
16020                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16021   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16022    && flag_unsafe_math_optimizations"
16023 {
16024   operands[2] = gen_reg_rtx (XFmode);
16025 })
16026
16027 (define_expand "ilogbsi2"
16028   [(parallel [(set (match_dup 2)
16029                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16030                               UNSPEC_XTRACT_FRACT))
16031               (set (match_operand:XF 3 "register_operand" "")
16032                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16033    (parallel [(set (match_operand:SI 0 "register_operand" "")
16034                    (fix:SI (match_dup 3)))
16035               (clobber (reg:CC FLAGS_REG))])]
16036   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16037    && flag_unsafe_math_optimizations"
16038 {
16039   operands[2] = gen_reg_rtx (XFmode);
16040   operands[3] = gen_reg_rtx (XFmode);
16041 })
16042
16043 (define_insn "*frndintxf2"
16044   [(set (match_operand:XF 0 "register_operand" "=f")
16045         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16046          UNSPEC_FRNDINT))]
16047   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16048    && flag_unsafe_math_optimizations"
16049   "frndint"
16050   [(set_attr "type" "fpspc")
16051    (set_attr "mode" "XF")])
16052
16053 (define_insn "*f2xm1xf2"
16054   [(set (match_operand:XF 0 "register_operand" "=f")
16055         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16056          UNSPEC_F2XM1))]
16057   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16058    && flag_unsafe_math_optimizations"
16059   "f2xm1"
16060   [(set_attr "type" "fpspc")
16061    (set_attr "mode" "XF")])
16062
16063 (define_insn "*fscalexf4"
16064   [(set (match_operand:XF 0 "register_operand" "=f")
16065         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16066                     (match_operand:XF 3 "register_operand" "1")]
16067                    UNSPEC_FSCALE_FRACT))
16068    (set (match_operand:XF 1 "register_operand" "=u")
16069         (unspec:XF [(match_dup 2) (match_dup 3)]
16070                    UNSPEC_FSCALE_EXP))]
16071   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16072    && flag_unsafe_math_optimizations"
16073   "fscale"
16074   [(set_attr "type" "fpspc")
16075    (set_attr "mode" "XF")])
16076
16077 (define_expand "expsf2"
16078   [(set (match_dup 2)
16079         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16080    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16081    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16082    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16083    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16084    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16085    (parallel [(set (match_dup 10)
16086                    (unspec:XF [(match_dup 9) (match_dup 5)]
16087                               UNSPEC_FSCALE_FRACT))
16088               (set (match_dup 11)
16089                    (unspec:XF [(match_dup 9) (match_dup 5)]
16090                               UNSPEC_FSCALE_EXP))])
16091    (set (match_operand:SF 0 "register_operand" "")
16092         (float_truncate:SF (match_dup 10)))]
16093   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16094    && flag_unsafe_math_optimizations"
16095 {
16096   rtx temp;
16097   int i;
16098
16099   for (i=2; i<12; i++)
16100     operands[i] = gen_reg_rtx (XFmode);
16101   temp = standard_80387_constant_rtx (5); /* fldl2e */
16102   emit_move_insn (operands[3], temp);
16103   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16104 })
16105
16106 (define_expand "expdf2"
16107   [(set (match_dup 2)
16108         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16109    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16110    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16111    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16112    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16113    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16114    (parallel [(set (match_dup 10)
16115                    (unspec:XF [(match_dup 9) (match_dup 5)]
16116                               UNSPEC_FSCALE_FRACT))
16117               (set (match_dup 11)
16118                    (unspec:XF [(match_dup 9) (match_dup 5)]
16119                               UNSPEC_FSCALE_EXP))])
16120    (set (match_operand:DF 0 "register_operand" "")
16121         (float_truncate:DF (match_dup 10)))]
16122   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16123    && flag_unsafe_math_optimizations"
16124 {
16125   rtx temp;
16126   int i;
16127
16128   for (i=2; i<12; i++)
16129     operands[i] = gen_reg_rtx (XFmode);
16130   temp = standard_80387_constant_rtx (5); /* fldl2e */
16131   emit_move_insn (operands[3], temp);
16132   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16133 })
16134
16135 (define_expand "expxf2"
16136   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16137                                (match_dup 2)))
16138    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16139    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16140    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16141    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16142    (parallel [(set (match_operand:XF 0 "register_operand" "")
16143                    (unspec:XF [(match_dup 8) (match_dup 4)]
16144                               UNSPEC_FSCALE_FRACT))
16145               (set (match_dup 9)
16146                    (unspec:XF [(match_dup 8) (match_dup 4)]
16147                               UNSPEC_FSCALE_EXP))])]
16148   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16149    && flag_unsafe_math_optimizations"
16150 {
16151   rtx temp;
16152   int i;
16153
16154   for (i=2; i<10; i++)
16155     operands[i] = gen_reg_rtx (XFmode);
16156   temp = standard_80387_constant_rtx (5); /* fldl2e */
16157   emit_move_insn (operands[2], temp);
16158   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16159 })
16160
16161 (define_expand "exp10sf2"
16162   [(set (match_dup 2)
16163         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16164    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16165    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16166    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16167    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16168    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16169    (parallel [(set (match_dup 10)
16170                    (unspec:XF [(match_dup 9) (match_dup 5)]
16171                               UNSPEC_FSCALE_FRACT))
16172               (set (match_dup 11)
16173                    (unspec:XF [(match_dup 9) (match_dup 5)]
16174                               UNSPEC_FSCALE_EXP))])
16175    (set (match_operand:SF 0 "register_operand" "")
16176         (float_truncate:SF (match_dup 10)))]
16177   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16178    && flag_unsafe_math_optimizations"
16179 {
16180   rtx temp;
16181   int i;
16182
16183   for (i=2; i<12; i++)
16184     operands[i] = gen_reg_rtx (XFmode);
16185   temp = standard_80387_constant_rtx (6); /* fldl2t */
16186   emit_move_insn (operands[3], temp);
16187   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16188 })
16189
16190 (define_expand "exp10df2"
16191   [(set (match_dup 2)
16192         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16193    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16194    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16195    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16196    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16197    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16198    (parallel [(set (match_dup 10)
16199                    (unspec:XF [(match_dup 9) (match_dup 5)]
16200                               UNSPEC_FSCALE_FRACT))
16201               (set (match_dup 11)
16202                    (unspec:XF [(match_dup 9) (match_dup 5)]
16203                               UNSPEC_FSCALE_EXP))])
16204    (set (match_operand:DF 0 "register_operand" "")
16205         (float_truncate:DF (match_dup 10)))]
16206   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16207    && flag_unsafe_math_optimizations"
16208 {
16209   rtx temp;
16210   int i;
16211
16212   for (i=2; i<12; i++)
16213     operands[i] = gen_reg_rtx (XFmode);
16214   temp = standard_80387_constant_rtx (6); /* fldl2t */
16215   emit_move_insn (operands[3], temp);
16216   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16217 })
16218
16219 (define_expand "exp10xf2"
16220   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16221                                (match_dup 2)))
16222    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16223    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16224    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16225    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16226    (parallel [(set (match_operand:XF 0 "register_operand" "")
16227                    (unspec:XF [(match_dup 8) (match_dup 4)]
16228                               UNSPEC_FSCALE_FRACT))
16229               (set (match_dup 9)
16230                    (unspec:XF [(match_dup 8) (match_dup 4)]
16231                               UNSPEC_FSCALE_EXP))])]
16232   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16233    && flag_unsafe_math_optimizations"
16234 {
16235   rtx temp;
16236   int i;
16237
16238   for (i=2; i<10; i++)
16239     operands[i] = gen_reg_rtx (XFmode);
16240   temp = standard_80387_constant_rtx (6); /* fldl2t */
16241   emit_move_insn (operands[2], temp);
16242   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16243 })
16244
16245 (define_expand "exp2sf2"
16246   [(set (match_dup 2)
16247         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16248    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16249    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16250    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16251    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16252    (parallel [(set (match_dup 8)
16253                    (unspec:XF [(match_dup 7) (match_dup 3)]
16254                               UNSPEC_FSCALE_FRACT))
16255               (set (match_dup 9)
16256                    (unspec:XF [(match_dup 7) (match_dup 3)]
16257                               UNSPEC_FSCALE_EXP))])
16258    (set (match_operand:SF 0 "register_operand" "")
16259         (float_truncate:SF (match_dup 8)))]
16260   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16261    && flag_unsafe_math_optimizations"
16262 {
16263   int i;
16264
16265   for (i=2; i<10; i++)
16266     operands[i] = gen_reg_rtx (XFmode);
16267   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16268 })
16269
16270 (define_expand "exp2df2"
16271   [(set (match_dup 2)
16272         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16273    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16274    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16275    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16276    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16277    (parallel [(set (match_dup 8)
16278                    (unspec:XF [(match_dup 7) (match_dup 3)]
16279                               UNSPEC_FSCALE_FRACT))
16280               (set (match_dup 9)
16281                    (unspec:XF [(match_dup 7) (match_dup 3)]
16282                               UNSPEC_FSCALE_EXP))])
16283    (set (match_operand:DF 0 "register_operand" "")
16284         (float_truncate:DF (match_dup 8)))]
16285   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16286    && flag_unsafe_math_optimizations"
16287 {
16288   int i;
16289
16290   for (i=2; i<10; i++)
16291     operands[i] = gen_reg_rtx (XFmode);
16292   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16293 })
16294
16295 (define_expand "exp2xf2"
16296   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16297    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16298    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16299    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16300    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16301    (parallel [(set (match_operand:XF 0 "register_operand" "")
16302                    (unspec:XF [(match_dup 7) (match_dup 3)]
16303                               UNSPEC_FSCALE_FRACT))
16304               (set (match_dup 8)
16305                    (unspec:XF [(match_dup 7) (match_dup 3)]
16306                               UNSPEC_FSCALE_EXP))])]
16307   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16308    && flag_unsafe_math_optimizations"
16309 {
16310   int i;
16311
16312   for (i=2; i<9; i++)
16313     operands[i] = gen_reg_rtx (XFmode);
16314   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16315 })
16316
16317 (define_expand "expm1df2"
16318   [(set (match_dup 2)
16319         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16320    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16321    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16322    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16323    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16324    (parallel [(set (match_dup 8)
16325                    (unspec:XF [(match_dup 7) (match_dup 5)]
16326                               UNSPEC_FSCALE_FRACT))
16327                    (set (match_dup 9)
16328                    (unspec:XF [(match_dup 7) (match_dup 5)]
16329                               UNSPEC_FSCALE_EXP))])
16330    (parallel [(set (match_dup 11)
16331                    (unspec:XF [(match_dup 10) (match_dup 9)]
16332                               UNSPEC_FSCALE_FRACT))
16333               (set (match_dup 12)
16334                    (unspec:XF [(match_dup 10) (match_dup 9)]
16335                               UNSPEC_FSCALE_EXP))])
16336    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16337    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16338    (set (match_operand:DF 0 "register_operand" "")
16339         (float_truncate:DF (match_dup 14)))]
16340   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16341    && flag_unsafe_math_optimizations"
16342 {
16343   rtx temp;
16344   int i;
16345
16346   for (i=2; i<15; i++)
16347     operands[i] = gen_reg_rtx (XFmode);
16348   temp = standard_80387_constant_rtx (5); /* fldl2e */
16349   emit_move_insn (operands[3], temp);
16350   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16351 })
16352
16353 (define_expand "expm1sf2"
16354   [(set (match_dup 2)
16355         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16356    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16357    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16358    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16359    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16360    (parallel [(set (match_dup 8)
16361                    (unspec:XF [(match_dup 7) (match_dup 5)]
16362                               UNSPEC_FSCALE_FRACT))
16363                    (set (match_dup 9)
16364                    (unspec:XF [(match_dup 7) (match_dup 5)]
16365                               UNSPEC_FSCALE_EXP))])
16366    (parallel [(set (match_dup 11)
16367                    (unspec:XF [(match_dup 10) (match_dup 9)]
16368                               UNSPEC_FSCALE_FRACT))
16369               (set (match_dup 12)
16370                    (unspec:XF [(match_dup 10) (match_dup 9)]
16371                               UNSPEC_FSCALE_EXP))])
16372    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16373    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16374    (set (match_operand:SF 0 "register_operand" "")
16375         (float_truncate:SF (match_dup 14)))]
16376   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16377    && flag_unsafe_math_optimizations"
16378 {
16379   rtx temp;
16380   int i;
16381
16382   for (i=2; i<15; i++)
16383     operands[i] = gen_reg_rtx (XFmode);
16384   temp = standard_80387_constant_rtx (5); /* fldl2e */
16385   emit_move_insn (operands[3], temp);
16386   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16387 })
16388
16389 (define_expand "expm1xf2"
16390   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16391                                (match_dup 2)))
16392    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16393    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16394    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16395    (parallel [(set (match_dup 7)
16396                    (unspec:XF [(match_dup 6) (match_dup 4)]
16397                               UNSPEC_FSCALE_FRACT))
16398                    (set (match_dup 8)
16399                    (unspec:XF [(match_dup 6) (match_dup 4)]
16400                               UNSPEC_FSCALE_EXP))])
16401    (parallel [(set (match_dup 10)
16402                    (unspec:XF [(match_dup 9) (match_dup 8)]
16403                               UNSPEC_FSCALE_FRACT))
16404               (set (match_dup 11)
16405                    (unspec:XF [(match_dup 9) (match_dup 8)]
16406                               UNSPEC_FSCALE_EXP))])
16407    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16408    (set (match_operand:XF 0 "register_operand" "")
16409         (plus:XF (match_dup 12) (match_dup 7)))]
16410   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16411    && flag_unsafe_math_optimizations"
16412 {
16413   rtx temp;
16414   int i;
16415
16416   for (i=2; i<13; i++)
16417     operands[i] = gen_reg_rtx (XFmode);
16418   temp = standard_80387_constant_rtx (5); /* fldl2e */
16419   emit_move_insn (operands[2], temp);
16420   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16421 })
16422 \f
16423 ;; Block operation instructions
16424
16425 (define_insn "cld"
16426  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16427  ""
16428  "cld"
16429   [(set_attr "type" "cld")])
16430
16431 (define_expand "movmemsi"
16432   [(use (match_operand:BLK 0 "memory_operand" ""))
16433    (use (match_operand:BLK 1 "memory_operand" ""))
16434    (use (match_operand:SI 2 "nonmemory_operand" ""))
16435    (use (match_operand:SI 3 "const_int_operand" ""))]
16436   "! optimize_size"
16437 {
16438  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16439    DONE;
16440  else
16441    FAIL;
16442 })
16443
16444 (define_expand "movmemdi"
16445   [(use (match_operand:BLK 0 "memory_operand" ""))
16446    (use (match_operand:BLK 1 "memory_operand" ""))
16447    (use (match_operand:DI 2 "nonmemory_operand" ""))
16448    (use (match_operand:DI 3 "const_int_operand" ""))]
16449   "TARGET_64BIT"
16450 {
16451  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16452    DONE;
16453  else
16454    FAIL;
16455 })
16456
16457 ;; Most CPUs don't like single string operations
16458 ;; Handle this case here to simplify previous expander.
16459
16460 (define_expand "strmov"
16461   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16462    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16463    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16464               (clobber (reg:CC FLAGS_REG))])
16465    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16466               (clobber (reg:CC FLAGS_REG))])]
16467   ""
16468 {
16469   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16470
16471   /* If .md ever supports :P for Pmode, these can be directly
16472      in the pattern above.  */
16473   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16474   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16475
16476   if (TARGET_SINGLE_STRINGOP || optimize_size)
16477     {
16478       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16479                                       operands[2], operands[3],
16480                                       operands[5], operands[6]));
16481       DONE;
16482     }
16483
16484   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16485 })
16486
16487 (define_expand "strmov_singleop"
16488   [(parallel [(set (match_operand 1 "memory_operand" "")
16489                    (match_operand 3 "memory_operand" ""))
16490               (set (match_operand 0 "register_operand" "")
16491                    (match_operand 4 "" ""))
16492               (set (match_operand 2 "register_operand" "")
16493                    (match_operand 5 "" ""))
16494               (use (reg:SI DIRFLAG_REG))])]
16495   "TARGET_SINGLE_STRINGOP || optimize_size"
16496   "")
16497
16498 (define_insn "*strmovdi_rex_1"
16499   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16500         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16501    (set (match_operand:DI 0 "register_operand" "=D")
16502         (plus:DI (match_dup 2)
16503                  (const_int 8)))
16504    (set (match_operand:DI 1 "register_operand" "=S")
16505         (plus:DI (match_dup 3)
16506                  (const_int 8)))
16507    (use (reg:SI DIRFLAG_REG))]
16508   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16509   "movsq"
16510   [(set_attr "type" "str")
16511    (set_attr "mode" "DI")
16512    (set_attr "memory" "both")])
16513
16514 (define_insn "*strmovsi_1"
16515   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16516         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16517    (set (match_operand:SI 0 "register_operand" "=D")
16518         (plus:SI (match_dup 2)
16519                  (const_int 4)))
16520    (set (match_operand:SI 1 "register_operand" "=S")
16521         (plus:SI (match_dup 3)
16522                  (const_int 4)))
16523    (use (reg:SI DIRFLAG_REG))]
16524   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16525   "{movsl|movsd}"
16526   [(set_attr "type" "str")
16527    (set_attr "mode" "SI")
16528    (set_attr "memory" "both")])
16529
16530 (define_insn "*strmovsi_rex_1"
16531   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16532         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16533    (set (match_operand:DI 0 "register_operand" "=D")
16534         (plus:DI (match_dup 2)
16535                  (const_int 4)))
16536    (set (match_operand:DI 1 "register_operand" "=S")
16537         (plus:DI (match_dup 3)
16538                  (const_int 4)))
16539    (use (reg:SI DIRFLAG_REG))]
16540   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16541   "{movsl|movsd}"
16542   [(set_attr "type" "str")
16543    (set_attr "mode" "SI")
16544    (set_attr "memory" "both")])
16545
16546 (define_insn "*strmovhi_1"
16547   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16548         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16549    (set (match_operand:SI 0 "register_operand" "=D")
16550         (plus:SI (match_dup 2)
16551                  (const_int 2)))
16552    (set (match_operand:SI 1 "register_operand" "=S")
16553         (plus:SI (match_dup 3)
16554                  (const_int 2)))
16555    (use (reg:SI DIRFLAG_REG))]
16556   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16557   "movsw"
16558   [(set_attr "type" "str")
16559    (set_attr "memory" "both")
16560    (set_attr "mode" "HI")])
16561
16562 (define_insn "*strmovhi_rex_1"
16563   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16564         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16565    (set (match_operand:DI 0 "register_operand" "=D")
16566         (plus:DI (match_dup 2)
16567                  (const_int 2)))
16568    (set (match_operand:DI 1 "register_operand" "=S")
16569         (plus:DI (match_dup 3)
16570                  (const_int 2)))
16571    (use (reg:SI DIRFLAG_REG))]
16572   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16573   "movsw"
16574   [(set_attr "type" "str")
16575    (set_attr "memory" "both")
16576    (set_attr "mode" "HI")])
16577
16578 (define_insn "*strmovqi_1"
16579   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16580         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16581    (set (match_operand:SI 0 "register_operand" "=D")
16582         (plus:SI (match_dup 2)
16583                  (const_int 1)))
16584    (set (match_operand:SI 1 "register_operand" "=S")
16585         (plus:SI (match_dup 3)
16586                  (const_int 1)))
16587    (use (reg:SI DIRFLAG_REG))]
16588   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16589   "movsb"
16590   [(set_attr "type" "str")
16591    (set_attr "memory" "both")
16592    (set_attr "mode" "QI")])
16593
16594 (define_insn "*strmovqi_rex_1"
16595   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16596         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16597    (set (match_operand:DI 0 "register_operand" "=D")
16598         (plus:DI (match_dup 2)
16599                  (const_int 1)))
16600    (set (match_operand:DI 1 "register_operand" "=S")
16601         (plus:DI (match_dup 3)
16602                  (const_int 1)))
16603    (use (reg:SI DIRFLAG_REG))]
16604   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16605   "movsb"
16606   [(set_attr "type" "str")
16607    (set_attr "memory" "both")
16608    (set_attr "mode" "QI")])
16609
16610 (define_expand "rep_mov"
16611   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16612               (set (match_operand 0 "register_operand" "")
16613                    (match_operand 5 "" ""))
16614               (set (match_operand 2 "register_operand" "")
16615                    (match_operand 6 "" ""))
16616               (set (match_operand 1 "memory_operand" "")
16617                    (match_operand 3 "memory_operand" ""))
16618               (use (match_dup 4))
16619               (use (reg:SI DIRFLAG_REG))])]
16620   ""
16621   "")
16622
16623 (define_insn "*rep_movdi_rex64"
16624   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16625    (set (match_operand:DI 0 "register_operand" "=D") 
16626         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16627                             (const_int 3))
16628                  (match_operand:DI 3 "register_operand" "0")))
16629    (set (match_operand:DI 1 "register_operand" "=S") 
16630         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16631                  (match_operand:DI 4 "register_operand" "1")))
16632    (set (mem:BLK (match_dup 3))
16633         (mem:BLK (match_dup 4)))
16634    (use (match_dup 5))
16635    (use (reg:SI DIRFLAG_REG))]
16636   "TARGET_64BIT"
16637   "{rep\;movsq|rep movsq}"
16638   [(set_attr "type" "str")
16639    (set_attr "prefix_rep" "1")
16640    (set_attr "memory" "both")
16641    (set_attr "mode" "DI")])
16642
16643 (define_insn "*rep_movsi"
16644   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16645    (set (match_operand:SI 0 "register_operand" "=D") 
16646         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16647                             (const_int 2))
16648                  (match_operand:SI 3 "register_operand" "0")))
16649    (set (match_operand:SI 1 "register_operand" "=S") 
16650         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16651                  (match_operand:SI 4 "register_operand" "1")))
16652    (set (mem:BLK (match_dup 3))
16653         (mem:BLK (match_dup 4)))
16654    (use (match_dup 5))
16655    (use (reg:SI DIRFLAG_REG))]
16656   "!TARGET_64BIT"
16657   "{rep\;movsl|rep movsd}"
16658   [(set_attr "type" "str")
16659    (set_attr "prefix_rep" "1")
16660    (set_attr "memory" "both")
16661    (set_attr "mode" "SI")])
16662
16663 (define_insn "*rep_movsi_rex64"
16664   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16665    (set (match_operand:DI 0 "register_operand" "=D") 
16666         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16667                             (const_int 2))
16668                  (match_operand:DI 3 "register_operand" "0")))
16669    (set (match_operand:DI 1 "register_operand" "=S") 
16670         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16671                  (match_operand:DI 4 "register_operand" "1")))
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\;movsl|rep movsd}"
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"
16684   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16685    (set (match_operand:SI 0 "register_operand" "=D") 
16686         (plus:SI (match_operand:SI 3 "register_operand" "0")
16687                  (match_operand:SI 5 "register_operand" "2")))
16688    (set (match_operand:SI 1 "register_operand" "=S") 
16689         (plus:SI (match_operand:SI 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_insn "*rep_movqi_rex64"
16702   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16703    (set (match_operand:DI 0 "register_operand" "=D") 
16704         (plus:DI (match_operand:DI 3 "register_operand" "0")
16705                  (match_operand:DI 5 "register_operand" "2")))
16706    (set (match_operand:DI 1 "register_operand" "=S") 
16707         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16708    (set (mem:BLK (match_dup 3))
16709         (mem:BLK (match_dup 4)))
16710    (use (match_dup 5))
16711    (use (reg:SI DIRFLAG_REG))]
16712   "TARGET_64BIT"
16713   "{rep\;movsb|rep movsb}"
16714   [(set_attr "type" "str")
16715    (set_attr "prefix_rep" "1")
16716    (set_attr "memory" "both")
16717    (set_attr "mode" "SI")])
16718
16719 (define_expand "clrmemsi"
16720    [(use (match_operand:BLK 0 "memory_operand" ""))
16721     (use (match_operand:SI 1 "nonmemory_operand" ""))
16722     (use (match_operand 2 "const_int_operand" ""))]
16723   ""
16724 {
16725  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16726    DONE;
16727  else
16728    FAIL;
16729 })
16730
16731 (define_expand "clrmemdi"
16732    [(use (match_operand:BLK 0 "memory_operand" ""))
16733     (use (match_operand:DI 1 "nonmemory_operand" ""))
16734     (use (match_operand 2 "const_int_operand" ""))]
16735   "TARGET_64BIT"
16736 {
16737  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16738    DONE;
16739  else
16740    FAIL;
16741 })
16742
16743 ;; Most CPUs don't like single string operations
16744 ;; Handle this case here to simplify previous expander.
16745
16746 (define_expand "strset"
16747   [(set (match_operand 1 "memory_operand" "")
16748         (match_operand 2 "register_operand" ""))
16749    (parallel [(set (match_operand 0 "register_operand" "")
16750                    (match_dup 3))
16751               (clobber (reg:CC FLAGS_REG))])]
16752   ""
16753 {
16754   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16755     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16756
16757   /* If .md ever supports :P for Pmode, this can be directly
16758      in the pattern above.  */
16759   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16760                               GEN_INT (GET_MODE_SIZE (GET_MODE
16761                                                       (operands[2]))));
16762   if (TARGET_SINGLE_STRINGOP || optimize_size)
16763     {
16764       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16765                                       operands[3]));
16766       DONE;
16767     }
16768 })
16769
16770 (define_expand "strset_singleop"
16771   [(parallel [(set (match_operand 1 "memory_operand" "")
16772                    (match_operand 2 "register_operand" ""))
16773               (set (match_operand 0 "register_operand" "")
16774                    (match_operand 3 "" ""))
16775               (use (reg:SI DIRFLAG_REG))])]
16776   "TARGET_SINGLE_STRINGOP || optimize_size"
16777   "")
16778
16779 (define_insn "*strsetdi_rex_1"
16780   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16781         (match_operand:DI 2 "register_operand" "a"))
16782    (set (match_operand:DI 0 "register_operand" "=D")
16783         (plus:DI (match_dup 1)
16784                  (const_int 8)))
16785    (use (reg:SI DIRFLAG_REG))]
16786   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16787   "stosq"
16788   [(set_attr "type" "str")
16789    (set_attr "memory" "store")
16790    (set_attr "mode" "DI")])
16791
16792 (define_insn "*strsetsi_1"
16793   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16794         (match_operand:SI 2 "register_operand" "a"))
16795    (set (match_operand:SI 0 "register_operand" "=D")
16796         (plus:SI (match_dup 1)
16797                  (const_int 4)))
16798    (use (reg:SI DIRFLAG_REG))]
16799   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16800   "{stosl|stosd}"
16801   [(set_attr "type" "str")
16802    (set_attr "memory" "store")
16803    (set_attr "mode" "SI")])
16804
16805 (define_insn "*strsetsi_rex_1"
16806   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16807         (match_operand:SI 2 "register_operand" "a"))
16808    (set (match_operand:DI 0 "register_operand" "=D")
16809         (plus:DI (match_dup 1)
16810                  (const_int 4)))
16811    (use (reg:SI DIRFLAG_REG))]
16812   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16813   "{stosl|stosd}"
16814   [(set_attr "type" "str")
16815    (set_attr "memory" "store")
16816    (set_attr "mode" "SI")])
16817
16818 (define_insn "*strsethi_1"
16819   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16820         (match_operand:HI 2 "register_operand" "a"))
16821    (set (match_operand:SI 0 "register_operand" "=D")
16822         (plus:SI (match_dup 1)
16823                  (const_int 2)))
16824    (use (reg:SI DIRFLAG_REG))]
16825   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16826   "stosw"
16827   [(set_attr "type" "str")
16828    (set_attr "memory" "store")
16829    (set_attr "mode" "HI")])
16830
16831 (define_insn "*strsethi_rex_1"
16832   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16833         (match_operand:HI 2 "register_operand" "a"))
16834    (set (match_operand:DI 0 "register_operand" "=D")
16835         (plus:DI (match_dup 1)
16836                  (const_int 2)))
16837    (use (reg:SI DIRFLAG_REG))]
16838   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16839   "stosw"
16840   [(set_attr "type" "str")
16841    (set_attr "memory" "store")
16842    (set_attr "mode" "HI")])
16843
16844 (define_insn "*strsetqi_1"
16845   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16846         (match_operand:QI 2 "register_operand" "a"))
16847    (set (match_operand:SI 0 "register_operand" "=D")
16848         (plus:SI (match_dup 1)
16849                  (const_int 1)))
16850    (use (reg:SI DIRFLAG_REG))]
16851   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16852   "stosb"
16853   [(set_attr "type" "str")
16854    (set_attr "memory" "store")
16855    (set_attr "mode" "QI")])
16856
16857 (define_insn "*strsetqi_rex_1"
16858   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16859         (match_operand:QI 2 "register_operand" "a"))
16860    (set (match_operand:DI 0 "register_operand" "=D")
16861         (plus:DI (match_dup 1)
16862                  (const_int 1)))
16863    (use (reg:SI DIRFLAG_REG))]
16864   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16865   "stosb"
16866   [(set_attr "type" "str")
16867    (set_attr "memory" "store")
16868    (set_attr "mode" "QI")])
16869
16870 (define_expand "rep_stos"
16871   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16872               (set (match_operand 0 "register_operand" "")
16873                    (match_operand 4 "" ""))
16874               (set (match_operand 2 "memory_operand" "") (const_int 0))
16875               (use (match_operand 3 "register_operand" ""))
16876               (use (match_dup 1))
16877               (use (reg:SI DIRFLAG_REG))])]
16878   ""
16879   "")
16880
16881 (define_insn "*rep_stosdi_rex64"
16882   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16883    (set (match_operand:DI 0 "register_operand" "=D") 
16884         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16885                             (const_int 3))
16886                  (match_operand:DI 3 "register_operand" "0")))
16887    (set (mem:BLK (match_dup 3))
16888         (const_int 0))
16889    (use (match_operand:DI 2 "register_operand" "a"))
16890    (use (match_dup 4))
16891    (use (reg:SI DIRFLAG_REG))]
16892   "TARGET_64BIT"
16893   "{rep\;stosq|rep stosq}"
16894   [(set_attr "type" "str")
16895    (set_attr "prefix_rep" "1")
16896    (set_attr "memory" "store")
16897    (set_attr "mode" "DI")])
16898
16899 (define_insn "*rep_stossi"
16900   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16901    (set (match_operand:SI 0 "register_operand" "=D") 
16902         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16903                             (const_int 2))
16904                  (match_operand:SI 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_stossi_rex64"
16918   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16919    (set (match_operand:DI 0 "register_operand" "=D") 
16920         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16921                             (const_int 2))
16922                  (match_operand:DI 3 "register_operand" "0")))
16923    (set (mem:BLK (match_dup 3))
16924         (const_int 0))
16925    (use (match_operand:SI 2 "register_operand" "a"))
16926    (use (match_dup 4))
16927    (use (reg:SI DIRFLAG_REG))]
16928   "TARGET_64BIT"
16929   "{rep\;stosl|rep stosd}"
16930   [(set_attr "type" "str")
16931    (set_attr "prefix_rep" "1")
16932    (set_attr "memory" "store")
16933    (set_attr "mode" "SI")])
16934
16935 (define_insn "*rep_stosqi"
16936   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16937    (set (match_operand:SI 0 "register_operand" "=D") 
16938         (plus:SI (match_operand:SI 3 "register_operand" "0")
16939                  (match_operand:SI 4 "register_operand" "1")))
16940    (set (mem:BLK (match_dup 3))
16941         (const_int 0))
16942    (use (match_operand:QI 2 "register_operand" "a"))
16943    (use (match_dup 4))
16944    (use (reg:SI DIRFLAG_REG))]
16945   "!TARGET_64BIT"
16946   "{rep\;stosb|rep stosb}"
16947   [(set_attr "type" "str")
16948    (set_attr "prefix_rep" "1")
16949    (set_attr "memory" "store")
16950    (set_attr "mode" "QI")])
16951
16952 (define_insn "*rep_stosqi_rex64"
16953   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16954    (set (match_operand:DI 0 "register_operand" "=D") 
16955         (plus:DI (match_operand:DI 3 "register_operand" "0")
16956                  (match_operand:DI 4 "register_operand" "1")))
16957    (set (mem:BLK (match_dup 3))
16958         (const_int 0))
16959    (use (match_operand:QI 2 "register_operand" "a"))
16960    (use (match_dup 4))
16961    (use (reg:SI DIRFLAG_REG))]
16962   "TARGET_64BIT"
16963   "{rep\;stosb|rep stosb}"
16964   [(set_attr "type" "str")
16965    (set_attr "prefix_rep" "1")
16966    (set_attr "memory" "store")
16967    (set_attr "mode" "QI")])
16968
16969 (define_expand "cmpstrsi"
16970   [(set (match_operand:SI 0 "register_operand" "")
16971         (compare:SI (match_operand:BLK 1 "general_operand" "")
16972                     (match_operand:BLK 2 "general_operand" "")))
16973    (use (match_operand 3 "general_operand" ""))
16974    (use (match_operand 4 "immediate_operand" ""))]
16975   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16976 {
16977   rtx addr1, addr2, out, outlow, count, countreg, align;
16978
16979   /* Can't use this if the user has appropriated esi or edi.  */
16980   if (global_regs[4] || global_regs[5])
16981     FAIL;
16982
16983   out = operands[0];
16984   if (GET_CODE (out) != REG)
16985     out = gen_reg_rtx (SImode);
16986
16987   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16988   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16989   if (addr1 != XEXP (operands[1], 0))
16990     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16991   if (addr2 != XEXP (operands[2], 0))
16992     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16993
16994   count = operands[3];
16995   countreg = ix86_zero_extend_to_Pmode (count);
16996
16997   /* %%% Iff we are testing strict equality, we can use known alignment
16998      to good advantage.  This may be possible with combine, particularly
16999      once cc0 is dead.  */
17000   align = operands[4];
17001
17002   emit_insn (gen_cld ());
17003   if (GET_CODE (count) == CONST_INT)
17004     {
17005       if (INTVAL (count) == 0)
17006         {
17007           emit_move_insn (operands[0], const0_rtx);
17008           DONE;
17009         }
17010       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17011                                     operands[1], operands[2]));
17012     }
17013   else
17014     {
17015       if (TARGET_64BIT)
17016         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17017       else
17018         emit_insn (gen_cmpsi_1 (countreg, countreg));
17019       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17020                                  operands[1], operands[2]));
17021     }
17022
17023   outlow = gen_lowpart (QImode, out);
17024   emit_insn (gen_cmpintqi (outlow));
17025   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17026
17027   if (operands[0] != out)
17028     emit_move_insn (operands[0], out);
17029
17030   DONE;
17031 })
17032
17033 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17034
17035 (define_expand "cmpintqi"
17036   [(set (match_dup 1)
17037         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17038    (set (match_dup 2)
17039         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17040    (parallel [(set (match_operand:QI 0 "register_operand" "")
17041                    (minus:QI (match_dup 1)
17042                              (match_dup 2)))
17043               (clobber (reg:CC FLAGS_REG))])]
17044   ""
17045   "operands[1] = gen_reg_rtx (QImode);
17046    operands[2] = gen_reg_rtx (QImode);")
17047
17048 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17049 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17050
17051 (define_expand "cmpstrqi_nz_1"
17052   [(parallel [(set (reg:CC FLAGS_REG)
17053                    (compare:CC (match_operand 4 "memory_operand" "")
17054                                (match_operand 5 "memory_operand" "")))
17055               (use (match_operand 2 "register_operand" ""))
17056               (use (match_operand:SI 3 "immediate_operand" ""))
17057               (use (reg:SI DIRFLAG_REG))
17058               (clobber (match_operand 0 "register_operand" ""))
17059               (clobber (match_operand 1 "register_operand" ""))
17060               (clobber (match_dup 2))])]
17061   ""
17062   "")
17063
17064 (define_insn "*cmpstrqi_nz_1"
17065   [(set (reg:CC FLAGS_REG)
17066         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17067                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17068    (use (match_operand:SI 6 "register_operand" "2"))
17069    (use (match_operand:SI 3 "immediate_operand" "i"))
17070    (use (reg:SI DIRFLAG_REG))
17071    (clobber (match_operand:SI 0 "register_operand" "=S"))
17072    (clobber (match_operand:SI 1 "register_operand" "=D"))
17073    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17074   "!TARGET_64BIT"
17075   "repz{\;| }cmpsb"
17076   [(set_attr "type" "str")
17077    (set_attr "mode" "QI")
17078    (set_attr "prefix_rep" "1")])
17079
17080 (define_insn "*cmpstrqi_nz_rex_1"
17081   [(set (reg:CC FLAGS_REG)
17082         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17083                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17084    (use (match_operand:DI 6 "register_operand" "2"))
17085    (use (match_operand:SI 3 "immediate_operand" "i"))
17086    (use (reg:SI DIRFLAG_REG))
17087    (clobber (match_operand:DI 0 "register_operand" "=S"))
17088    (clobber (match_operand:DI 1 "register_operand" "=D"))
17089    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17090   "TARGET_64BIT"
17091   "repz{\;| }cmpsb"
17092   [(set_attr "type" "str")
17093    (set_attr "mode" "QI")
17094    (set_attr "prefix_rep" "1")])
17095
17096 ;; The same, but the count is not known to not be zero.
17097
17098 (define_expand "cmpstrqi_1"
17099   [(parallel [(set (reg:CC FLAGS_REG)
17100                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17101                                      (const_int 0))
17102                   (compare:CC (match_operand 4 "memory_operand" "")
17103                               (match_operand 5 "memory_operand" ""))
17104                   (const_int 0)))
17105               (use (match_operand:SI 3 "immediate_operand" ""))
17106               (use (reg:CC FLAGS_REG))
17107               (use (reg:SI DIRFLAG_REG))
17108               (clobber (match_operand 0 "register_operand" ""))
17109               (clobber (match_operand 1 "register_operand" ""))
17110               (clobber (match_dup 2))])]
17111   ""
17112   "")
17113
17114 (define_insn "*cmpstrqi_1"
17115   [(set (reg:CC FLAGS_REG)
17116         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17117                              (const_int 0))
17118           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17119                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17120           (const_int 0)))
17121    (use (match_operand:SI 3 "immediate_operand" "i"))
17122    (use (reg:CC FLAGS_REG))
17123    (use (reg:SI DIRFLAG_REG))
17124    (clobber (match_operand:SI 0 "register_operand" "=S"))
17125    (clobber (match_operand:SI 1 "register_operand" "=D"))
17126    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17127   "!TARGET_64BIT"
17128   "repz{\;| }cmpsb"
17129   [(set_attr "type" "str")
17130    (set_attr "mode" "QI")
17131    (set_attr "prefix_rep" "1")])
17132
17133 (define_insn "*cmpstrqi_rex_1"
17134   [(set (reg:CC FLAGS_REG)
17135         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17136                              (const_int 0))
17137           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17138                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17139           (const_int 0)))
17140    (use (match_operand:SI 3 "immediate_operand" "i"))
17141    (use (reg:CC FLAGS_REG))
17142    (use (reg:SI DIRFLAG_REG))
17143    (clobber (match_operand:DI 0 "register_operand" "=S"))
17144    (clobber (match_operand:DI 1 "register_operand" "=D"))
17145    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17146   "TARGET_64BIT"
17147   "repz{\;| }cmpsb"
17148   [(set_attr "type" "str")
17149    (set_attr "mode" "QI")
17150    (set_attr "prefix_rep" "1")])
17151
17152 (define_expand "strlensi"
17153   [(set (match_operand:SI 0 "register_operand" "")
17154         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17155                     (match_operand:QI 2 "immediate_operand" "")
17156                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17157   ""
17158 {
17159  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17160    DONE;
17161  else
17162    FAIL;
17163 })
17164
17165 (define_expand "strlendi"
17166   [(set (match_operand:DI 0 "register_operand" "")
17167         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17168                     (match_operand:QI 2 "immediate_operand" "")
17169                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17170   ""
17171 {
17172  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17173    DONE;
17174  else
17175    FAIL;
17176 })
17177
17178 (define_expand "strlenqi_1"
17179   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17180               (use (reg:SI DIRFLAG_REG))
17181               (clobber (match_operand 1 "register_operand" ""))
17182               (clobber (reg:CC FLAGS_REG))])]
17183   ""
17184   "")
17185
17186 (define_insn "*strlenqi_1"
17187   [(set (match_operand:SI 0 "register_operand" "=&c")
17188         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17189                     (match_operand:QI 2 "register_operand" "a")
17190                     (match_operand:SI 3 "immediate_operand" "i")
17191                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17192    (use (reg:SI DIRFLAG_REG))
17193    (clobber (match_operand:SI 1 "register_operand" "=D"))
17194    (clobber (reg:CC FLAGS_REG))]
17195   "!TARGET_64BIT"
17196   "repnz{\;| }scasb"
17197   [(set_attr "type" "str")
17198    (set_attr "mode" "QI")
17199    (set_attr "prefix_rep" "1")])
17200
17201 (define_insn "*strlenqi_rex_1"
17202   [(set (match_operand:DI 0 "register_operand" "=&c")
17203         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17204                     (match_operand:QI 2 "register_operand" "a")
17205                     (match_operand:DI 3 "immediate_operand" "i")
17206                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17207    (use (reg:SI DIRFLAG_REG))
17208    (clobber (match_operand:DI 1 "register_operand" "=D"))
17209    (clobber (reg:CC FLAGS_REG))]
17210   "TARGET_64BIT"
17211   "repnz{\;| }scasb"
17212   [(set_attr "type" "str")
17213    (set_attr "mode" "QI")
17214    (set_attr "prefix_rep" "1")])
17215
17216 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17217 ;; handled in combine, but it is not currently up to the task.
17218 ;; When used for their truth value, the cmpstr* expanders generate
17219 ;; code like this:
17220 ;;
17221 ;;   repz cmpsb
17222 ;;   seta       %al
17223 ;;   setb       %dl
17224 ;;   cmpb       %al, %dl
17225 ;;   jcc        label
17226 ;;
17227 ;; The intermediate three instructions are unnecessary.
17228
17229 ;; This one handles cmpstr*_nz_1...
17230 (define_peephole2
17231   [(parallel[
17232      (set (reg:CC FLAGS_REG)
17233           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17234                       (mem:BLK (match_operand 5 "register_operand" ""))))
17235      (use (match_operand 6 "register_operand" ""))
17236      (use (match_operand:SI 3 "immediate_operand" ""))
17237      (use (reg:SI DIRFLAG_REG))
17238      (clobber (match_operand 0 "register_operand" ""))
17239      (clobber (match_operand 1 "register_operand" ""))
17240      (clobber (match_operand 2 "register_operand" ""))])
17241    (set (match_operand:QI 7 "register_operand" "")
17242         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17243    (set (match_operand:QI 8 "register_operand" "")
17244         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17245    (set (reg 17)
17246         (compare (match_dup 7) (match_dup 8)))
17247   ]
17248   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17249   [(parallel[
17250      (set (reg:CC FLAGS_REG)
17251           (compare:CC (mem:BLK (match_dup 4))
17252                       (mem:BLK (match_dup 5))))
17253      (use (match_dup 6))
17254      (use (match_dup 3))
17255      (use (reg:SI DIRFLAG_REG))
17256      (clobber (match_dup 0))
17257      (clobber (match_dup 1))
17258      (clobber (match_dup 2))])]
17259   "")
17260
17261 ;; ...and this one handles cmpstr*_1.
17262 (define_peephole2
17263   [(parallel[
17264      (set (reg:CC FLAGS_REG)
17265           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17266                                (const_int 0))
17267             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17268                         (mem:BLK (match_operand 5 "register_operand" "")))
17269             (const_int 0)))
17270      (use (match_operand:SI 3 "immediate_operand" ""))
17271      (use (reg:CC FLAGS_REG))
17272      (use (reg:SI DIRFLAG_REG))
17273      (clobber (match_operand 0 "register_operand" ""))
17274      (clobber (match_operand 1 "register_operand" ""))
17275      (clobber (match_operand 2 "register_operand" ""))])
17276    (set (match_operand:QI 7 "register_operand" "")
17277         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17278    (set (match_operand:QI 8 "register_operand" "")
17279         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17280    (set (reg 17)
17281         (compare (match_dup 7) (match_dup 8)))
17282   ]
17283   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17284   [(parallel[
17285      (set (reg:CC FLAGS_REG)
17286           (if_then_else:CC (ne (match_dup 6)
17287                                (const_int 0))
17288             (compare:CC (mem:BLK (match_dup 4))
17289                         (mem:BLK (match_dup 5)))
17290             (const_int 0)))
17291      (use (match_dup 3))
17292      (use (reg:CC FLAGS_REG))
17293      (use (reg:SI DIRFLAG_REG))
17294      (clobber (match_dup 0))
17295      (clobber (match_dup 1))
17296      (clobber (match_dup 2))])]
17297   "")
17298
17299
17300 \f
17301 ;; Conditional move instructions.
17302
17303 (define_expand "movdicc"
17304   [(set (match_operand:DI 0 "register_operand" "")
17305         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17306                          (match_operand:DI 2 "general_operand" "")
17307                          (match_operand:DI 3 "general_operand" "")))]
17308   "TARGET_64BIT"
17309   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17310
17311 (define_insn "x86_movdicc_0_m1_rex64"
17312   [(set (match_operand:DI 0 "register_operand" "=r")
17313         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17314           (const_int -1)
17315           (const_int 0)))
17316    (clobber (reg:CC FLAGS_REG))]
17317   "TARGET_64BIT"
17318   "sbb{q}\t%0, %0"
17319   ; Since we don't have the proper number of operands for an alu insn,
17320   ; fill in all the blanks.
17321   [(set_attr "type" "alu")
17322    (set_attr "pent_pair" "pu")
17323    (set_attr "memory" "none")
17324    (set_attr "imm_disp" "false")
17325    (set_attr "mode" "DI")
17326    (set_attr "length_immediate" "0")])
17327
17328 (define_insn "movdicc_c_rex64"
17329   [(set (match_operand:DI 0 "register_operand" "=r,r")
17330         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17331                                 [(reg 17) (const_int 0)])
17332                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17333                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17334   "TARGET_64BIT && TARGET_CMOVE
17335    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17336   "@
17337    cmov%O2%C1\t{%2, %0|%0, %2}
17338    cmov%O2%c1\t{%3, %0|%0, %3}"
17339   [(set_attr "type" "icmov")
17340    (set_attr "mode" "DI")])
17341
17342 (define_expand "movsicc"
17343   [(set (match_operand:SI 0 "register_operand" "")
17344         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17345                          (match_operand:SI 2 "general_operand" "")
17346                          (match_operand:SI 3 "general_operand" "")))]
17347   ""
17348   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17349
17350 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17351 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17352 ;; So just document what we're doing explicitly.
17353
17354 (define_insn "x86_movsicc_0_m1"
17355   [(set (match_operand:SI 0 "register_operand" "=r")
17356         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17357           (const_int -1)
17358           (const_int 0)))
17359    (clobber (reg:CC FLAGS_REG))]
17360   ""
17361   "sbb{l}\t%0, %0"
17362   ; Since we don't have the proper number of operands for an alu insn,
17363   ; fill in all the blanks.
17364   [(set_attr "type" "alu")
17365    (set_attr "pent_pair" "pu")
17366    (set_attr "memory" "none")
17367    (set_attr "imm_disp" "false")
17368    (set_attr "mode" "SI")
17369    (set_attr "length_immediate" "0")])
17370
17371 (define_insn "*movsicc_noc"
17372   [(set (match_operand:SI 0 "register_operand" "=r,r")
17373         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17374                                 [(reg 17) (const_int 0)])
17375                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17376                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17377   "TARGET_CMOVE
17378    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17379   "@
17380    cmov%O2%C1\t{%2, %0|%0, %2}
17381    cmov%O2%c1\t{%3, %0|%0, %3}"
17382   [(set_attr "type" "icmov")
17383    (set_attr "mode" "SI")])
17384
17385 (define_expand "movhicc"
17386   [(set (match_operand:HI 0 "register_operand" "")
17387         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17388                          (match_operand:HI 2 "general_operand" "")
17389                          (match_operand:HI 3 "general_operand" "")))]
17390   "TARGET_HIMODE_MATH"
17391   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17392
17393 (define_insn "*movhicc_noc"
17394   [(set (match_operand:HI 0 "register_operand" "=r,r")
17395         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17396                                 [(reg 17) (const_int 0)])
17397                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17398                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17399   "TARGET_CMOVE
17400    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17401   "@
17402    cmov%O2%C1\t{%2, %0|%0, %2}
17403    cmov%O2%c1\t{%3, %0|%0, %3}"
17404   [(set_attr "type" "icmov")
17405    (set_attr "mode" "HI")])
17406
17407 (define_expand "movqicc"
17408   [(set (match_operand:QI 0 "register_operand" "")
17409         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17410                          (match_operand:QI 2 "general_operand" "")
17411                          (match_operand:QI 3 "general_operand" "")))]
17412   "TARGET_QIMODE_MATH"
17413   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17414
17415 (define_insn_and_split "*movqicc_noc"
17416   [(set (match_operand:QI 0 "register_operand" "=r,r")
17417         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17418                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17419                       (match_operand:QI 2 "register_operand" "r,0")
17420                       (match_operand:QI 3 "register_operand" "0,r")))]
17421   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17422   "#"
17423   "&& reload_completed"
17424   [(set (match_dup 0)
17425         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17426                       (match_dup 2)
17427                       (match_dup 3)))]
17428   "operands[0] = gen_lowpart (SImode, operands[0]);
17429    operands[2] = gen_lowpart (SImode, operands[2]);
17430    operands[3] = gen_lowpart (SImode, operands[3]);"
17431   [(set_attr "type" "icmov")
17432    (set_attr "mode" "SI")])
17433
17434 (define_expand "movsfcc"
17435   [(set (match_operand:SF 0 "register_operand" "")
17436         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17437                          (match_operand:SF 2 "register_operand" "")
17438                          (match_operand:SF 3 "register_operand" "")))]
17439   "TARGET_CMOVE"
17440   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17441
17442 (define_insn "*movsfcc_1"
17443   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17444         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17445                                 [(reg 17) (const_int 0)])
17446                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17447                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17448   "TARGET_CMOVE
17449    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17450   "@
17451    fcmov%F1\t{%2, %0|%0, %2}
17452    fcmov%f1\t{%3, %0|%0, %3}
17453    cmov%O2%C1\t{%2, %0|%0, %2}
17454    cmov%O2%c1\t{%3, %0|%0, %3}"
17455   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17456    (set_attr "mode" "SF,SF,SI,SI")])
17457
17458 (define_expand "movdfcc"
17459   [(set (match_operand:DF 0 "register_operand" "")
17460         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17461                          (match_operand:DF 2 "register_operand" "")
17462                          (match_operand:DF 3 "register_operand" "")))]
17463   "TARGET_CMOVE"
17464   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17465
17466 (define_insn "*movdfcc_1"
17467   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17468         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17469                                 [(reg 17) (const_int 0)])
17470                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17471                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17472   "!TARGET_64BIT && TARGET_CMOVE
17473    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17474   "@
17475    fcmov%F1\t{%2, %0|%0, %2}
17476    fcmov%f1\t{%3, %0|%0, %3}
17477    #
17478    #"
17479   [(set_attr "type" "fcmov,fcmov,multi,multi")
17480    (set_attr "mode" "DF")])
17481
17482 (define_insn "*movdfcc_1_rex64"
17483   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17484         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17485                                 [(reg 17) (const_int 0)])
17486                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17487                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17488   "TARGET_64BIT && TARGET_CMOVE
17489    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17490   "@
17491    fcmov%F1\t{%2, %0|%0, %2}
17492    fcmov%f1\t{%3, %0|%0, %3}
17493    cmov%O2%C1\t{%2, %0|%0, %2}
17494    cmov%O2%c1\t{%3, %0|%0, %3}"
17495   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17496    (set_attr "mode" "DF")])
17497
17498 (define_split
17499   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17500         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17501                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17502                       (match_operand:DF 2 "nonimmediate_operand" "")
17503                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17504   "!TARGET_64BIT && reload_completed"
17505   [(set (match_dup 2)
17506         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17507                       (match_dup 5)
17508                       (match_dup 7)))
17509    (set (match_dup 3)
17510         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17511                       (match_dup 6)
17512                       (match_dup 8)))]
17513   "split_di (operands+2, 1, operands+5, operands+6);
17514    split_di (operands+3, 1, operands+7, operands+8);
17515    split_di (operands, 1, operands+2, operands+3);")
17516
17517 (define_expand "movxfcc"
17518   [(set (match_operand:XF 0 "register_operand" "")
17519         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17520                          (match_operand:XF 2 "register_operand" "")
17521                          (match_operand:XF 3 "register_operand" "")))]
17522   "TARGET_CMOVE"
17523   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17524
17525 (define_insn "*movxfcc_1"
17526   [(set (match_operand:XF 0 "register_operand" "=f,f")
17527         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17528                                 [(reg 17) (const_int 0)])
17529                       (match_operand:XF 2 "register_operand" "f,0")
17530                       (match_operand:XF 3 "register_operand" "0,f")))]
17531   "TARGET_CMOVE"
17532   "@
17533    fcmov%F1\t{%2, %0|%0, %2}
17534    fcmov%f1\t{%3, %0|%0, %3}"
17535   [(set_attr "type" "fcmov")
17536    (set_attr "mode" "XF")])
17537
17538 (define_expand "minsf3"
17539   [(parallel [
17540      (set (match_operand:SF 0 "register_operand" "")
17541           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17542                                (match_operand:SF 2 "nonimmediate_operand" ""))
17543                            (match_dup 1)
17544                            (match_dup 2)))
17545      (clobber (reg:CC FLAGS_REG))])]
17546   "TARGET_SSE"
17547   "")
17548
17549 (define_insn "*minsf"
17550   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17551         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17552                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17553                          (match_dup 1)
17554                          (match_dup 2)))
17555    (clobber (reg:CC FLAGS_REG))]
17556   "TARGET_SSE && TARGET_IEEE_FP"
17557   "#")
17558
17559 (define_insn "*minsf_nonieee"
17560   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17561         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17562                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17563                          (match_dup 1)
17564                          (match_dup 2)))
17565    (clobber (reg:CC FLAGS_REG))]
17566   "TARGET_SSE && !TARGET_IEEE_FP
17567    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17568   "#")
17569
17570 (define_split
17571   [(set (match_operand:SF 0 "register_operand" "")
17572         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17573                              (match_operand:SF 2 "nonimmediate_operand" ""))
17574                          (match_operand:SF 3 "register_operand" "")
17575                          (match_operand:SF 4 "nonimmediate_operand" "")))
17576    (clobber (reg:CC FLAGS_REG))]
17577   "SSE_REG_P (operands[0]) && reload_completed
17578    && ((operands_match_p (operands[1], operands[3])
17579         && operands_match_p (operands[2], operands[4]))
17580        || (operands_match_p (operands[1], operands[4])
17581            && operands_match_p (operands[2], operands[3])))"
17582   [(set (match_dup 0)
17583         (if_then_else:SF (lt (match_dup 1)
17584                              (match_dup 2))
17585                          (match_dup 1)
17586                          (match_dup 2)))])
17587
17588 ;; Conditional addition patterns
17589 (define_expand "addqicc"
17590   [(match_operand:QI 0 "register_operand" "")
17591    (match_operand 1 "comparison_operator" "")
17592    (match_operand:QI 2 "register_operand" "")
17593    (match_operand:QI 3 "const_int_operand" "")]
17594   ""
17595   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17596
17597 (define_expand "addhicc"
17598   [(match_operand:HI 0 "register_operand" "")
17599    (match_operand 1 "comparison_operator" "")
17600    (match_operand:HI 2 "register_operand" "")
17601    (match_operand:HI 3 "const_int_operand" "")]
17602   ""
17603   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17604
17605 (define_expand "addsicc"
17606   [(match_operand:SI 0 "register_operand" "")
17607    (match_operand 1 "comparison_operator" "")
17608    (match_operand:SI 2 "register_operand" "")
17609    (match_operand:SI 3 "const_int_operand" "")]
17610   ""
17611   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17612
17613 (define_expand "adddicc"
17614   [(match_operand:DI 0 "register_operand" "")
17615    (match_operand 1 "comparison_operator" "")
17616    (match_operand:DI 2 "register_operand" "")
17617    (match_operand:DI 3 "const_int_operand" "")]
17618   "TARGET_64BIT"
17619   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17620
17621 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17622
17623 (define_split
17624   [(set (match_operand:SF 0 "fp_register_operand" "")
17625         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17626                              (match_operand:SF 2 "register_operand" ""))
17627                          (match_operand:SF 3 "register_operand" "")
17628                          (match_operand:SF 4 "register_operand" "")))
17629    (clobber (reg:CC FLAGS_REG))]
17630   "reload_completed
17631    && ((operands_match_p (operands[1], operands[3])
17632         && operands_match_p (operands[2], operands[4]))
17633        || (operands_match_p (operands[1], operands[4])
17634            && operands_match_p (operands[2], operands[3])))"
17635   [(set (reg:CCFP FLAGS_REG)
17636         (compare:CCFP (match_dup 2)
17637                       (match_dup 1)))
17638    (set (match_dup 0)
17639         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17640                          (match_dup 1)
17641                          (match_dup 2)))])
17642
17643 (define_insn "*minsf_sse"
17644   [(set (match_operand:SF 0 "register_operand" "=x")
17645         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17646                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17647                          (match_dup 1)
17648                          (match_dup 2)))]
17649   "TARGET_SSE && reload_completed"
17650   "minss\t{%2, %0|%0, %2}"
17651   [(set_attr "type" "sse")
17652    (set_attr "mode" "SF")])
17653
17654 (define_expand "mindf3"
17655   [(parallel [
17656      (set (match_operand:DF 0 "register_operand" "")
17657           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17658                                (match_operand:DF 2 "nonimmediate_operand" ""))
17659                            (match_dup 1)
17660                            (match_dup 2)))
17661      (clobber (reg:CC FLAGS_REG))])]
17662   "TARGET_SSE2 && TARGET_SSE_MATH"
17663   "#")
17664
17665 (define_insn "*mindf"
17666   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17667         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17668                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17669                          (match_dup 1)
17670                          (match_dup 2)))
17671    (clobber (reg:CC FLAGS_REG))]
17672   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17673   "#")
17674
17675 (define_insn "*mindf_nonieee"
17676   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17677         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17678                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17679                          (match_dup 1)
17680                          (match_dup 2)))
17681    (clobber (reg:CC FLAGS_REG))]
17682   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17683    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17684   "#")
17685
17686 (define_split
17687   [(set (match_operand:DF 0 "register_operand" "")
17688         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17689                              (match_operand:DF 2 "nonimmediate_operand" ""))
17690                          (match_operand:DF 3 "register_operand" "")
17691                          (match_operand:DF 4 "nonimmediate_operand" "")))
17692    (clobber (reg:CC FLAGS_REG))]
17693   "SSE_REG_P (operands[0]) && reload_completed
17694    && ((operands_match_p (operands[1], operands[3])
17695         && operands_match_p (operands[2], operands[4]))
17696        || (operands_match_p (operands[1], operands[4])
17697            && operands_match_p (operands[2], operands[3])))"
17698   [(set (match_dup 0)
17699         (if_then_else:DF (lt (match_dup 1)
17700                              (match_dup 2))
17701                          (match_dup 1)
17702                          (match_dup 2)))])
17703
17704 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17705 (define_split
17706   [(set (match_operand:DF 0 "fp_register_operand" "")
17707         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17708                              (match_operand:DF 2 "register_operand" ""))
17709                          (match_operand:DF 3 "register_operand" "")
17710                          (match_operand:DF 4 "register_operand" "")))
17711    (clobber (reg:CC FLAGS_REG))]
17712   "reload_completed
17713    && ((operands_match_p (operands[1], operands[3])
17714         && operands_match_p (operands[2], operands[4]))
17715        || (operands_match_p (operands[1], operands[4])
17716            && operands_match_p (operands[2], operands[3])))"
17717   [(set (reg:CCFP FLAGS_REG)
17718         (compare:CCFP (match_dup 2)
17719                       (match_dup 1)))
17720    (set (match_dup 0)
17721         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17722                          (match_dup 1)
17723                          (match_dup 2)))])
17724
17725 (define_insn "*mindf_sse"
17726   [(set (match_operand:DF 0 "register_operand" "=Y")
17727         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17728                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17729                          (match_dup 1)
17730                          (match_dup 2)))]
17731   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17732   "minsd\t{%2, %0|%0, %2}"
17733   [(set_attr "type" "sse")
17734    (set_attr "mode" "DF")])
17735
17736 (define_expand "maxsf3"
17737   [(parallel [
17738      (set (match_operand:SF 0 "register_operand" "")
17739           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17740                                (match_operand:SF 2 "nonimmediate_operand" ""))
17741                            (match_dup 1)
17742                            (match_dup 2)))
17743      (clobber (reg:CC FLAGS_REG))])]
17744   "TARGET_SSE"
17745   "#")
17746
17747 (define_insn "*maxsf"
17748   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17749         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17750                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17751                          (match_dup 1)
17752                          (match_dup 2)))
17753    (clobber (reg:CC FLAGS_REG))]
17754   "TARGET_SSE && TARGET_IEEE_FP"
17755   "#")
17756
17757 (define_insn "*maxsf_nonieee"
17758   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17759         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17760                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17761                          (match_dup 1)
17762                          (match_dup 2)))
17763    (clobber (reg:CC FLAGS_REG))]
17764   "TARGET_SSE && !TARGET_IEEE_FP
17765    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17766   "#")
17767
17768 (define_split
17769   [(set (match_operand:SF 0 "register_operand" "")
17770         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17771                              (match_operand:SF 2 "nonimmediate_operand" ""))
17772                          (match_operand:SF 3 "register_operand" "")
17773                          (match_operand:SF 4 "nonimmediate_operand" "")))
17774    (clobber (reg:CC FLAGS_REG))]
17775   "SSE_REG_P (operands[0]) && 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 (match_dup 0)
17781         (if_then_else:SF (gt (match_dup 1)
17782                              (match_dup 2))
17783                          (match_dup 1)
17784                          (match_dup 2)))])
17785
17786 (define_split
17787   [(set (match_operand:SF 0 "fp_register_operand" "")
17788         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17789                              (match_operand:SF 2 "register_operand" ""))
17790                          (match_operand:SF 3 "register_operand" "")
17791                          (match_operand:SF 4 "register_operand" "")))
17792    (clobber (reg:CC FLAGS_REG))]
17793   "reload_completed
17794    && ((operands_match_p (operands[1], operands[3])
17795         && operands_match_p (operands[2], operands[4]))
17796        || (operands_match_p (operands[1], operands[4])
17797            && operands_match_p (operands[2], operands[3])))"
17798   [(set (reg:CCFP FLAGS_REG)
17799         (compare:CCFP (match_dup 1)
17800                       (match_dup 2)))
17801    (set (match_dup 0)
17802         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17803                          (match_dup 1)
17804                          (match_dup 2)))])
17805
17806 (define_insn "*maxsf_sse"
17807   [(set (match_operand:SF 0 "register_operand" "=x")
17808         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17809                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17810                          (match_dup 1)
17811                          (match_dup 2)))]
17812   "TARGET_SSE && reload_completed"
17813   "maxss\t{%2, %0|%0, %2}"
17814   [(set_attr "type" "sse")
17815    (set_attr "mode" "SF")])
17816
17817 (define_expand "maxdf3"
17818   [(parallel [
17819      (set (match_operand:DF 0 "register_operand" "")
17820           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17821                                (match_operand:DF 2 "nonimmediate_operand" ""))
17822                            (match_dup 1)
17823                            (match_dup 2)))
17824      (clobber (reg:CC FLAGS_REG))])]
17825   "TARGET_SSE2 && TARGET_SSE_MATH"
17826   "#")
17827
17828 (define_insn "*maxdf"
17829   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17830         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17831                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17832                          (match_dup 1)
17833                          (match_dup 2)))
17834    (clobber (reg:CC FLAGS_REG))]
17835   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17836   "#")
17837
17838 (define_insn "*maxdf_nonieee"
17839   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17840         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17841                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17842                          (match_dup 1)
17843                          (match_dup 2)))
17844    (clobber (reg:CC FLAGS_REG))]
17845   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17846    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17847   "#")
17848
17849 (define_split
17850   [(set (match_operand:DF 0 "register_operand" "")
17851         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17852                              (match_operand:DF 2 "nonimmediate_operand" ""))
17853                          (match_operand:DF 3 "register_operand" "")
17854                          (match_operand:DF 4 "nonimmediate_operand" "")))
17855    (clobber (reg:CC FLAGS_REG))]
17856   "SSE_REG_P (operands[0]) && 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 (match_dup 0)
17862         (if_then_else:DF (gt (match_dup 1)
17863                              (match_dup 2))
17864                          (match_dup 1)
17865                          (match_dup 2)))])
17866
17867 (define_split
17868   [(set (match_operand:DF 0 "fp_register_operand" "")
17869         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17870                              (match_operand:DF 2 "register_operand" ""))
17871                          (match_operand:DF 3 "register_operand" "")
17872                          (match_operand:DF 4 "register_operand" "")))
17873    (clobber (reg:CC FLAGS_REG))]
17874   "reload_completed
17875    && ((operands_match_p (operands[1], operands[3])
17876         && operands_match_p (operands[2], operands[4]))
17877        || (operands_match_p (operands[1], operands[4])
17878            && operands_match_p (operands[2], operands[3])))"
17879   [(set (reg:CCFP FLAGS_REG)
17880         (compare:CCFP (match_dup 1)
17881                       (match_dup 2)))
17882    (set (match_dup 0)
17883         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17884                          (match_dup 1)
17885                          (match_dup 2)))])
17886
17887 (define_insn "*maxdf_sse"
17888   [(set (match_operand:DF 0 "register_operand" "=Y")
17889         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17890                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17891                          (match_dup 1)
17892                          (match_dup 2)))]
17893   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17894   "maxsd\t{%2, %0|%0, %2}"
17895   [(set_attr "type" "sse")
17896    (set_attr "mode" "DF")])
17897 \f
17898 ;; Misc patterns (?)
17899
17900 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17901 ;; Otherwise there will be nothing to keep
17902 ;; 
17903 ;; [(set (reg ebp) (reg esp))]
17904 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17905 ;;  (clobber (eflags)]
17906 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17907 ;;
17908 ;; in proper program order.
17909 (define_insn "pro_epilogue_adjust_stack_1"
17910   [(set (match_operand:SI 0 "register_operand" "=r,r")
17911         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17912                  (match_operand:SI 2 "immediate_operand" "i,i")))
17913    (clobber (reg:CC FLAGS_REG))
17914    (clobber (mem:BLK (scratch)))]
17915   "!TARGET_64BIT"
17916 {
17917   switch (get_attr_type (insn))
17918     {
17919     case TYPE_IMOV:
17920       return "mov{l}\t{%1, %0|%0, %1}";
17921
17922     case TYPE_ALU:
17923       if (GET_CODE (operands[2]) == CONST_INT
17924           && (INTVAL (operands[2]) == 128
17925               || (INTVAL (operands[2]) < 0
17926                   && INTVAL (operands[2]) != -128)))
17927         {
17928           operands[2] = GEN_INT (-INTVAL (operands[2]));
17929           return "sub{l}\t{%2, %0|%0, %2}";
17930         }
17931       return "add{l}\t{%2, %0|%0, %2}";
17932
17933     case TYPE_LEA:
17934       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17935       return "lea{l}\t{%a2, %0|%0, %a2}";
17936
17937     default:
17938       abort ();
17939     }
17940 }
17941   [(set (attr "type")
17942         (cond [(eq_attr "alternative" "0")
17943                  (const_string "alu")
17944                (match_operand:SI 2 "const0_operand" "")
17945                  (const_string "imov")
17946               ]
17947               (const_string "lea")))
17948    (set_attr "mode" "SI")])
17949
17950 (define_insn "pro_epilogue_adjust_stack_rex64"
17951   [(set (match_operand:DI 0 "register_operand" "=r,r")
17952         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17953                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17954    (clobber (reg:CC FLAGS_REG))
17955    (clobber (mem:BLK (scratch)))]
17956   "TARGET_64BIT"
17957 {
17958   switch (get_attr_type (insn))
17959     {
17960     case TYPE_IMOV:
17961       return "mov{q}\t{%1, %0|%0, %1}";
17962
17963     case TYPE_ALU:
17964       if (GET_CODE (operands[2]) == CONST_INT
17965           /* Avoid overflows.  */
17966           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17967           && (INTVAL (operands[2]) == 128
17968               || (INTVAL (operands[2]) < 0
17969                   && INTVAL (operands[2]) != -128)))
17970         {
17971           operands[2] = GEN_INT (-INTVAL (operands[2]));
17972           return "sub{q}\t{%2, %0|%0, %2}";
17973         }
17974       return "add{q}\t{%2, %0|%0, %2}";
17975
17976     case TYPE_LEA:
17977       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17978       return "lea{q}\t{%a2, %0|%0, %a2}";
17979
17980     default:
17981       abort ();
17982     }
17983 }
17984   [(set (attr "type")
17985         (cond [(eq_attr "alternative" "0")
17986                  (const_string "alu")
17987                (match_operand:DI 2 "const0_operand" "")
17988                  (const_string "imov")
17989               ]
17990               (const_string "lea")))
17991    (set_attr "mode" "DI")])
17992
17993 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17994   [(set (match_operand:DI 0 "register_operand" "=r,r")
17995         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17996                  (match_operand:DI 3 "immediate_operand" "i,i")))
17997    (use (match_operand:DI 2 "register_operand" "r,r"))
17998    (clobber (reg:CC FLAGS_REG))
17999    (clobber (mem:BLK (scratch)))]
18000   "TARGET_64BIT"
18001 {
18002   switch (get_attr_type (insn))
18003     {
18004     case TYPE_ALU:
18005       return "add{q}\t{%2, %0|%0, %2}";
18006
18007     case TYPE_LEA:
18008       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18009       return "lea{q}\t{%a2, %0|%0, %a2}";
18010
18011     default:
18012       abort ();
18013     }
18014 }
18015   [(set_attr "type" "alu,lea")
18016    (set_attr "mode" "DI")])
18017
18018 ;; Placeholder for the conditional moves.  This one is split either to SSE
18019 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18020 ;; fact is that compares supported by the cmp??ss instructions are exactly
18021 ;; swapped of those supported by cmove sequence.
18022 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18023 ;; supported by i387 comparisons and we do need to emit two conditional moves
18024 ;; in tandem.
18025
18026 (define_insn "sse_movsfcc"
18027   [(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")
18028         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18029                         [(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")
18030                          (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")])
18031                       (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")
18032                       (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")))
18033    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18034    (clobber (reg:CC FLAGS_REG))]
18035   "TARGET_SSE
18036    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18037    /* Avoid combine from being smart and converting min/max
18038       instruction patterns into conditional moves.  */
18039    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18040         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18041        || !rtx_equal_p (operands[4], operands[2])
18042        || !rtx_equal_p (operands[5], operands[3]))
18043    && (!TARGET_IEEE_FP
18044        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18045   "#")
18046
18047 (define_insn "sse_movsfcc_eq"
18048   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18049         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18050                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18051                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18052                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18053    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18054    (clobber (reg:CC FLAGS_REG))]
18055   "TARGET_SSE
18056    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18057   "#")
18058
18059 (define_insn "sse_movdfcc"
18060   [(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")
18061         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18062                         [(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")
18063                          (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")])
18064                       (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")
18065                       (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")))
18066    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18067    (clobber (reg:CC FLAGS_REG))]
18068   "TARGET_SSE2
18069    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18070    /* Avoid combine from being smart and converting min/max
18071       instruction patterns into conditional moves.  */
18072    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18073         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18074        || !rtx_equal_p (operands[4], operands[2])
18075        || !rtx_equal_p (operands[5], operands[3]))
18076    && (!TARGET_IEEE_FP
18077        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18078   "#")
18079
18080 (define_insn "sse_movdfcc_eq"
18081   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18082         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18083                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18084                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18085                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18086    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18087    (clobber (reg:CC FLAGS_REG))]
18088   "TARGET_SSE
18089    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18090   "#")
18091
18092 ;; For non-sse moves just expand the usual cmove sequence.
18093 (define_split
18094   [(set (match_operand 0 "register_operand" "")
18095         (if_then_else (match_operator 1 "comparison_operator"
18096                         [(match_operand 4 "nonimmediate_operand" "")
18097                          (match_operand 5 "register_operand" "")])
18098                       (match_operand 2 "nonimmediate_operand" "")
18099                       (match_operand 3 "nonimmediate_operand" "")))
18100    (clobber (match_operand 6 "" ""))
18101    (clobber (reg:CC FLAGS_REG))]
18102   "!SSE_REG_P (operands[0]) && reload_completed
18103    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18104   [(const_int 0)]
18105 {
18106    ix86_compare_op0 = operands[5];
18107    ix86_compare_op1 = operands[4];
18108    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18109                                  VOIDmode, operands[5], operands[4]);
18110    ix86_expand_fp_movcc (operands);
18111    DONE;
18112 })
18113
18114 ;; Split SSE based conditional move into sequence:
18115 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18116 ;; and   op2, op0   -  zero op2 if comparison was false
18117 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18118 ;; or    op2, op0   -  get the nonzero one into the result.
18119 (define_split
18120   [(set (match_operand:SF 0 "register_operand" "")
18121         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18122                         [(match_operand:SF 4 "register_operand" "")
18123                          (match_operand:SF 5 "nonimmediate_operand" "")])
18124                       (match_operand:SF 2 "register_operand" "")
18125                       (match_operand:SF 3 "register_operand" "")))
18126    (clobber (match_operand 6 "" ""))
18127    (clobber (reg:CC FLAGS_REG))]
18128   "SSE_REG_P (operands[0]) && reload_completed"
18129   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18130    (set (match_dup 2) (and:V4SF (match_dup 2)
18131                                 (match_dup 8)))
18132    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18133                                           (match_dup 3)))
18134    (set (match_dup 0) (ior:V4SF (match_dup 6)
18135                                 (match_dup 7)))]
18136 {
18137   /* If op2 == op3, op3 would be clobbered before it is used.  */
18138   if (operands_match_p (operands[2], operands[3]))
18139     {
18140       emit_move_insn (operands[0], operands[2]);
18141       DONE;
18142     }
18143
18144   PUT_MODE (operands[1], GET_MODE (operands[0]));
18145   if (operands_match_p (operands[0], operands[4]))
18146     operands[6] = operands[4], operands[7] = operands[2];
18147   else
18148     operands[6] = operands[2], operands[7] = operands[4];
18149   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18150   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18151   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18152   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18153   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18154   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18155 })
18156
18157 (define_split
18158   [(set (match_operand:DF 0 "register_operand" "")
18159         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18160                         [(match_operand:DF 4 "register_operand" "")
18161                          (match_operand:DF 5 "nonimmediate_operand" "")])
18162                       (match_operand:DF 2 "register_operand" "")
18163                       (match_operand:DF 3 "register_operand" "")))
18164    (clobber (match_operand 6 "" ""))
18165    (clobber (reg:CC FLAGS_REG))]
18166   "SSE_REG_P (operands[0]) && reload_completed"
18167   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18168    (set (match_dup 2) (and:V2DF (match_dup 2)
18169                                 (match_dup 8)))
18170    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18171                                           (match_dup 3)))
18172    (set (match_dup 0) (ior:V2DF (match_dup 6)
18173                                 (match_dup 7)))]
18174 {
18175   if (GET_MODE (operands[2]) == DFmode
18176       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18177     {
18178       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18179       emit_insn (gen_sse2_unpcklpd (op, op, op));
18180       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18181       emit_insn (gen_sse2_unpcklpd (op, op, op));
18182     }
18183
18184   /* If op2 == op3, op3 would be clobbered before it is used.  */
18185   if (operands_match_p (operands[2], operands[3]))
18186     {
18187       emit_move_insn (operands[0], operands[2]);
18188       DONE;
18189     }
18190
18191   PUT_MODE (operands[1], GET_MODE (operands[0]));
18192   if (operands_match_p (operands[0], operands[4]))
18193     operands[6] = operands[4], operands[7] = operands[2];
18194   else
18195     operands[6] = operands[2], operands[7] = operands[4];
18196   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18197   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18198   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18199   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18200   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18201   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18202 })
18203
18204 ;; Special case of conditional move we can handle effectively.
18205 ;; Do not brother with the integer/floating point case, since these are
18206 ;; bot considerably slower, unlike in the generic case.
18207 (define_insn "*sse_movsfcc_const0_1"
18208   [(set (match_operand:SF 0 "register_operand" "=&x")
18209         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18210                         [(match_operand:SF 4 "register_operand" "0")
18211                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18212                       (match_operand:SF 2 "register_operand" "x")
18213                       (match_operand:SF 3 "const0_operand" "X")))]
18214   "TARGET_SSE"
18215   "#")
18216
18217 (define_insn "*sse_movsfcc_const0_2"
18218   [(set (match_operand:SF 0 "register_operand" "=&x")
18219         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18220                         [(match_operand:SF 4 "register_operand" "0")
18221                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18222                       (match_operand:SF 2 "const0_operand" "X")
18223                       (match_operand:SF 3 "register_operand" "x")))]
18224   "TARGET_SSE"
18225   "#")
18226
18227 (define_insn "*sse_movsfcc_const0_3"
18228   [(set (match_operand:SF 0 "register_operand" "=&x")
18229         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18230                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18231                          (match_operand:SF 5 "register_operand" "0")])
18232                       (match_operand:SF 2 "register_operand" "x")
18233                       (match_operand:SF 3 "const0_operand" "X")))]
18234   "TARGET_SSE"
18235   "#")
18236
18237 (define_insn "*sse_movsfcc_const0_4"
18238   [(set (match_operand:SF 0 "register_operand" "=&x")
18239         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18240                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18241                          (match_operand:SF 5 "register_operand" "0")])
18242                       (match_operand:SF 2 "const0_operand" "X")
18243                       (match_operand:SF 3 "register_operand" "x")))]
18244   "TARGET_SSE"
18245   "#")
18246
18247 (define_insn "*sse_movdfcc_const0_1"
18248   [(set (match_operand:DF 0 "register_operand" "=&Y")
18249         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18250                         [(match_operand:DF 4 "register_operand" "0")
18251                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18252                       (match_operand:DF 2 "register_operand" "Y")
18253                       (match_operand:DF 3 "const0_operand" "X")))]
18254   "TARGET_SSE2"
18255   "#")
18256
18257 (define_insn "*sse_movdfcc_const0_2"
18258   [(set (match_operand:DF 0 "register_operand" "=&Y")
18259         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18260                         [(match_operand:DF 4 "register_operand" "0")
18261                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18262                       (match_operand:DF 2 "const0_operand" "X")
18263                       (match_operand:DF 3 "register_operand" "Y")))]
18264   "TARGET_SSE2"
18265   "#")
18266
18267 (define_insn "*sse_movdfcc_const0_3"
18268   [(set (match_operand:DF 0 "register_operand" "=&Y")
18269         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18270                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18271                          (match_operand:DF 5 "register_operand" "0")])
18272                       (match_operand:DF 2 "register_operand" "Y")
18273                       (match_operand:DF 3 "const0_operand" "X")))]
18274   "TARGET_SSE2"
18275   "#")
18276
18277 (define_insn "*sse_movdfcc_const0_4"
18278   [(set (match_operand:DF 0 "register_operand" "=&Y")
18279         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18280                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18281                          (match_operand:DF 5 "register_operand" "0")])
18282                       (match_operand:DF 2 "const0_operand" "X")
18283                       (match_operand:DF 3 "register_operand" "Y")))]
18284   "TARGET_SSE2"
18285   "#")
18286
18287 (define_split
18288   [(set (match_operand:SF 0 "register_operand" "")
18289         (if_then_else (match_operator 1 "comparison_operator"
18290                         [(match_operand:SF 4 "nonimmediate_operand" "")
18291                          (match_operand:SF 5 "nonimmediate_operand" "")])
18292                       (match_operand:SF 2 "nonmemory_operand" "")
18293                       (match_operand:SF 3 "nonmemory_operand" "")))]
18294   "SSE_REG_P (operands[0]) && reload_completed
18295    && (const0_operand (operands[2], GET_MODE (operands[0]))
18296        || const0_operand (operands[3], GET_MODE (operands[0])))"
18297   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18298    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18299 {
18300   PUT_MODE (operands[1], GET_MODE (operands[0]));
18301   if (!sse_comparison_operator (operands[1], VOIDmode)
18302       || !rtx_equal_p (operands[0], operands[4]))
18303     {
18304       rtx tmp = operands[5];
18305       operands[5] = operands[4];
18306       operands[4] = tmp;
18307       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18308     }
18309   if (!rtx_equal_p (operands[0], operands[4]))
18310     abort ();
18311   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18312   if (const0_operand (operands[2], GET_MODE (operands[2])))
18313     {
18314       operands[7] = operands[3];
18315       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18316     }
18317   else
18318     {
18319       operands[7] = operands[2];
18320       operands[6] = operands[8];
18321     }
18322   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18323 })
18324
18325 (define_split
18326   [(set (match_operand:DF 0 "register_operand" "")
18327         (if_then_else (match_operator 1 "comparison_operator"
18328                         [(match_operand:DF 4 "nonimmediate_operand" "")
18329                          (match_operand:DF 5 "nonimmediate_operand" "")])
18330                       (match_operand:DF 2 "nonmemory_operand" "")
18331                       (match_operand:DF 3 "nonmemory_operand" "")))]
18332   "SSE_REG_P (operands[0]) && reload_completed
18333    && (const0_operand (operands[2], GET_MODE (operands[0]))
18334        || const0_operand (operands[3], GET_MODE (operands[0])))"
18335   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18336    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18337 {
18338   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18339       && GET_MODE (operands[2]) == DFmode)
18340     {
18341       if (REG_P (operands[2]))
18342         {
18343           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18344           emit_insn (gen_sse2_unpcklpd (op, op, op));
18345         }
18346       if (REG_P (operands[3]))
18347         {
18348           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18349           emit_insn (gen_sse2_unpcklpd (op, op, op));
18350         }
18351     }
18352   PUT_MODE (operands[1], GET_MODE (operands[0]));
18353   if (!sse_comparison_operator (operands[1], VOIDmode)
18354       || !rtx_equal_p (operands[0], operands[4]))
18355     {
18356       rtx tmp = operands[5];
18357       operands[5] = operands[4];
18358       operands[4] = tmp;
18359       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18360     }
18361   if (!rtx_equal_p (operands[0], operands[4]))
18362     abort ();
18363   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18364   if (const0_operand (operands[2], GET_MODE (operands[2])))
18365     {
18366       operands[7] = operands[3];
18367       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18368     }
18369   else
18370     {
18371       operands[7] = operands[2];
18372       operands[6] = operands[8];
18373     }
18374   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18375 })
18376
18377 (define_expand "allocate_stack_worker"
18378   [(match_operand:SI 0 "register_operand" "")]
18379   "TARGET_STACK_PROBE"
18380 {
18381   if (reload_completed)
18382     {
18383       if (TARGET_64BIT)
18384         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18385       else
18386         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18387     }
18388   else
18389     {
18390       if (TARGET_64BIT)
18391         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18392       else
18393         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18394     }
18395   DONE;
18396 })
18397
18398 (define_insn "allocate_stack_worker_1"
18399   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18400     UNSPECV_STACK_PROBE)
18401    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18402    (clobber (match_scratch:SI 1 "=0"))
18403    (clobber (reg:CC FLAGS_REG))]
18404   "!TARGET_64BIT && TARGET_STACK_PROBE"
18405   "call\t__alloca"
18406   [(set_attr "type" "multi")
18407    (set_attr "length" "5")])
18408
18409 (define_expand "allocate_stack_worker_postreload"
18410   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18411                                     UNSPECV_STACK_PROBE)
18412               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18413               (clobber (match_dup 0))
18414               (clobber (reg:CC FLAGS_REG))])]
18415   ""
18416   "")
18417
18418 (define_insn "allocate_stack_worker_rex64"
18419   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18420     UNSPECV_STACK_PROBE)
18421    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18422    (clobber (match_scratch:DI 1 "=0"))
18423    (clobber (reg:CC FLAGS_REG))]
18424   "TARGET_64BIT && TARGET_STACK_PROBE"
18425   "call\t__alloca"
18426   [(set_attr "type" "multi")
18427    (set_attr "length" "5")])
18428
18429 (define_expand "allocate_stack_worker_rex64_postreload"
18430   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18431                                     UNSPECV_STACK_PROBE)
18432               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18433               (clobber (match_dup 0))
18434               (clobber (reg:CC FLAGS_REG))])]
18435   ""
18436   "")
18437
18438 (define_expand "allocate_stack"
18439   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18440                    (minus:SI (reg:SI SP_REG)
18441                              (match_operand:SI 1 "general_operand" "")))
18442               (clobber (reg:CC FLAGS_REG))])
18443    (parallel [(set (reg:SI SP_REG)
18444                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18445               (clobber (reg:CC FLAGS_REG))])]
18446   "TARGET_STACK_PROBE"
18447 {
18448 #ifdef CHECK_STACK_LIMIT
18449   if (GET_CODE (operands[1]) == CONST_INT
18450       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18451     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18452                            operands[1]));
18453   else 
18454 #endif
18455     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18456                                                             operands[1])));
18457
18458   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18459   DONE;
18460 })
18461
18462 (define_expand "builtin_setjmp_receiver"
18463   [(label_ref (match_operand 0 "" ""))]
18464   "!TARGET_64BIT && flag_pic"
18465 {
18466   emit_insn (gen_set_got (pic_offset_table_rtx));
18467   DONE;
18468 })
18469 \f
18470 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18471
18472 (define_split
18473   [(set (match_operand 0 "register_operand" "")
18474         (match_operator 3 "promotable_binary_operator"
18475            [(match_operand 1 "register_operand" "")
18476             (match_operand 2 "aligned_operand" "")]))
18477    (clobber (reg:CC FLAGS_REG))]
18478   "! TARGET_PARTIAL_REG_STALL && reload_completed
18479    && ((GET_MODE (operands[0]) == HImode 
18480         && ((!optimize_size && !TARGET_FAST_PREFIX)
18481             || GET_CODE (operands[2]) != CONST_INT
18482             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18483        || (GET_MODE (operands[0]) == QImode 
18484            && (TARGET_PROMOTE_QImode || optimize_size)))"
18485   [(parallel [(set (match_dup 0)
18486                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18487               (clobber (reg:CC FLAGS_REG))])]
18488   "operands[0] = gen_lowpart (SImode, operands[0]);
18489    operands[1] = gen_lowpart (SImode, operands[1]);
18490    if (GET_CODE (operands[3]) != ASHIFT)
18491      operands[2] = gen_lowpart (SImode, operands[2]);
18492    PUT_MODE (operands[3], SImode);")
18493
18494 ; Promote the QImode tests, as i386 has encoding of the AND
18495 ; instruction with 32-bit sign-extended immediate and thus the
18496 ; instruction size is unchanged, except in the %eax case for
18497 ; which it is increased by one byte, hence the ! optimize_size.
18498 (define_split
18499   [(set (reg 17)
18500         (compare (and (match_operand 1 "aligned_operand" "")
18501                       (match_operand 2 "const_int_operand" ""))
18502                  (const_int 0)))
18503    (set (match_operand 0 "register_operand" "")
18504         (and (match_dup 1) (match_dup 2)))]
18505   "! TARGET_PARTIAL_REG_STALL && reload_completed
18506    /* Ensure that the operand will remain sign-extended immediate.  */
18507    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18508    && ! optimize_size
18509    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18510        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18511   [(parallel [(set (reg:CCNO FLAGS_REG)
18512                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18513                                  (const_int 0)))
18514               (set (match_dup 0)
18515                    (and:SI (match_dup 1) (match_dup 2)))])]
18516   "operands[2]
18517      = gen_int_mode (INTVAL (operands[2])
18518                      & GET_MODE_MASK (GET_MODE (operands[0])),
18519                      SImode);
18520    operands[0] = gen_lowpart (SImode, operands[0]);
18521    operands[1] = gen_lowpart (SImode, operands[1]);")
18522
18523 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18524 ; the TEST instruction with 32-bit sign-extended immediate and thus
18525 ; the instruction size would at least double, which is not what we
18526 ; want even with ! optimize_size.
18527 (define_split
18528   [(set (reg 17)
18529         (compare (and (match_operand:HI 0 "aligned_operand" "")
18530                       (match_operand:HI 1 "const_int_operand" ""))
18531                  (const_int 0)))]
18532   "! TARGET_PARTIAL_REG_STALL && reload_completed
18533    /* Ensure that the operand will remain sign-extended immediate.  */
18534    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18535    && ! TARGET_FAST_PREFIX
18536    && ! optimize_size"
18537   [(set (reg:CCNO FLAGS_REG)
18538         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18539                       (const_int 0)))]
18540   "operands[1]
18541      = gen_int_mode (INTVAL (operands[1])
18542                      & GET_MODE_MASK (GET_MODE (operands[0])),
18543                      SImode);
18544    operands[0] = gen_lowpart (SImode, operands[0]);")
18545
18546 (define_split
18547   [(set (match_operand 0 "register_operand" "")
18548         (neg (match_operand 1 "register_operand" "")))
18549    (clobber (reg:CC FLAGS_REG))]
18550   "! TARGET_PARTIAL_REG_STALL && reload_completed
18551    && (GET_MODE (operands[0]) == HImode
18552        || (GET_MODE (operands[0]) == QImode 
18553            && (TARGET_PROMOTE_QImode || optimize_size)))"
18554   [(parallel [(set (match_dup 0)
18555                    (neg:SI (match_dup 1)))
18556               (clobber (reg:CC FLAGS_REG))])]
18557   "operands[0] = gen_lowpart (SImode, operands[0]);
18558    operands[1] = gen_lowpart (SImode, operands[1]);")
18559
18560 (define_split
18561   [(set (match_operand 0 "register_operand" "")
18562         (not (match_operand 1 "register_operand" "")))]
18563   "! TARGET_PARTIAL_REG_STALL && reload_completed
18564    && (GET_MODE (operands[0]) == HImode
18565        || (GET_MODE (operands[0]) == QImode 
18566            && (TARGET_PROMOTE_QImode || optimize_size)))"
18567   [(set (match_dup 0)
18568         (not:SI (match_dup 1)))]
18569   "operands[0] = gen_lowpart (SImode, operands[0]);
18570    operands[1] = gen_lowpart (SImode, operands[1]);")
18571
18572 (define_split 
18573   [(set (match_operand 0 "register_operand" "")
18574         (if_then_else (match_operator 1 "comparison_operator" 
18575                                 [(reg 17) (const_int 0)])
18576                       (match_operand 2 "register_operand" "")
18577                       (match_operand 3 "register_operand" "")))]
18578   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18579    && (GET_MODE (operands[0]) == HImode
18580        || (GET_MODE (operands[0]) == QImode 
18581            && (TARGET_PROMOTE_QImode || optimize_size)))"
18582   [(set (match_dup 0)
18583         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18584   "operands[0] = gen_lowpart (SImode, operands[0]);
18585    operands[2] = gen_lowpart (SImode, operands[2]);
18586    operands[3] = gen_lowpart (SImode, operands[3]);")
18587                         
18588 \f
18589 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18590 ;; transform a complex memory operation into two memory to register operations.
18591
18592 ;; Don't push memory operands
18593 (define_peephole2
18594   [(set (match_operand:SI 0 "push_operand" "")
18595         (match_operand:SI 1 "memory_operand" ""))
18596    (match_scratch:SI 2 "r")]
18597   "! optimize_size && ! TARGET_PUSH_MEMORY"
18598   [(set (match_dup 2) (match_dup 1))
18599    (set (match_dup 0) (match_dup 2))]
18600   "")
18601
18602 (define_peephole2
18603   [(set (match_operand:DI 0 "push_operand" "")
18604         (match_operand:DI 1 "memory_operand" ""))
18605    (match_scratch:DI 2 "r")]
18606   "! optimize_size && ! TARGET_PUSH_MEMORY"
18607   [(set (match_dup 2) (match_dup 1))
18608    (set (match_dup 0) (match_dup 2))]
18609   "")
18610
18611 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18612 ;; SImode pushes.
18613 (define_peephole2
18614   [(set (match_operand:SF 0 "push_operand" "")
18615         (match_operand:SF 1 "memory_operand" ""))
18616    (match_scratch:SF 2 "r")]
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 (define_peephole2
18623   [(set (match_operand:HI 0 "push_operand" "")
18624         (match_operand:HI 1 "memory_operand" ""))
18625    (match_scratch:HI 2 "r")]
18626   "! optimize_size && ! TARGET_PUSH_MEMORY"
18627   [(set (match_dup 2) (match_dup 1))
18628    (set (match_dup 0) (match_dup 2))]
18629   "")
18630
18631 (define_peephole2
18632   [(set (match_operand:QI 0 "push_operand" "")
18633         (match_operand:QI 1 "memory_operand" ""))
18634    (match_scratch:QI 2 "q")]
18635   "! optimize_size && ! TARGET_PUSH_MEMORY"
18636   [(set (match_dup 2) (match_dup 1))
18637    (set (match_dup 0) (match_dup 2))]
18638   "")
18639
18640 ;; Don't move an immediate directly to memory when the instruction
18641 ;; gets too big.
18642 (define_peephole2
18643   [(match_scratch:SI 1 "r")
18644    (set (match_operand:SI 0 "memory_operand" "")
18645         (const_int 0))]
18646   "! optimize_size
18647    && ! TARGET_USE_MOV0
18648    && TARGET_SPLIT_LONG_MOVES
18649    && get_attr_length (insn) >= ix86_cost->large_insn
18650    && peep2_regno_dead_p (0, FLAGS_REG)"
18651   [(parallel [(set (match_dup 1) (const_int 0))
18652               (clobber (reg:CC FLAGS_REG))])
18653    (set (match_dup 0) (match_dup 1))]
18654   "")
18655
18656 (define_peephole2
18657   [(match_scratch:HI 1 "r")
18658    (set (match_operand:HI 0 "memory_operand" "")
18659         (const_int 0))]
18660   "! optimize_size
18661    && ! TARGET_USE_MOV0
18662    && TARGET_SPLIT_LONG_MOVES
18663    && get_attr_length (insn) >= ix86_cost->large_insn
18664    && peep2_regno_dead_p (0, FLAGS_REG)"
18665   [(parallel [(set (match_dup 2) (const_int 0))
18666               (clobber (reg:CC FLAGS_REG))])
18667    (set (match_dup 0) (match_dup 1))]
18668   "operands[2] = gen_lowpart (SImode, operands[1]);")
18669
18670 (define_peephole2
18671   [(match_scratch:QI 1 "q")
18672    (set (match_operand:QI 0 "memory_operand" "")
18673         (const_int 0))]
18674   "! optimize_size
18675    && ! TARGET_USE_MOV0
18676    && TARGET_SPLIT_LONG_MOVES
18677    && get_attr_length (insn) >= ix86_cost->large_insn
18678    && peep2_regno_dead_p (0, FLAGS_REG)"
18679   [(parallel [(set (match_dup 2) (const_int 0))
18680               (clobber (reg:CC FLAGS_REG))])
18681    (set (match_dup 0) (match_dup 1))]
18682   "operands[2] = gen_lowpart (SImode, operands[1]);")
18683
18684 (define_peephole2
18685   [(match_scratch:SI 2 "r")
18686    (set (match_operand:SI 0 "memory_operand" "")
18687         (match_operand:SI 1 "immediate_operand" ""))]
18688   "! optimize_size
18689    && get_attr_length (insn) >= ix86_cost->large_insn
18690    && TARGET_SPLIT_LONG_MOVES"
18691   [(set (match_dup 2) (match_dup 1))
18692    (set (match_dup 0) (match_dup 2))]
18693   "")
18694
18695 (define_peephole2
18696   [(match_scratch:HI 2 "r")
18697    (set (match_operand:HI 0 "memory_operand" "")
18698         (match_operand:HI 1 "immediate_operand" ""))]
18699   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18700   && TARGET_SPLIT_LONG_MOVES"
18701   [(set (match_dup 2) (match_dup 1))
18702    (set (match_dup 0) (match_dup 2))]
18703   "")
18704
18705 (define_peephole2
18706   [(match_scratch:QI 2 "q")
18707    (set (match_operand:QI 0 "memory_operand" "")
18708         (match_operand:QI 1 "immediate_operand" ""))]
18709   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18710   && TARGET_SPLIT_LONG_MOVES"
18711   [(set (match_dup 2) (match_dup 1))
18712    (set (match_dup 0) (match_dup 2))]
18713   "")
18714
18715 ;; Don't compare memory with zero, load and use a test instead.
18716 (define_peephole2
18717   [(set (reg 17)
18718         (compare (match_operand:SI 0 "memory_operand" "")
18719                  (const_int 0)))
18720    (match_scratch:SI 3 "r")]
18721   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18722   [(set (match_dup 3) (match_dup 0))
18723    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
18724   "")
18725
18726 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18727 ;; Don't split NOTs with a displacement operand, because resulting XOR
18728 ;; will not be pairable anyway.
18729 ;;
18730 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18731 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18732 ;; so this split helps here as well.
18733 ;;
18734 ;; Note: Can't do this as a regular split because we can't get proper
18735 ;; lifetime information then.
18736
18737 (define_peephole2
18738   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18739         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18740   "!optimize_size
18741    && peep2_regno_dead_p (0, FLAGS_REG)
18742    && ((TARGET_PENTIUM 
18743         && (GET_CODE (operands[0]) != MEM
18744             || !memory_displacement_operand (operands[0], SImode)))
18745        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18746   [(parallel [(set (match_dup 0)
18747                    (xor:SI (match_dup 1) (const_int -1)))
18748               (clobber (reg:CC FLAGS_REG))])]
18749   "")
18750
18751 (define_peephole2
18752   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18753         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18754   "!optimize_size
18755    && peep2_regno_dead_p (0, FLAGS_REG)
18756    && ((TARGET_PENTIUM 
18757         && (GET_CODE (operands[0]) != MEM
18758             || !memory_displacement_operand (operands[0], HImode)))
18759        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18760   [(parallel [(set (match_dup 0)
18761                    (xor:HI (match_dup 1) (const_int -1)))
18762               (clobber (reg:CC FLAGS_REG))])]
18763   "")
18764
18765 (define_peephole2
18766   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18767         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18768   "!optimize_size
18769    && peep2_regno_dead_p (0, FLAGS_REG)
18770    && ((TARGET_PENTIUM 
18771         && (GET_CODE (operands[0]) != MEM
18772             || !memory_displacement_operand (operands[0], QImode)))
18773        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18774   [(parallel [(set (match_dup 0)
18775                    (xor:QI (match_dup 1) (const_int -1)))
18776               (clobber (reg:CC FLAGS_REG))])]
18777   "")
18778
18779 ;; Non pairable "test imm, reg" instructions can be translated to
18780 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18781 ;; byte opcode instead of two, have a short form for byte operands),
18782 ;; so do it for other CPUs as well.  Given that the value was dead,
18783 ;; this should not create any new dependencies.  Pass on the sub-word
18784 ;; versions if we're concerned about partial register stalls.
18785
18786 (define_peephole2
18787   [(set (reg 17)
18788         (compare (and:SI (match_operand:SI 0 "register_operand" "")
18789                          (match_operand:SI 1 "immediate_operand" ""))
18790                  (const_int 0)))]
18791   "ix86_match_ccmode (insn, CCNOmode)
18792    && (true_regnum (operands[0]) != 0
18793        || (GET_CODE (operands[1]) == CONST_INT
18794            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18795    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18796   [(parallel
18797      [(set (reg:CCNO FLAGS_REG)
18798            (compare:CCNO (and:SI (match_dup 0)
18799                                  (match_dup 1))
18800                          (const_int 0)))
18801       (set (match_dup 0)
18802            (and:SI (match_dup 0) (match_dup 1)))])]
18803   "")
18804
18805 ;; We don't need to handle HImode case, because it will be promoted to SImode
18806 ;; on ! TARGET_PARTIAL_REG_STALL
18807
18808 (define_peephole2
18809   [(set (reg 17)
18810         (compare (and:QI (match_operand:QI 0 "register_operand" "")
18811                          (match_operand:QI 1 "immediate_operand" ""))
18812                  (const_int 0)))]
18813   "! TARGET_PARTIAL_REG_STALL
18814    && ix86_match_ccmode (insn, CCNOmode)
18815    && true_regnum (operands[0]) != 0
18816    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18817   [(parallel
18818      [(set (reg:CCNO FLAGS_REG)
18819            (compare:CCNO (and:QI (match_dup 0)
18820                                  (match_dup 1))
18821                          (const_int 0)))
18822       (set (match_dup 0)
18823            (and:QI (match_dup 0) (match_dup 1)))])]
18824   "")
18825
18826 (define_peephole2
18827   [(set (reg 17)
18828         (compare
18829           (and:SI
18830             (zero_extract:SI
18831               (match_operand 0 "ext_register_operand" "")
18832               (const_int 8)
18833               (const_int 8))
18834             (match_operand 1 "const_int_operand" ""))
18835           (const_int 0)))]
18836   "! TARGET_PARTIAL_REG_STALL
18837    && ix86_match_ccmode (insn, CCNOmode)
18838    && true_regnum (operands[0]) != 0
18839    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18840   [(parallel [(set (reg:CCNO FLAGS_REG)
18841                    (compare:CCNO
18842                        (and:SI
18843                          (zero_extract:SI
18844                          (match_dup 0)
18845                          (const_int 8)
18846                          (const_int 8))
18847                         (match_dup 1))
18848                    (const_int 0)))
18849               (set (zero_extract:SI (match_dup 0)
18850                                     (const_int 8)
18851                                     (const_int 8))
18852                    (and:SI 
18853                      (zero_extract:SI
18854                        (match_dup 0)
18855                        (const_int 8)
18856                        (const_int 8))
18857                      (match_dup 1)))])]
18858   "")
18859
18860 ;; Don't do logical operations with memory inputs.
18861 (define_peephole2
18862   [(match_scratch:SI 2 "r")
18863    (parallel [(set (match_operand:SI 0 "register_operand" "")
18864                    (match_operator:SI 3 "arith_or_logical_operator"
18865                      [(match_dup 0)
18866                       (match_operand:SI 1 "memory_operand" "")]))
18867               (clobber (reg:CC FLAGS_REG))])]
18868   "! optimize_size && ! TARGET_READ_MODIFY"
18869   [(set (match_dup 2) (match_dup 1))
18870    (parallel [(set (match_dup 0)
18871                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18872               (clobber (reg:CC FLAGS_REG))])]
18873   "")
18874
18875 (define_peephole2
18876   [(match_scratch:SI 2 "r")
18877    (parallel [(set (match_operand:SI 0 "register_operand" "")
18878                    (match_operator:SI 3 "arith_or_logical_operator"
18879                      [(match_operand:SI 1 "memory_operand" "")
18880                       (match_dup 0)]))
18881               (clobber (reg:CC FLAGS_REG))])]
18882   "! optimize_size && ! TARGET_READ_MODIFY"
18883   [(set (match_dup 2) (match_dup 1))
18884    (parallel [(set (match_dup 0)
18885                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18886               (clobber (reg:CC FLAGS_REG))])]
18887   "")
18888
18889 ; Don't do logical operations with memory outputs
18890 ;
18891 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18892 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18893 ; the same decoder scheduling characteristics as the original.
18894
18895 (define_peephole2
18896   [(match_scratch:SI 2 "r")
18897    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18898                    (match_operator:SI 3 "arith_or_logical_operator"
18899                      [(match_dup 0)
18900                       (match_operand:SI 1 "nonmemory_operand" "")]))
18901               (clobber (reg:CC FLAGS_REG))])]
18902   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18903   [(set (match_dup 2) (match_dup 0))
18904    (parallel [(set (match_dup 2)
18905                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18906               (clobber (reg:CC FLAGS_REG))])
18907    (set (match_dup 0) (match_dup 2))]
18908   "")
18909
18910 (define_peephole2
18911   [(match_scratch:SI 2 "r")
18912    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18913                    (match_operator:SI 3 "arith_or_logical_operator"
18914                      [(match_operand:SI 1 "nonmemory_operand" "")
18915                       (match_dup 0)]))
18916               (clobber (reg:CC FLAGS_REG))])]
18917   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18918   [(set (match_dup 2) (match_dup 0))
18919    (parallel [(set (match_dup 2)
18920                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18921               (clobber (reg:CC FLAGS_REG))])
18922    (set (match_dup 0) (match_dup 2))]
18923   "")
18924
18925 ;; Attempt to always use XOR for zeroing registers.
18926 (define_peephole2
18927   [(set (match_operand 0 "register_operand" "")
18928         (const_int 0))]
18929   "(GET_MODE (operands[0]) == QImode
18930     || GET_MODE (operands[0]) == HImode
18931     || GET_MODE (operands[0]) == SImode
18932     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18933    && (! TARGET_USE_MOV0 || optimize_size)
18934    && peep2_regno_dead_p (0, FLAGS_REG)"
18935   [(parallel [(set (match_dup 0) (const_int 0))
18936               (clobber (reg:CC FLAGS_REG))])]
18937   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18938                               operands[0]);")
18939
18940 (define_peephole2
18941   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18942         (const_int 0))]
18943   "(GET_MODE (operands[0]) == QImode
18944     || GET_MODE (operands[0]) == HImode)
18945    && (! TARGET_USE_MOV0 || optimize_size)
18946    && peep2_regno_dead_p (0, FLAGS_REG)"
18947   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18948               (clobber (reg:CC FLAGS_REG))])])
18949
18950 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18951 (define_peephole2
18952   [(set (match_operand 0 "register_operand" "")
18953         (const_int -1))]
18954   "(GET_MODE (operands[0]) == HImode
18955     || GET_MODE (operands[0]) == SImode 
18956     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18957    && (optimize_size || TARGET_PENTIUM)
18958    && peep2_regno_dead_p (0, FLAGS_REG)"
18959   [(parallel [(set (match_dup 0) (const_int -1))
18960               (clobber (reg:CC FLAGS_REG))])]
18961   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18962                               operands[0]);")
18963
18964 ;; Attempt to convert simple leas to adds. These can be created by
18965 ;; move expanders.
18966 (define_peephole2
18967   [(set (match_operand:SI 0 "register_operand" "")
18968         (plus:SI (match_dup 0)
18969                  (match_operand:SI 1 "nonmemory_operand" "")))]
18970   "peep2_regno_dead_p (0, FLAGS_REG)"
18971   [(parallel [(set (match_dup 0) (plus:SI (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         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18978                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18979   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18980   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18981               (clobber (reg:CC FLAGS_REG))])]
18982   "operands[2] = gen_lowpart (SImode, operands[2]);")
18983
18984 (define_peephole2
18985   [(set (match_operand:DI 0 "register_operand" "")
18986         (plus:DI (match_dup 0)
18987                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18988   "peep2_regno_dead_p (0, FLAGS_REG)"
18989   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18990               (clobber (reg:CC FLAGS_REG))])]
18991   "")
18992
18993 (define_peephole2
18994   [(set (match_operand:SI 0 "register_operand" "")
18995         (mult:SI (match_dup 0)
18996                  (match_operand:SI 1 "const_int_operand" "")))]
18997   "exact_log2 (INTVAL (operands[1])) >= 0
18998    && peep2_regno_dead_p (0, FLAGS_REG)"
18999   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19000               (clobber (reg:CC FLAGS_REG))])]
19001   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19002
19003 (define_peephole2
19004   [(set (match_operand:DI 0 "register_operand" "")
19005         (mult:DI (match_dup 0)
19006                  (match_operand:DI 1 "const_int_operand" "")))]
19007   "exact_log2 (INTVAL (operands[1])) >= 0
19008    && peep2_regno_dead_p (0, FLAGS_REG)"
19009   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19010               (clobber (reg:CC FLAGS_REG))])]
19011   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19012
19013 (define_peephole2
19014   [(set (match_operand:SI 0 "register_operand" "")
19015         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19016                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19017   "exact_log2 (INTVAL (operands[2])) >= 0
19018    && REGNO (operands[0]) == REGNO (operands[1])
19019    && peep2_regno_dead_p (0, FLAGS_REG)"
19020   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19021               (clobber (reg:CC FLAGS_REG))])]
19022   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19023
19024 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19025 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19026 ;; many CPUs it is also faster, since special hardware to avoid esp
19027 ;; dependencies is present.
19028
19029 ;; While some of these conversions may be done using splitters, we use peepholes
19030 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19031
19032 ;; Convert prologue esp subtractions to push.
19033 ;; We need register to push.  In order to keep verify_flow_info happy we have
19034 ;; two choices
19035 ;; - use scratch and clobber it in order to avoid dependencies
19036 ;; - use already live register
19037 ;; We can't use the second way right now, since there is no reliable way how to
19038 ;; verify that given register is live.  First choice will also most likely in
19039 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19040 ;; call clobbered registers are dead.  We may want to use base pointer as an
19041 ;; alternative when no register is available later.
19042
19043 (define_peephole2
19044   [(match_scratch:SI 0 "r")
19045    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19046               (clobber (reg:CC FLAGS_REG))
19047               (clobber (mem:BLK (scratch)))])]
19048   "optimize_size || !TARGET_SUB_ESP_4"
19049   [(clobber (match_dup 0))
19050    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19051               (clobber (mem:BLK (scratch)))])])
19052
19053 (define_peephole2
19054   [(match_scratch:SI 0 "r")
19055    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19056               (clobber (reg:CC FLAGS_REG))
19057               (clobber (mem:BLK (scratch)))])]
19058   "optimize_size || !TARGET_SUB_ESP_8"
19059   [(clobber (match_dup 0))
19060    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19061    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19062               (clobber (mem:BLK (scratch)))])])
19063
19064 ;; Convert esp subtractions to push.
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   "optimize_size || !TARGET_SUB_ESP_4"
19070   [(clobber (match_dup 0))
19071    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19072
19073 (define_peephole2
19074   [(match_scratch:SI 0 "r")
19075    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19076               (clobber (reg:CC FLAGS_REG))])]
19077   "optimize_size || !TARGET_SUB_ESP_8"
19078   [(clobber (match_dup 0))
19079    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19080    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19081
19082 ;; Convert epilogue deallocator to pop.
19083 (define_peephole2
19084   [(match_scratch:SI 0 "r")
19085    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19086               (clobber (reg:CC FLAGS_REG))
19087               (clobber (mem:BLK (scratch)))])]
19088   "optimize_size || !TARGET_ADD_ESP_4"
19089   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19090               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19091               (clobber (mem:BLK (scratch)))])]
19092   "")
19093
19094 ;; Two pops case is tricky, since pop causes dependency on destination register.
19095 ;; We use two registers if available.
19096 (define_peephole2
19097   [(match_scratch:SI 0 "r")
19098    (match_scratch:SI 1 "r")
19099    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19100               (clobber (reg:CC FLAGS_REG))
19101               (clobber (mem:BLK (scratch)))])]
19102   "optimize_size || !TARGET_ADD_ESP_8"
19103   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19104               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19105               (clobber (mem:BLK (scratch)))])
19106    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19107               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19108   "")
19109
19110 (define_peephole2
19111   [(match_scratch:SI 0 "r")
19112    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19113               (clobber (reg:CC FLAGS_REG))
19114               (clobber (mem:BLK (scratch)))])]
19115   "optimize_size"
19116   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19117               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19118               (clobber (mem:BLK (scratch)))])
19119    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19120               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19121   "")
19122
19123 ;; Convert esp additions to pop.
19124 (define_peephole2
19125   [(match_scratch:SI 0 "r")
19126    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19127               (clobber (reg:CC FLAGS_REG))])]
19128   ""
19129   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19130               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19131   "")
19132
19133 ;; Two pops case is tricky, since pop causes dependency on destination register.
19134 ;; We use two registers if available.
19135 (define_peephole2
19136   [(match_scratch:SI 0 "r")
19137    (match_scratch:SI 1 "r")
19138    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19139               (clobber (reg:CC FLAGS_REG))])]
19140   ""
19141   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19142               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19143    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19144               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19145   "")
19146
19147 (define_peephole2
19148   [(match_scratch:SI 0 "r")
19149    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19150               (clobber (reg:CC FLAGS_REG))])]
19151   "optimize_size"
19152   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19153               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19154    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19155               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19156   "")
19157 \f
19158 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19159 ;; required and register dies.
19160 (define_peephole2
19161   [(set (reg 17)
19162         (compare (match_operand:SI 0 "register_operand" "")
19163                  (match_operand:SI 1 "incdec_operand" "")))]
19164   "ix86_match_ccmode (insn, CCGCmode)
19165    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19166   [(parallel [(set (reg:CCGC FLAGS_REG)
19167                    (compare:CCGC (match_dup 0)
19168                                  (match_dup 1)))
19169               (clobber (match_dup 0))])]
19170   "")
19171
19172 (define_peephole2
19173   [(set (reg 17)
19174         (compare (match_operand:HI 0 "register_operand" "")
19175                  (match_operand:HI 1 "incdec_operand" "")))]
19176   "ix86_match_ccmode (insn, CCGCmode)
19177    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19178   [(parallel [(set (reg:CCGC FLAGS_REG)
19179                    (compare:CCGC (match_dup 0)
19180                                  (match_dup 1)))
19181               (clobber (match_dup 0))])]
19182   "")
19183
19184 (define_peephole2
19185   [(set (reg 17)
19186         (compare (match_operand:QI 0 "register_operand" "")
19187                  (match_operand:QI 1 "incdec_operand" "")))]
19188   "ix86_match_ccmode (insn, CCGCmode)
19189    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19190   [(parallel [(set (reg:CCGC FLAGS_REG)
19191                    (compare:CCGC (match_dup 0)
19192                                  (match_dup 1)))
19193               (clobber (match_dup 0))])]
19194   "")
19195
19196 ;; Convert compares with 128 to shorter add -128
19197 (define_peephole2
19198   [(set (reg 17)
19199         (compare (match_operand:SI 0 "register_operand" "")
19200                  (const_int 128)))]
19201   "ix86_match_ccmode (insn, CCGCmode)
19202    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19203   [(parallel [(set (reg:CCGC FLAGS_REG)
19204                    (compare:CCGC (match_dup 0)
19205                                  (const_int 128)))
19206               (clobber (match_dup 0))])]
19207   "")
19208
19209 (define_peephole2
19210   [(set (reg 17)
19211         (compare (match_operand:HI 0 "register_operand" "")
19212                  (const_int 128)))]
19213   "ix86_match_ccmode (insn, CCGCmode)
19214    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19215   [(parallel [(set (reg:CCGC FLAGS_REG)
19216                    (compare:CCGC (match_dup 0)
19217                                  (const_int 128)))
19218               (clobber (match_dup 0))])]
19219   "")
19220 \f
19221 (define_peephole2
19222   [(match_scratch:DI 0 "r")
19223    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19224               (clobber (reg:CC FLAGS_REG))
19225               (clobber (mem:BLK (scratch)))])]
19226   "optimize_size || !TARGET_SUB_ESP_4"
19227   [(clobber (match_dup 0))
19228    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19229               (clobber (mem:BLK (scratch)))])])
19230
19231 (define_peephole2
19232   [(match_scratch:DI 0 "r")
19233    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19234               (clobber (reg:CC FLAGS_REG))
19235               (clobber (mem:BLK (scratch)))])]
19236   "optimize_size || !TARGET_SUB_ESP_8"
19237   [(clobber (match_dup 0))
19238    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19239    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19240               (clobber (mem:BLK (scratch)))])])
19241
19242 ;; Convert esp subtractions to push.
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   "optimize_size || !TARGET_SUB_ESP_4"
19248   [(clobber (match_dup 0))
19249    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19250
19251 (define_peephole2
19252   [(match_scratch:DI 0 "r")
19253    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19254               (clobber (reg:CC FLAGS_REG))])]
19255   "optimize_size || !TARGET_SUB_ESP_8"
19256   [(clobber (match_dup 0))
19257    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19258    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19259
19260 ;; Convert epilogue deallocator to pop.
19261 (define_peephole2
19262   [(match_scratch:DI 0 "r")
19263    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19264               (clobber (reg:CC FLAGS_REG))
19265               (clobber (mem:BLK (scratch)))])]
19266   "optimize_size || !TARGET_ADD_ESP_4"
19267   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19268               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19269               (clobber (mem:BLK (scratch)))])]
19270   "")
19271
19272 ;; Two pops case is tricky, since pop causes dependency on destination register.
19273 ;; We use two registers if available.
19274 (define_peephole2
19275   [(match_scratch:DI 0 "r")
19276    (match_scratch:DI 1 "r")
19277    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19278               (clobber (reg:CC FLAGS_REG))
19279               (clobber (mem:BLK (scratch)))])]
19280   "optimize_size || !TARGET_ADD_ESP_8"
19281   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19282               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19283               (clobber (mem:BLK (scratch)))])
19284    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19285               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19286   "")
19287
19288 (define_peephole2
19289   [(match_scratch:DI 0 "r")
19290    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19291               (clobber (reg:CC FLAGS_REG))
19292               (clobber (mem:BLK (scratch)))])]
19293   "optimize_size"
19294   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19295               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19296               (clobber (mem:BLK (scratch)))])
19297    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19298               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19299   "")
19300
19301 ;; Convert esp additions to pop.
19302 (define_peephole2
19303   [(match_scratch:DI 0 "r")
19304    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19305               (clobber (reg:CC FLAGS_REG))])]
19306   ""
19307   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19308               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19309   "")
19310
19311 ;; Two pops case is tricky, since pop causes dependency on destination register.
19312 ;; We use two registers if available.
19313 (define_peephole2
19314   [(match_scratch:DI 0 "r")
19315    (match_scratch:DI 1 "r")
19316    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19317               (clobber (reg:CC FLAGS_REG))])]
19318   ""
19319   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19320               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19321    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19322               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19323   "")
19324
19325 (define_peephole2
19326   [(match_scratch:DI 0 "r")
19327    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19328               (clobber (reg:CC FLAGS_REG))])]
19329   "optimize_size"
19330   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19331               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19332    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19333               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19334   "")
19335 \f
19336 ;; Convert imul by three, five and nine into lea
19337 (define_peephole2
19338   [(parallel
19339     [(set (match_operand:SI 0 "register_operand" "")
19340           (mult:SI (match_operand:SI 1 "register_operand" "")
19341                    (match_operand:SI 2 "const_int_operand" "")))
19342      (clobber (reg:CC FLAGS_REG))])]
19343   "INTVAL (operands[2]) == 3
19344    || INTVAL (operands[2]) == 5
19345    || INTVAL (operands[2]) == 9"
19346   [(set (match_dup 0)
19347         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19348                  (match_dup 1)))]
19349   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19350
19351 (define_peephole2
19352   [(parallel
19353     [(set (match_operand:SI 0 "register_operand" "")
19354           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19355                    (match_operand:SI 2 "const_int_operand" "")))
19356      (clobber (reg:CC FLAGS_REG))])]
19357   "!optimize_size 
19358    && (INTVAL (operands[2]) == 3
19359        || INTVAL (operands[2]) == 5
19360        || INTVAL (operands[2]) == 9)"
19361   [(set (match_dup 0) (match_dup 1))
19362    (set (match_dup 0)
19363         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19364                  (match_dup 0)))]
19365   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19366
19367 (define_peephole2
19368   [(parallel
19369     [(set (match_operand:DI 0 "register_operand" "")
19370           (mult:DI (match_operand:DI 1 "register_operand" "")
19371                    (match_operand:DI 2 "const_int_operand" "")))
19372      (clobber (reg:CC FLAGS_REG))])]
19373   "TARGET_64BIT
19374    && (INTVAL (operands[2]) == 3
19375        || INTVAL (operands[2]) == 5
19376        || INTVAL (operands[2]) == 9)"
19377   [(set (match_dup 0)
19378         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19379                  (match_dup 1)))]
19380   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19381
19382 (define_peephole2
19383   [(parallel
19384     [(set (match_operand:DI 0 "register_operand" "")
19385           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19386                    (match_operand:DI 2 "const_int_operand" "")))
19387      (clobber (reg:CC FLAGS_REG))])]
19388   "TARGET_64BIT
19389    && !optimize_size 
19390    && (INTVAL (operands[2]) == 3
19391        || INTVAL (operands[2]) == 5
19392        || INTVAL (operands[2]) == 9)"
19393   [(set (match_dup 0) (match_dup 1))
19394    (set (match_dup 0)
19395         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19396                  (match_dup 0)))]
19397   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19398
19399 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19400 ;; imul $32bit_imm, reg, reg is direct decoded.
19401 (define_peephole2
19402   [(match_scratch:DI 3 "r")
19403    (parallel [(set (match_operand:DI 0 "register_operand" "")
19404                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19405                             (match_operand:DI 2 "immediate_operand" "")))
19406               (clobber (reg:CC FLAGS_REG))])]
19407   "TARGET_K8 && !optimize_size
19408    && (GET_CODE (operands[2]) != CONST_INT
19409        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19410   [(set (match_dup 3) (match_dup 1))
19411    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19412               (clobber (reg:CC FLAGS_REG))])]
19413 "")
19414
19415 (define_peephole2
19416   [(match_scratch:SI 3 "r")
19417    (parallel [(set (match_operand:SI 0 "register_operand" "")
19418                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19419                             (match_operand:SI 2 "immediate_operand" "")))
19420               (clobber (reg:CC FLAGS_REG))])]
19421   "TARGET_K8 && !optimize_size
19422    && (GET_CODE (operands[2]) != CONST_INT
19423        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19424   [(set (match_dup 3) (match_dup 1))
19425    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19426               (clobber (reg:CC FLAGS_REG))])]
19427 "")
19428
19429 (define_peephole2
19430   [(match_scratch:SI 3 "r")
19431    (parallel [(set (match_operand:DI 0 "register_operand" "")
19432                    (zero_extend:DI
19433                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19434                               (match_operand:SI 2 "immediate_operand" ""))))
19435               (clobber (reg:CC FLAGS_REG))])]
19436   "TARGET_K8 && !optimize_size
19437    && (GET_CODE (operands[2]) != CONST_INT
19438        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19439   [(set (match_dup 3) (match_dup 1))
19440    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19441               (clobber (reg:CC FLAGS_REG))])]
19442 "")
19443
19444 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19445 ;; Convert it into imul reg, reg
19446 ;; It would be better to force assembler to encode instruction using long
19447 ;; immediate, but there is apparently no way to do so.
19448 (define_peephole2
19449   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19450                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19451                             (match_operand:DI 2 "const_int_operand" "")))
19452               (clobber (reg:CC FLAGS_REG))])
19453    (match_scratch:DI 3 "r")]
19454   "TARGET_K8 && !optimize_size
19455    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19456   [(set (match_dup 3) (match_dup 2))
19457    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19458               (clobber (reg:CC FLAGS_REG))])]
19459 {
19460   if (!rtx_equal_p (operands[0], operands[1]))
19461     emit_move_insn (operands[0], operands[1]);
19462 })
19463
19464 (define_peephole2
19465   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19466                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19467                             (match_operand:SI 2 "const_int_operand" "")))
19468               (clobber (reg:CC FLAGS_REG))])
19469    (match_scratch:SI 3 "r")]
19470   "TARGET_K8 && !optimize_size
19471    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19472   [(set (match_dup 3) (match_dup 2))
19473    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19474               (clobber (reg:CC FLAGS_REG))])]
19475 {
19476   if (!rtx_equal_p (operands[0], operands[1]))
19477     emit_move_insn (operands[0], operands[1]);
19478 })
19479
19480 (define_peephole2
19481   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19482                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19483                             (match_operand:HI 2 "immediate_operand" "")))
19484               (clobber (reg:CC FLAGS_REG))])
19485    (match_scratch:HI 3 "r")]
19486   "TARGET_K8 && !optimize_size"
19487   [(set (match_dup 3) (match_dup 2))
19488    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19489               (clobber (reg:CC FLAGS_REG))])]
19490 {
19491   if (!rtx_equal_p (operands[0], operands[1]))
19492     emit_move_insn (operands[0], operands[1]);
19493 })
19494 \f
19495 ;; Call-value patterns last so that the wildcard operand does not
19496 ;; disrupt insn-recog's switch tables.
19497
19498 (define_insn "*call_value_pop_0"
19499   [(set (match_operand 0 "" "")
19500         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19501               (match_operand:SI 2 "" "")))
19502    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19503                             (match_operand:SI 3 "immediate_operand" "")))]
19504   "!TARGET_64BIT"
19505 {
19506   if (SIBLING_CALL_P (insn))
19507     return "jmp\t%P1";
19508   else
19509     return "call\t%P1";
19510 }
19511   [(set_attr "type" "callv")])
19512
19513 (define_insn "*call_value_pop_1"
19514   [(set (match_operand 0 "" "")
19515         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19516               (match_operand:SI 2 "" "")))
19517    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19518                             (match_operand:SI 3 "immediate_operand" "i")))]
19519   "!TARGET_64BIT"
19520 {
19521   if (constant_call_address_operand (operands[1], QImode))
19522     {
19523       if (SIBLING_CALL_P (insn))
19524         return "jmp\t%P1";
19525       else
19526         return "call\t%P1";
19527     }
19528   if (SIBLING_CALL_P (insn))
19529     return "jmp\t%A1";
19530   else
19531     return "call\t%A1";
19532 }
19533   [(set_attr "type" "callv")])
19534
19535 (define_insn "*call_value_0"
19536   [(set (match_operand 0 "" "")
19537         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19538               (match_operand:SI 2 "" "")))]
19539   "!TARGET_64BIT"
19540 {
19541   if (SIBLING_CALL_P (insn))
19542     return "jmp\t%P1";
19543   else
19544     return "call\t%P1";
19545 }
19546   [(set_attr "type" "callv")])
19547
19548 (define_insn "*call_value_0_rex64"
19549   [(set (match_operand 0 "" "")
19550         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19551               (match_operand:DI 2 "const_int_operand" "")))]
19552   "TARGET_64BIT"
19553 {
19554   if (SIBLING_CALL_P (insn))
19555     return "jmp\t%P1";
19556   else
19557     return "call\t%P1";
19558 }
19559   [(set_attr "type" "callv")])
19560
19561 (define_insn "*call_value_1"
19562   [(set (match_operand 0 "" "")
19563         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19564               (match_operand:SI 2 "" "")))]
19565   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19566 {
19567   if (constant_call_address_operand (operands[1], QImode))
19568     return "call\t%P1";
19569   return "call\t%*%1";
19570 }
19571   [(set_attr "type" "callv")])
19572
19573 (define_insn "*sibcall_value_1"
19574   [(set (match_operand 0 "" "")
19575         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19576               (match_operand:SI 2 "" "")))]
19577   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19578 {
19579   if (constant_call_address_operand (operands[1], QImode))
19580     return "jmp\t%P1";
19581   return "jmp\t%*%1";
19582 }
19583   [(set_attr "type" "callv")])
19584
19585 (define_insn "*call_value_1_rex64"
19586   [(set (match_operand 0 "" "")
19587         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19588               (match_operand:DI 2 "" "")))]
19589   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19590 {
19591   if (constant_call_address_operand (operands[1], QImode))
19592     return "call\t%P1";
19593   return "call\t%A1";
19594 }
19595   [(set_attr "type" "callv")])
19596
19597 (define_insn "*sibcall_value_1_rex64"
19598   [(set (match_operand 0 "" "")
19599         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19600               (match_operand:DI 2 "" "")))]
19601   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19602   "jmp\t%P1"
19603   [(set_attr "type" "callv")])
19604
19605 (define_insn "*sibcall_value_1_rex64_v"
19606   [(set (match_operand 0 "" "")
19607         (call (mem:QI (reg:DI 40))
19608               (match_operand:DI 1 "" "")))]
19609   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19610   "jmp\t*%%r11"
19611   [(set_attr "type" "callv")])
19612 \f
19613 (define_insn "trap"
19614   [(trap_if (const_int 1) (const_int 5))]
19615   ""
19616   "int\t$5")
19617
19618 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19619 ;;; for the sake of bounds checking.  By emitting bounds checks as
19620 ;;; conditional traps rather than as conditional jumps around
19621 ;;; unconditional traps we avoid introducing spurious basic-block
19622 ;;; boundaries and facilitate elimination of redundant checks.  In
19623 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19624 ;;; interrupt 5.
19625 ;;; 
19626 ;;; FIXME: Static branch prediction rules for ix86 are such that
19627 ;;; forward conditional branches predict as untaken.  As implemented
19628 ;;; below, pseudo conditional traps violate that rule.  We should use
19629 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19630 ;;; section loaded at the end of the text segment and branch forward
19631 ;;; there on bounds-failure, and then jump back immediately (in case
19632 ;;; the system chooses to ignore bounds violations, or to report
19633 ;;; violations and continue execution).
19634
19635 (define_expand "conditional_trap"
19636   [(trap_if (match_operator 0 "comparison_operator"
19637              [(match_dup 2) (const_int 0)])
19638             (match_operand 1 "const_int_operand" ""))]
19639   ""
19640 {
19641   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19642                               ix86_expand_compare (GET_CODE (operands[0]),
19643                                                    NULL, NULL),
19644                               operands[1]));
19645   DONE;
19646 })
19647
19648 (define_insn "*conditional_trap_1"
19649   [(trap_if (match_operator 0 "comparison_operator"
19650              [(reg 17) (const_int 0)])
19651             (match_operand 1 "const_int_operand" ""))]
19652   ""
19653 {
19654   operands[2] = gen_label_rtx ();
19655   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19656   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19657                              CODE_LABEL_NUMBER (operands[2]));
19658   RET;
19659 })
19660
19661         ;; Pentium III SIMD instructions.
19662
19663 ;; Moves for SSE/MMX regs.
19664
19665 (define_insn "movv4sf_internal"
19666   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19667         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19668   "TARGET_SSE"
19669   "@
19670     xorps\t%0, %0
19671     movaps\t{%1, %0|%0, %1}
19672     movaps\t{%1, %0|%0, %1}"
19673   [(set_attr "type" "ssemov")
19674    (set_attr "mode" "V4SF")])
19675
19676 (define_split
19677   [(set (match_operand:V4SF 0 "register_operand" "")
19678         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19679   "TARGET_SSE"
19680   [(set (match_dup 0)
19681         (vec_merge:V4SF
19682          (vec_duplicate:V4SF (match_dup 1))
19683          (match_dup 2)
19684          (const_int 1)))]
19685 {
19686   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19687   operands[2] = CONST0_RTX (V4SFmode);
19688 })
19689
19690 (define_insn "movv4si_internal"
19691   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19692         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19693   "TARGET_SSE"
19694 {
19695   switch (which_alternative)
19696     {
19697     case 0:
19698       if (get_attr_mode (insn) == MODE_V4SF)
19699         return "xorps\t%0, %0";
19700       else
19701         return "pxor\t%0, %0";
19702     case 1:
19703     case 2:
19704       if (get_attr_mode (insn) == MODE_V4SF)
19705         return "movaps\t{%1, %0|%0, %1}";
19706       else
19707         return "movdqa\t{%1, %0|%0, %1}";
19708     default:
19709       abort ();
19710     }
19711 }
19712   [(set_attr "type" "ssemov")
19713    (set (attr "mode")
19714         (cond [(eq_attr "alternative" "0,1")
19715                  (if_then_else
19716                    (ne (symbol_ref "optimize_size")
19717                        (const_int 0))
19718                    (const_string "V4SF")
19719                    (const_string "TI"))
19720                (eq_attr "alternative" "2")
19721                  (if_then_else
19722                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19723                             (const_int 0))
19724                         (ne (symbol_ref "optimize_size")
19725                             (const_int 0)))
19726                    (const_string "V4SF")
19727                    (const_string "TI"))]
19728                (const_string "TI")))])
19729
19730 (define_insn "movv2di_internal"
19731   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19732         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19733   "TARGET_SSE"
19734 {
19735   switch (which_alternative)
19736     {
19737     case 0:
19738       if (get_attr_mode (insn) == MODE_V4SF)
19739         return "xorps\t%0, %0";
19740       else
19741         return "pxor\t%0, %0";
19742     case 1:
19743     case 2:
19744       if (get_attr_mode (insn) == MODE_V4SF)
19745         return "movaps\t{%1, %0|%0, %1}";
19746       else
19747         return "movdqa\t{%1, %0|%0, %1}";
19748     default:
19749       abort ();
19750     }
19751 }
19752   [(set_attr "type" "ssemov")
19753    (set (attr "mode")
19754         (cond [(eq_attr "alternative" "0,1")
19755                  (if_then_else
19756                    (ne (symbol_ref "optimize_size")
19757                        (const_int 0))
19758                    (const_string "V4SF")
19759                    (const_string "TI"))
19760                (eq_attr "alternative" "2")
19761                  (if_then_else
19762                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19763                             (const_int 0))
19764                         (ne (symbol_ref "optimize_size")
19765                             (const_int 0)))
19766                    (const_string "V4SF")
19767                    (const_string "TI"))]
19768                (const_string "TI")))])
19769
19770 (define_split
19771   [(set (match_operand:V2DF 0 "register_operand" "")
19772         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19773   "TARGET_SSE2"
19774   [(set (match_dup 0)
19775         (vec_merge:V2DF
19776          (vec_duplicate:V2DF (match_dup 1))
19777          (match_dup 2)
19778          (const_int 1)))]
19779 {
19780   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19781   operands[2] = CONST0_RTX (V2DFmode);
19782 })
19783
19784 (define_insn "movv8qi_internal"
19785   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19786         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19787   "TARGET_MMX
19788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19789   "@
19790     pxor\t%0, %0
19791     movq\t{%1, %0|%0, %1}
19792     movq\t{%1, %0|%0, %1}
19793     movdq2q\t{%1, %0|%0, %1}
19794     movq2dq\t{%1, %0|%0, %1}
19795     movq\t{%1, %0|%0, %1}
19796     movq\t{%1, %0|%0, %1}"
19797   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19798    (set_attr "mode" "DI")])
19799
19800 (define_insn "movv4hi_internal"
19801   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19802         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19803   "TARGET_MMX
19804    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19805   "@
19806     pxor\t%0, %0
19807     movq\t{%1, %0|%0, %1}
19808     movq\t{%1, %0|%0, %1}
19809     movdq2q\t{%1, %0|%0, %1}
19810     movq2dq\t{%1, %0|%0, %1}
19811     movq\t{%1, %0|%0, %1}
19812     movq\t{%1, %0|%0, %1}"
19813   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19814    (set_attr "mode" "DI")])
19815
19816 (define_insn "*movv2si_internal"
19817   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19818         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19819   "TARGET_MMX
19820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19821   "@
19822     pxor\t%0, %0
19823     movq\t{%1, %0|%0, %1}
19824     movq\t{%1, %0|%0, %1}
19825     movdq2q\t{%1, %0|%0, %1}
19826     movq2dq\t{%1, %0|%0, %1}
19827     movq\t{%1, %0|%0, %1}
19828     movq\t{%1, %0|%0, %1}"
19829   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19830    (set_attr "mode" "DI")])
19831
19832 (define_insn "movv2sf_internal"
19833   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19834         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
19835   "TARGET_3DNOW
19836    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19837   "@
19838     pxor\t%0, %0
19839     movq\t{%1, %0|%0, %1}
19840     movq\t{%1, %0|%0, %1}
19841     movdq2q\t{%1, %0|%0, %1}
19842     movq2dq\t{%1, %0|%0, %1}
19843     movlps\t{%1, %0|%0, %1}
19844     movlps\t{%1, %0|%0, %1}"
19845   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19846    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
19847
19848 (define_expand "movti"
19849   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19850         (match_operand:TI 1 "nonimmediate_operand" ""))]
19851   "TARGET_SSE || TARGET_64BIT"
19852 {
19853   if (TARGET_64BIT)
19854     ix86_expand_move (TImode, operands);
19855   else
19856     ix86_expand_vector_move (TImode, operands);
19857   DONE;
19858 })
19859
19860 (define_expand "movtf"
19861   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19862         (match_operand:TF 1 "nonimmediate_operand" ""))]
19863   "TARGET_64BIT"
19864 {
19865   if (TARGET_64BIT)
19866     ix86_expand_move (TFmode, operands);
19867   else
19868     ix86_expand_vector_move (TFmode, operands);
19869   DONE;
19870 })
19871
19872 (define_insn "movv2df_internal"
19873   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19874         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19875   "TARGET_SSE2
19876    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19877 {
19878   switch (which_alternative)
19879     {
19880     case 0:
19881       if (get_attr_mode (insn) == MODE_V4SF)
19882         return "xorps\t%0, %0";
19883       else
19884         return "xorpd\t%0, %0";
19885     case 1:
19886     case 2:
19887       if (get_attr_mode (insn) == MODE_V4SF)
19888         return "movaps\t{%1, %0|%0, %1}";
19889       else
19890         return "movapd\t{%1, %0|%0, %1}";
19891     default:
19892       abort ();
19893     }
19894 }
19895   [(set_attr "type" "ssemov")
19896    (set (attr "mode")
19897         (cond [(eq_attr "alternative" "0,1")
19898                  (if_then_else
19899                    (ne (symbol_ref "optimize_size")
19900                        (const_int 0))
19901                    (const_string "V4SF")
19902                    (const_string "V2DF"))
19903                (eq_attr "alternative" "2")
19904                  (if_then_else
19905                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19906                             (const_int 0))
19907                         (ne (symbol_ref "optimize_size")
19908                             (const_int 0)))
19909                    (const_string "V4SF")
19910                    (const_string "V2DF"))]
19911                (const_string "V2DF")))])
19912
19913 (define_insn "movv8hi_internal"
19914   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19915         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19916   "TARGET_SSE2
19917    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19918 {
19919   switch (which_alternative)
19920     {
19921     case 0:
19922       if (get_attr_mode (insn) == MODE_V4SF)
19923         return "xorps\t%0, %0";
19924       else
19925         return "pxor\t%0, %0";
19926     case 1:
19927     case 2:
19928       if (get_attr_mode (insn) == MODE_V4SF)
19929         return "movaps\t{%1, %0|%0, %1}";
19930       else
19931         return "movdqa\t{%1, %0|%0, %1}";
19932     default:
19933       abort ();
19934     }
19935 }
19936   [(set_attr "type" "ssemov")
19937    (set (attr "mode")
19938         (cond [(eq_attr "alternative" "0,1")
19939                  (if_then_else
19940                    (ne (symbol_ref "optimize_size")
19941                        (const_int 0))
19942                    (const_string "V4SF")
19943                    (const_string "TI"))
19944                (eq_attr "alternative" "2")
19945                  (if_then_else
19946                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19947                             (const_int 0))
19948                         (ne (symbol_ref "optimize_size")
19949                             (const_int 0)))
19950                    (const_string "V4SF")
19951                    (const_string "TI"))]
19952                (const_string "TI")))])
19953
19954 (define_insn "movv16qi_internal"
19955   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19956         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
19957   "TARGET_SSE2
19958    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19959 {
19960   switch (which_alternative)
19961     {
19962     case 0:
19963       if (get_attr_mode (insn) == MODE_V4SF)
19964         return "xorps\t%0, %0";
19965       else
19966         return "pxor\t%0, %0";
19967     case 1:
19968     case 2:
19969       if (get_attr_mode (insn) == MODE_V4SF)
19970         return "movaps\t{%1, %0|%0, %1}";
19971       else
19972         return "movdqa\t{%1, %0|%0, %1}";
19973     default:
19974       abort ();
19975     }
19976 }
19977   [(set_attr "type" "ssemov")
19978    (set (attr "mode")
19979         (cond [(eq_attr "alternative" "0,1")
19980                  (if_then_else
19981                    (ne (symbol_ref "optimize_size")
19982                        (const_int 0))
19983                    (const_string "V4SF")
19984                    (const_string "TI"))
19985                (eq_attr "alternative" "2")
19986                  (if_then_else
19987                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19988                             (const_int 0))
19989                         (ne (symbol_ref "optimize_size")
19990                             (const_int 0)))
19991                    (const_string "V4SF")
19992                    (const_string "TI"))]
19993                (const_string "TI")))])
19994
19995 (define_expand "movv2df"
19996   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19997         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19998   "TARGET_SSE2"
19999 {
20000   ix86_expand_vector_move (V2DFmode, operands);
20001   DONE;
20002 })
20003
20004 (define_expand "movv8hi"
20005   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20006         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20007   "TARGET_SSE2"
20008 {
20009   ix86_expand_vector_move (V8HImode, operands);
20010   DONE;
20011 })
20012
20013 (define_expand "movv16qi"
20014   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20015         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20016   "TARGET_SSE2"
20017 {
20018   ix86_expand_vector_move (V16QImode, operands);
20019   DONE;
20020 })
20021
20022 (define_expand "movv4sf"
20023   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20024         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20025   "TARGET_SSE"
20026 {
20027   ix86_expand_vector_move (V4SFmode, operands);
20028   DONE;
20029 })
20030
20031 (define_expand "movv4si"
20032   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20033         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20034   "TARGET_SSE"
20035 {
20036   ix86_expand_vector_move (V4SImode, operands);
20037   DONE;
20038 })
20039
20040 (define_expand "movv2di"
20041   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20042         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20043   "TARGET_SSE"
20044 {
20045   ix86_expand_vector_move (V2DImode, operands);
20046   DONE;
20047 })
20048
20049 (define_expand "movv2si"
20050   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20051         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20052   "TARGET_MMX"
20053 {
20054   ix86_expand_vector_move (V2SImode, operands);
20055   DONE;
20056 })
20057
20058 (define_expand "movv4hi"
20059   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20060         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20061   "TARGET_MMX"
20062 {
20063   ix86_expand_vector_move (V4HImode, operands);
20064   DONE;
20065 })
20066
20067 (define_expand "movv8qi"
20068   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20069         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20070   "TARGET_MMX"
20071 {
20072   ix86_expand_vector_move (V8QImode, operands);
20073   DONE;
20074 })
20075
20076 (define_expand "movv2sf"
20077   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20078         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20079    "TARGET_3DNOW"
20080 {
20081   ix86_expand_vector_move (V2SFmode, operands);
20082   DONE;
20083 })
20084
20085 (define_insn "*pushti"
20086   [(set (match_operand:TI 0 "push_operand" "=<")
20087         (match_operand:TI 1 "register_operand" "x"))]
20088   "TARGET_SSE"
20089   "#")
20090
20091 (define_insn "*pushv2df"
20092   [(set (match_operand:V2DF 0 "push_operand" "=<")
20093         (match_operand:V2DF 1 "register_operand" "x"))]
20094   "TARGET_SSE"
20095   "#")
20096
20097 (define_insn "*pushv2di"
20098   [(set (match_operand:V2DI 0 "push_operand" "=<")
20099         (match_operand:V2DI 1 "register_operand" "x"))]
20100   "TARGET_SSE2"
20101   "#")
20102
20103 (define_insn "*pushv8hi"
20104   [(set (match_operand:V8HI 0 "push_operand" "=<")
20105         (match_operand:V8HI 1 "register_operand" "x"))]
20106   "TARGET_SSE2"
20107   "#")
20108
20109 (define_insn "*pushv16qi"
20110   [(set (match_operand:V16QI 0 "push_operand" "=<")
20111         (match_operand:V16QI 1 "register_operand" "x"))]
20112   "TARGET_SSE2"
20113   "#")
20114
20115 (define_insn "*pushv4sf"
20116   [(set (match_operand:V4SF 0 "push_operand" "=<")
20117         (match_operand:V4SF 1 "register_operand" "x"))]
20118   "TARGET_SSE"
20119   "#")
20120
20121 (define_insn "*pushv4si"
20122   [(set (match_operand:V4SI 0 "push_operand" "=<")
20123         (match_operand:V4SI 1 "register_operand" "x"))]
20124   "TARGET_SSE2"
20125   "#")
20126
20127 (define_insn "*pushv2si"
20128   [(set (match_operand:V2SI 0 "push_operand" "=<")
20129         (match_operand:V2SI 1 "register_operand" "y"))]
20130   "TARGET_MMX"
20131   "#")
20132
20133 (define_insn "*pushv4hi"
20134   [(set (match_operand:V4HI 0 "push_operand" "=<")
20135         (match_operand:V4HI 1 "register_operand" "y"))]
20136   "TARGET_MMX"
20137   "#")
20138
20139 (define_insn "*pushv8qi"
20140   [(set (match_operand:V8QI 0 "push_operand" "=<")
20141         (match_operand:V8QI 1 "register_operand" "y"))]
20142   "TARGET_MMX"
20143   "#")
20144
20145 (define_insn "*pushv2sf"
20146   [(set (match_operand:V2SF 0 "push_operand" "=<")
20147         (match_operand:V2SF 1 "register_operand" "y"))]
20148   "TARGET_3DNOW"
20149   "#")
20150
20151 (define_split
20152   [(set (match_operand 0 "push_operand" "")
20153         (match_operand 1 "register_operand" ""))]
20154   "!TARGET_64BIT && reload_completed
20155    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20156   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20157    (set (match_dup 2) (match_dup 1))]
20158   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20159                                  stack_pointer_rtx);
20160    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20161
20162 (define_split
20163   [(set (match_operand 0 "push_operand" "")
20164         (match_operand 1 "register_operand" ""))]
20165   "TARGET_64BIT && reload_completed
20166    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20167   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20168    (set (match_dup 2) (match_dup 1))]
20169   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20170                                  stack_pointer_rtx);
20171    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20172
20173
20174 (define_insn "movti_internal"
20175   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20176         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20177   "TARGET_SSE && !TARGET_64BIT
20178    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20179 {
20180   switch (which_alternative)
20181     {
20182     case 0:
20183       if (get_attr_mode (insn) == MODE_V4SF)
20184         return "xorps\t%0, %0";
20185       else
20186         return "pxor\t%0, %0";
20187     case 1:
20188     case 2:
20189       if (get_attr_mode (insn) == MODE_V4SF)
20190         return "movaps\t{%1, %0|%0, %1}";
20191       else
20192         return "movdqa\t{%1, %0|%0, %1}";
20193     default:
20194       abort ();
20195     }
20196 }
20197   [(set_attr "type" "ssemov,ssemov,ssemov")
20198    (set (attr "mode")
20199         (cond [(eq_attr "alternative" "0,1")
20200                  (if_then_else
20201                    (ne (symbol_ref "optimize_size")
20202                        (const_int 0))
20203                    (const_string "V4SF")
20204                    (const_string "TI"))
20205                (eq_attr "alternative" "2")
20206                  (if_then_else
20207                    (ne (symbol_ref "optimize_size")
20208                        (const_int 0))
20209                    (const_string "V4SF")
20210                    (const_string "TI"))]
20211                (const_string "TI")))])
20212
20213 (define_insn "*movti_rex64"
20214   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20215         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20216   "TARGET_64BIT
20217    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20218 {
20219   switch (which_alternative)
20220     {
20221     case 0:
20222     case 1:
20223       return "#";
20224     case 2:
20225       if (get_attr_mode (insn) == MODE_V4SF)
20226         return "xorps\t%0, %0";
20227       else
20228         return "pxor\t%0, %0";
20229     case 3:
20230     case 4:
20231       if (get_attr_mode (insn) == MODE_V4SF)
20232         return "movaps\t{%1, %0|%0, %1}";
20233       else
20234         return "movdqa\t{%1, %0|%0, %1}";
20235     default:
20236       abort ();
20237     }
20238 }
20239   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20240    (set (attr "mode")
20241         (cond [(eq_attr "alternative" "2,3")
20242                  (if_then_else
20243                    (ne (symbol_ref "optimize_size")
20244                        (const_int 0))
20245                    (const_string "V4SF")
20246                    (const_string "TI"))
20247                (eq_attr "alternative" "4")
20248                  (if_then_else
20249                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20250                             (const_int 0))
20251                         (ne (symbol_ref "optimize_size")
20252                             (const_int 0)))
20253                    (const_string "V4SF")
20254                    (const_string "TI"))]
20255                (const_string "DI")))])
20256
20257 (define_insn "*movtf_rex64"
20258   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20259         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20260   "TARGET_64BIT
20261    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20262 {
20263   switch (which_alternative)
20264     {
20265     case 0:
20266     case 1:
20267       return "#";
20268     case 2:
20269       if (get_attr_mode (insn) == MODE_V4SF)
20270         return "xorps\t%0, %0";
20271       else
20272         return "pxor\t%0, %0";
20273     case 3:
20274     case 4:
20275       if (get_attr_mode (insn) == MODE_V4SF)
20276         return "movaps\t{%1, %0|%0, %1}";
20277       else
20278         return "movdqa\t{%1, %0|%0, %1}";
20279     default:
20280       abort ();
20281     }
20282 }
20283   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20284    (set (attr "mode")
20285         (cond [(eq_attr "alternative" "2,3")
20286                  (if_then_else
20287                    (ne (symbol_ref "optimize_size")
20288                        (const_int 0))
20289                    (const_string "V4SF")
20290                    (const_string "TI"))
20291                (eq_attr "alternative" "4")
20292                  (if_then_else
20293                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20294                             (const_int 0))
20295                         (ne (symbol_ref "optimize_size")
20296                             (const_int 0)))
20297                    (const_string "V4SF")
20298                    (const_string "TI"))]
20299                (const_string "DI")))])
20300
20301 (define_split
20302   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20303         (match_operand:TI 1 "general_operand" ""))]
20304   "reload_completed && !SSE_REG_P (operands[0])
20305    && !SSE_REG_P (operands[1])"
20306   [(const_int 0)]
20307   "ix86_split_long_move (operands); DONE;")
20308
20309 (define_split
20310   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20311         (match_operand:TF 1 "general_operand" ""))]
20312   "reload_completed && !SSE_REG_P (operands[0])
20313    && !SSE_REG_P (operands[1])"
20314   [(const_int 0)]
20315   "ix86_split_long_move (operands); DONE;")
20316
20317 ;; These two patterns are useful for specifying exactly whether to use
20318 ;; movaps or movups
20319 (define_expand "sse_movaps"
20320   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20321         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20322                      UNSPEC_MOVA))]
20323   "TARGET_SSE"
20324 {
20325   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20326     {
20327       rtx tmp = gen_reg_rtx (V4SFmode);
20328       emit_insn (gen_sse_movaps (tmp, operands[1]));
20329       emit_move_insn (operands[0], tmp);
20330       DONE;
20331     }
20332 })
20333
20334 (define_insn "*sse_movaps_1"
20335   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20336         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20337                      UNSPEC_MOVA))]
20338   "TARGET_SSE
20339    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20340   "movaps\t{%1, %0|%0, %1}"
20341   [(set_attr "type" "ssemov,ssemov")
20342    (set_attr "mode" "V4SF")])
20343
20344 (define_expand "sse_movups"
20345   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20346         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20347                      UNSPEC_MOVU))]
20348   "TARGET_SSE"
20349 {
20350   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20351     {
20352       rtx tmp = gen_reg_rtx (V4SFmode);
20353       emit_insn (gen_sse_movups (tmp, operands[1]));
20354       emit_move_insn (operands[0], tmp);
20355       DONE;
20356     }
20357 })
20358
20359 (define_insn "*sse_movups_1"
20360   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20361         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20362                      UNSPEC_MOVU))]
20363   "TARGET_SSE
20364    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20365   "movups\t{%1, %0|%0, %1}"
20366   [(set_attr "type" "ssecvt,ssecvt")
20367    (set_attr "mode" "V4SF")])
20368
20369 ;; SSE Strange Moves.
20370
20371 (define_insn "sse_movmskps"
20372   [(set (match_operand:SI 0 "register_operand" "=r")
20373         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20374                    UNSPEC_MOVMSK))]
20375   "TARGET_SSE"
20376   "movmskps\t{%1, %0|%0, %1}"
20377   [(set_attr "type" "ssecvt")
20378    (set_attr "mode" "V4SF")])
20379
20380 (define_insn "mmx_pmovmskb"
20381   [(set (match_operand:SI 0 "register_operand" "=r")
20382         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20383                    UNSPEC_MOVMSK))]
20384   "TARGET_SSE || TARGET_3DNOW_A"
20385   "pmovmskb\t{%1, %0|%0, %1}"
20386   [(set_attr "type" "ssecvt")
20387    (set_attr "mode" "V4SF")])
20388
20389
20390 (define_insn "mmx_maskmovq"
20391   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20392         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20393                       (match_operand:V8QI 2 "register_operand" "y")]
20394                      UNSPEC_MASKMOV))]
20395   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20396   ;; @@@ check ordering of operands in intel/nonintel syntax
20397   "maskmovq\t{%2, %1|%1, %2}"
20398   [(set_attr "type" "mmxcvt")
20399    (set_attr "mode" "DI")])
20400
20401 (define_insn "mmx_maskmovq_rex"
20402   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20403         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20404                       (match_operand:V8QI 2 "register_operand" "y")]
20405                      UNSPEC_MASKMOV))]
20406   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20407   ;; @@@ check ordering of operands in intel/nonintel syntax
20408   "maskmovq\t{%2, %1|%1, %2}"
20409   [(set_attr "type" "mmxcvt")
20410    (set_attr "mode" "DI")])
20411
20412 (define_insn "sse_movntv4sf"
20413   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20414         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20415                      UNSPEC_MOVNT))]
20416   "TARGET_SSE"
20417   "movntps\t{%1, %0|%0, %1}"
20418   [(set_attr "type" "ssemov")
20419    (set_attr "mode" "V4SF")])
20420
20421 (define_insn "sse_movntdi"
20422   [(set (match_operand:DI 0 "memory_operand" "=m")
20423         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20424                    UNSPEC_MOVNT))]
20425   "TARGET_SSE || TARGET_3DNOW_A"
20426   "movntq\t{%1, %0|%0, %1}"
20427   [(set_attr "type" "mmxmov")
20428    (set_attr "mode" "DI")])
20429
20430 (define_insn "sse_movhlps"
20431   [(set (match_operand:V4SF 0 "register_operand" "=x")
20432         (vec_merge:V4SF
20433          (match_operand:V4SF 1 "register_operand" "0")
20434          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20435                           (parallel [(const_int 2)
20436                                      (const_int 3)
20437                                      (const_int 0)
20438                                      (const_int 1)]))
20439          (const_int 3)))]
20440   "TARGET_SSE"
20441   "movhlps\t{%2, %0|%0, %2}"
20442   [(set_attr "type" "ssecvt")
20443    (set_attr "mode" "V4SF")])
20444
20445 (define_insn "sse_movlhps"
20446   [(set (match_operand:V4SF 0 "register_operand" "=x")
20447         (vec_merge:V4SF
20448          (match_operand:V4SF 1 "register_operand" "0")
20449          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20450                           (parallel [(const_int 2)
20451                                      (const_int 3)
20452                                      (const_int 0)
20453                                      (const_int 1)]))
20454          (const_int 12)))]
20455   "TARGET_SSE"
20456   "movlhps\t{%2, %0|%0, %2}"
20457   [(set_attr "type" "ssecvt")
20458    (set_attr "mode" "V4SF")])
20459
20460 (define_insn "sse_movhps"
20461   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20462         (vec_merge:V4SF
20463          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20464          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20465          (const_int 12)))]
20466   "TARGET_SSE
20467    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20468   "movhps\t{%2, %0|%0, %2}"
20469   [(set_attr "type" "ssecvt")
20470    (set_attr "mode" "V4SF")])
20471
20472 (define_insn "sse_movlps"
20473   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20474         (vec_merge:V4SF
20475          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20476          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20477          (const_int 3)))]
20478   "TARGET_SSE
20479    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20480   "movlps\t{%2, %0|%0, %2}"
20481   [(set_attr "type" "ssecvt")
20482    (set_attr "mode" "V4SF")])
20483
20484 (define_expand "sse_loadss"
20485   [(match_operand:V4SF 0 "register_operand" "")
20486    (match_operand:SF 1 "memory_operand" "")]
20487   "TARGET_SSE"
20488 {
20489   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20490                                CONST0_RTX (V4SFmode)));
20491   DONE;
20492 })
20493
20494 (define_insn "sse_loadss_1"
20495   [(set (match_operand:V4SF 0 "register_operand" "=x")
20496         (vec_merge:V4SF
20497          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20498          (match_operand:V4SF 2 "const0_operand" "X")
20499          (const_int 1)))]
20500   "TARGET_SSE"
20501   "movss\t{%1, %0|%0, %1}"
20502   [(set_attr "type" "ssemov")
20503    (set_attr "mode" "SF")])
20504
20505 (define_insn "sse_movss"
20506   [(set (match_operand:V4SF 0 "register_operand" "=x")
20507         (vec_merge:V4SF
20508          (match_operand:V4SF 1 "register_operand" "0")
20509          (match_operand:V4SF 2 "register_operand" "x")
20510          (const_int 1)))]
20511   "TARGET_SSE"
20512   "movss\t{%2, %0|%0, %2}"
20513   [(set_attr "type" "ssemov")
20514    (set_attr "mode" "SF")])
20515
20516 (define_insn "sse_storess"
20517   [(set (match_operand:SF 0 "memory_operand" "=m")
20518         (vec_select:SF
20519          (match_operand:V4SF 1 "register_operand" "x")
20520          (parallel [(const_int 0)])))]
20521   "TARGET_SSE"
20522   "movss\t{%1, %0|%0, %1}"
20523   [(set_attr "type" "ssemov")
20524    (set_attr "mode" "SF")])
20525
20526 (define_insn "sse_shufps"
20527   [(set (match_operand:V4SF 0 "register_operand" "=x")
20528         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20529                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20530                       (match_operand:SI 3 "immediate_operand" "i")]
20531                      UNSPEC_SHUFFLE))]
20532   "TARGET_SSE"
20533   ;; @@@ check operand order for intel/nonintel syntax
20534   "shufps\t{%3, %2, %0|%0, %2, %3}"
20535   [(set_attr "type" "ssecvt")
20536    (set_attr "mode" "V4SF")])
20537
20538
20539 ;; SSE arithmetic
20540
20541 (define_insn "addv4sf3"
20542   [(set (match_operand:V4SF 0 "register_operand" "=x")
20543         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20544                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20545   "TARGET_SSE"
20546   "addps\t{%2, %0|%0, %2}"
20547   [(set_attr "type" "sseadd")
20548    (set_attr "mode" "V4SF")])
20549
20550 (define_insn "vmaddv4sf3"
20551   [(set (match_operand:V4SF 0 "register_operand" "=x")
20552         (vec_merge:V4SF
20553          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20554                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20555          (match_dup 1)
20556          (const_int 1)))]
20557   "TARGET_SSE"
20558   "addss\t{%2, %0|%0, %2}"
20559   [(set_attr "type" "sseadd")
20560    (set_attr "mode" "SF")])
20561
20562 (define_insn "subv4sf3"
20563   [(set (match_operand:V4SF 0 "register_operand" "=x")
20564         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20565                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20566   "TARGET_SSE"
20567   "subps\t{%2, %0|%0, %2}"
20568   [(set_attr "type" "sseadd")
20569    (set_attr "mode" "V4SF")])
20570
20571 (define_insn "vmsubv4sf3"
20572   [(set (match_operand:V4SF 0 "register_operand" "=x")
20573         (vec_merge:V4SF
20574          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20575                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20576          (match_dup 1)
20577          (const_int 1)))]
20578   "TARGET_SSE"
20579   "subss\t{%2, %0|%0, %2}"
20580   [(set_attr "type" "sseadd")
20581    (set_attr "mode" "SF")])
20582
20583 ;; ??? Should probably be done by generic code instead.
20584 (define_expand "negv4sf2"
20585   [(set (match_operand:V4SF 0 "register_operand" "")
20586         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20587                   (match_dup 2)))]
20588   "TARGET_SSE"
20589 {
20590   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20591   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20592   operands[2] = force_reg (V4SFmode, vm0);
20593 })
20594
20595 (define_insn "mulv4sf3"
20596   [(set (match_operand:V4SF 0 "register_operand" "=x")
20597         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20598                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20599   "TARGET_SSE"
20600   "mulps\t{%2, %0|%0, %2}"
20601   [(set_attr "type" "ssemul")
20602    (set_attr "mode" "V4SF")])
20603
20604 (define_insn "vmmulv4sf3"
20605   [(set (match_operand:V4SF 0 "register_operand" "=x")
20606         (vec_merge:V4SF
20607          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20608                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20609          (match_dup 1)
20610          (const_int 1)))]
20611   "TARGET_SSE"
20612   "mulss\t{%2, %0|%0, %2}"
20613   [(set_attr "type" "ssemul")
20614    (set_attr "mode" "SF")])
20615
20616 (define_insn "divv4sf3"
20617   [(set (match_operand:V4SF 0 "register_operand" "=x")
20618         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20619                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20620   "TARGET_SSE"
20621   "divps\t{%2, %0|%0, %2}"
20622   [(set_attr "type" "ssediv")
20623    (set_attr "mode" "V4SF")])
20624
20625 (define_insn "vmdivv4sf3"
20626   [(set (match_operand:V4SF 0 "register_operand" "=x")
20627         (vec_merge:V4SF
20628          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20629                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20630          (match_dup 1)
20631          (const_int 1)))]
20632   "TARGET_SSE"
20633   "divss\t{%2, %0|%0, %2}"
20634   [(set_attr "type" "ssediv")
20635    (set_attr "mode" "SF")])
20636
20637
20638 ;; SSE square root/reciprocal
20639
20640 (define_insn "rcpv4sf2"
20641   [(set (match_operand:V4SF 0 "register_operand" "=x")
20642         (unspec:V4SF
20643          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20644   "TARGET_SSE"
20645   "rcpps\t{%1, %0|%0, %1}"
20646   [(set_attr "type" "sse")
20647    (set_attr "mode" "V4SF")])
20648
20649 (define_insn "vmrcpv4sf2"
20650   [(set (match_operand:V4SF 0 "register_operand" "=x")
20651         (vec_merge:V4SF
20652          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20653                       UNSPEC_RCP)
20654          (match_operand:V4SF 2 "register_operand" "0")
20655          (const_int 1)))]
20656   "TARGET_SSE"
20657   "rcpss\t{%1, %0|%0, %1}"
20658   [(set_attr "type" "sse")
20659    (set_attr "mode" "SF")])
20660
20661 (define_insn "rsqrtv4sf2"
20662   [(set (match_operand:V4SF 0 "register_operand" "=x")
20663         (unspec:V4SF
20664          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20665   "TARGET_SSE"
20666   "rsqrtps\t{%1, %0|%0, %1}"
20667   [(set_attr "type" "sse")
20668    (set_attr "mode" "V4SF")])
20669
20670 (define_insn "vmrsqrtv4sf2"
20671   [(set (match_operand:V4SF 0 "register_operand" "=x")
20672         (vec_merge:V4SF
20673          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20674                       UNSPEC_RSQRT)
20675          (match_operand:V4SF 2 "register_operand" "0")
20676          (const_int 1)))]
20677   "TARGET_SSE"
20678   "rsqrtss\t{%1, %0|%0, %1}"
20679   [(set_attr "type" "sse")
20680    (set_attr "mode" "SF")])
20681
20682 (define_insn "sqrtv4sf2"
20683   [(set (match_operand:V4SF 0 "register_operand" "=x")
20684         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20685   "TARGET_SSE"
20686   "sqrtps\t{%1, %0|%0, %1}"
20687   [(set_attr "type" "sse")
20688    (set_attr "mode" "V4SF")])
20689
20690 (define_insn "vmsqrtv4sf2"
20691   [(set (match_operand:V4SF 0 "register_operand" "=x")
20692         (vec_merge:V4SF
20693          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20694          (match_operand:V4SF 2 "register_operand" "0")
20695          (const_int 1)))]
20696   "TARGET_SSE"
20697   "sqrtss\t{%1, %0|%0, %1}"
20698   [(set_attr "type" "sse")
20699    (set_attr "mode" "SF")])
20700
20701 ;; SSE logical operations.
20702
20703 ;; SSE defines logical operations on floating point values.  This brings
20704 ;; interesting challenge to RTL representation where logicals are only valid
20705 ;; on integral types.  We deal with this by representing the floating point
20706 ;; logical as logical on arguments casted to TImode as this is what hardware
20707 ;; really does.  Unfortunately hardware requires the type information to be
20708 ;; present and thus we must avoid subregs from being simplified and eliminated
20709 ;; in later compilation phases.
20710 ;;
20711 ;; We have following variants from each instruction:
20712 ;; sse_andsf3 - the operation taking V4SF vector operands
20713 ;;              and doing TImode cast on them
20714 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20715 ;;                      TImode, since backend insist on eliminating casts
20716 ;;                      on memory operands
20717 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20718 ;;                   We cannot accept memory operand here as instruction reads
20719 ;;                   whole scalar.  This is generated only post reload by GCC
20720 ;;                   scalar float operations that expands to logicals (fabs)
20721 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20722 ;;                   memory operand.  Eventually combine can be able
20723 ;;                   to synthesize these using splitter.
20724 ;; sse2_anddf3, *sse2_anddf3_memory
20725 ;;              
20726 ;; 
20727 ;; These are not called andti3 etc. because we really really don't want
20728 ;; the compiler to widen DImode ands to TImode ands and then try to move
20729 ;; into DImode subregs of SSE registers, and them together, and move out
20730 ;; of DImode subregs again!
20731 ;; SSE1 single precision floating point logical operation
20732 (define_expand "sse_andv4sf3"
20733   [(set (match_operand:V4SF 0 "register_operand" "")
20734         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20735                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20736   "TARGET_SSE"
20737   "")
20738
20739 (define_insn "*sse_andv4sf3"
20740   [(set (match_operand:V4SF 0 "register_operand" "=x")
20741         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20742                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20743   "TARGET_SSE
20744    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20745   "andps\t{%2, %0|%0, %2}"
20746   [(set_attr "type" "sselog")
20747    (set_attr "mode" "V4SF")])
20748
20749 (define_expand "sse_nandv4sf3"
20750   [(set (match_operand:V4SF 0 "register_operand" "")
20751         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20752                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20753   "TARGET_SSE"
20754   "")
20755
20756 (define_insn "*sse_nandv4sf3"
20757   [(set (match_operand:V4SF 0 "register_operand" "=x")
20758         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20759                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20760   "TARGET_SSE"
20761   "andnps\t{%2, %0|%0, %2}"
20762   [(set_attr "type" "sselog")
20763    (set_attr "mode" "V4SF")])
20764
20765 (define_expand "sse_iorv4sf3"
20766   [(set (match_operand:V4SF 0 "register_operand" "")
20767         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20768                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20769   "TARGET_SSE"
20770   "")
20771
20772 (define_insn "*sse_iorv4sf3"
20773   [(set (match_operand:V4SF 0 "register_operand" "=x")
20774         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20775                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20776   "TARGET_SSE
20777    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20778   "orps\t{%2, %0|%0, %2}"
20779   [(set_attr "type" "sselog")
20780    (set_attr "mode" "V4SF")])
20781
20782 (define_expand "sse_xorv4sf3"
20783   [(set (match_operand:V4SF 0 "register_operand" "")
20784         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20785                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20786   "TARGET_SSE"
20787   "")
20788
20789 (define_insn "*sse_xorv4sf3"
20790   [(set (match_operand:V4SF 0 "register_operand" "=x")
20791         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20792                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20793   "TARGET_SSE
20794    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20795   "xorps\t{%2, %0|%0, %2}"
20796   [(set_attr "type" "sselog")
20797    (set_attr "mode" "V4SF")])
20798
20799 ;; SSE2 double precision floating point logical operation
20800
20801 (define_expand "sse2_andv2df3"
20802   [(set (match_operand:V2DF 0 "register_operand" "")
20803         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20804                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20805   "TARGET_SSE2"
20806   "")
20807
20808 (define_insn "*sse2_andv2df3"
20809   [(set (match_operand:V2DF 0 "register_operand" "=x")
20810         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20811                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20812   "TARGET_SSE2
20813    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20814   "andpd\t{%2, %0|%0, %2}"
20815   [(set_attr "type" "sselog")
20816    (set_attr "mode" "V2DF")])
20817
20818 (define_expand "sse2_nandv2df3"
20819   [(set (match_operand:V2DF 0 "register_operand" "")
20820         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20821                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20822   "TARGET_SSE2"
20823   "")
20824
20825 (define_insn "*sse2_nandv2df3"
20826   [(set (match_operand:V2DF 0 "register_operand" "=x")
20827         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20828                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20829   "TARGET_SSE2"
20830   "andnpd\t{%2, %0|%0, %2}"
20831   [(set_attr "type" "sselog")
20832    (set_attr "mode" "V2DF")])
20833
20834 (define_expand "sse2_iorv2df3"
20835   [(set (match_operand:V2DF 0 "register_operand" "")
20836         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20837                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20838   "TARGET_SSE2"
20839   "")
20840
20841 (define_insn "*sse2_iorv2df3"
20842   [(set (match_operand:V2DF 0 "register_operand" "=x")
20843         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20844                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20845   "TARGET_SSE2
20846    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20847   "orpd\t{%2, %0|%0, %2}"
20848   [(set_attr "type" "sselog")
20849    (set_attr "mode" "V2DF")])
20850
20851 (define_expand "sse2_xorv2df3"
20852   [(set (match_operand:V2DF 0 "register_operand" "")
20853         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20854                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20855   "TARGET_SSE2"
20856   "")
20857
20858 (define_insn "*sse2_xorv2df3"
20859   [(set (match_operand:V2DF 0 "register_operand" "=x")
20860         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20861                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20862   "TARGET_SSE2
20863    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20864   "xorpd\t{%2, %0|%0, %2}"
20865   [(set_attr "type" "sselog")
20866    (set_attr "mode" "V2DF")])
20867
20868 ;; SSE2 integral logicals.  These patterns must always come after floating
20869 ;; point ones since we don't want compiler to use integer opcodes on floating
20870 ;; point SSE values to avoid matching of subregs in the match_operand.
20871 (define_insn "*sse2_andti3"
20872   [(set (match_operand:TI 0 "register_operand" "=x")
20873         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20874                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20875   "TARGET_SSE2
20876    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20877   "pand\t{%2, %0|%0, %2}"
20878   [(set_attr "type" "sselog")
20879    (set_attr "mode" "TI")])
20880
20881 (define_insn "sse2_andv2di3"
20882   [(set (match_operand:V2DI 0 "register_operand" "=x")
20883         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20884                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20885   "TARGET_SSE2
20886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20887   "pand\t{%2, %0|%0, %2}"
20888   [(set_attr "type" "sselog")
20889    (set_attr "mode" "TI")])
20890
20891 (define_insn "*sse2_nandti3"
20892   [(set (match_operand:TI 0 "register_operand" "=x")
20893         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20894                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20895   "TARGET_SSE2"
20896   "pandn\t{%2, %0|%0, %2}"
20897   [(set_attr "type" "sselog")
20898    (set_attr "mode" "TI")])
20899
20900 (define_insn "sse2_nandv2di3"
20901   [(set (match_operand:V2DI 0 "register_operand" "=x")
20902         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20903                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20904   "TARGET_SSE2
20905    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20906   "pandn\t{%2, %0|%0, %2}"
20907   [(set_attr "type" "sselog")
20908    (set_attr "mode" "TI")])
20909
20910 (define_insn "*sse2_iorti3"
20911   [(set (match_operand:TI 0 "register_operand" "=x")
20912         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20913                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20914   "TARGET_SSE2
20915    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20916   "por\t{%2, %0|%0, %2}"
20917   [(set_attr "type" "sselog")
20918    (set_attr "mode" "TI")])
20919
20920 (define_insn "sse2_iorv2di3"
20921   [(set (match_operand:V2DI 0 "register_operand" "=x")
20922         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20923                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20924   "TARGET_SSE2
20925    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20926   "por\t{%2, %0|%0, %2}"
20927   [(set_attr "type" "sselog")
20928    (set_attr "mode" "TI")])
20929
20930 (define_insn "*sse2_xorti3"
20931   [(set (match_operand:TI 0 "register_operand" "=x")
20932         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20933                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20934   "TARGET_SSE2
20935    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20936   "pxor\t{%2, %0|%0, %2}"
20937   [(set_attr "type" "sselog")
20938    (set_attr "mode" "TI")])
20939
20940 (define_insn "sse2_xorv2di3"
20941   [(set (match_operand:V2DI 0 "register_operand" "=x")
20942         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20943                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20944   "TARGET_SSE2
20945    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20946   "pxor\t{%2, %0|%0, %2}"
20947   [(set_attr "type" "sselog")
20948    (set_attr "mode" "TI")])
20949
20950 ;; Use xor, but don't show input operands so they aren't live before
20951 ;; this insn.
20952 (define_insn "sse_clrv4sf"
20953   [(set (match_operand:V4SF 0 "register_operand" "=x")
20954         (match_operand:V4SF 1 "const0_operand" "X"))]
20955   "TARGET_SSE"
20956 {
20957   if (get_attr_mode (insn) == MODE_TI)
20958     return "pxor\t{%0, %0|%0, %0}";
20959   else
20960     return "xorps\t{%0, %0|%0, %0}";
20961 }
20962   [(set_attr "type" "sselog")
20963    (set_attr "memory" "none")
20964    (set (attr "mode")
20965         (if_then_else
20966            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20967                          (const_int 0))
20968                      (ne (symbol_ref "TARGET_SSE2")
20969                          (const_int 0)))
20970                 (eq (symbol_ref "optimize_size")
20971                     (const_int 0)))
20972          (const_string "TI")
20973          (const_string "V4SF")))])
20974
20975 ;; Use xor, but don't show input operands so they aren't live before
20976 ;; this insn.
20977 (define_insn "sse_clrv2df"
20978   [(set (match_operand:V2DF 0 "register_operand" "=x")
20979         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20980   "TARGET_SSE2"
20981   "xorpd\t{%0, %0|%0, %0}"
20982   [(set_attr "type" "sselog")
20983    (set_attr "memory" "none")
20984    (set_attr "mode" "V4SF")])
20985
20986 ;; SSE mask-generating compares
20987
20988 (define_insn "maskcmpv4sf3"
20989   [(set (match_operand:V4SI 0 "register_operand" "=x")
20990         (match_operator:V4SI 3 "sse_comparison_operator"
20991                 [(match_operand:V4SF 1 "register_operand" "0")
20992                  (match_operand:V4SF 2 "register_operand" "x")]))]
20993   "TARGET_SSE"
20994   "cmp%D3ps\t{%2, %0|%0, %2}"
20995   [(set_attr "type" "ssecmp")
20996    (set_attr "mode" "V4SF")])
20997
20998 (define_insn "maskncmpv4sf3"
20999   [(set (match_operand:V4SI 0 "register_operand" "=x")
21000         (not:V4SI
21001          (match_operator:V4SI 3 "sse_comparison_operator"
21002                 [(match_operand:V4SF 1 "register_operand" "0")
21003                  (match_operand:V4SF 2 "register_operand" "x")])))]
21004   "TARGET_SSE"
21005 {
21006   if (GET_CODE (operands[3]) == UNORDERED)
21007     return "cmpordps\t{%2, %0|%0, %2}";
21008   else
21009     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21010 }
21011   [(set_attr "type" "ssecmp")
21012    (set_attr "mode" "V4SF")])
21013
21014 (define_insn "vmmaskcmpv4sf3"
21015   [(set (match_operand:V4SI 0 "register_operand" "=x")
21016         (vec_merge:V4SI
21017          (match_operator:V4SI 3 "sse_comparison_operator"
21018                 [(match_operand:V4SF 1 "register_operand" "0")
21019                  (match_operand:V4SF 2 "register_operand" "x")])
21020          (subreg:V4SI (match_dup 1) 0)
21021          (const_int 1)))]
21022   "TARGET_SSE"
21023   "cmp%D3ss\t{%2, %0|%0, %2}"
21024   [(set_attr "type" "ssecmp")
21025    (set_attr "mode" "SF")])
21026
21027 (define_insn "vmmaskncmpv4sf3"
21028   [(set (match_operand:V4SI 0 "register_operand" "=x")
21029         (vec_merge:V4SI
21030          (not:V4SI
21031           (match_operator:V4SI 3 "sse_comparison_operator"
21032                 [(match_operand:V4SF 1 "register_operand" "0")
21033                  (match_operand:V4SF 2 "register_operand" "x")]))
21034          (subreg:V4SI (match_dup 1) 0)
21035          (const_int 1)))]
21036   "TARGET_SSE"
21037 {
21038   if (GET_CODE (operands[3]) == UNORDERED)
21039     return "cmpordss\t{%2, %0|%0, %2}";
21040   else
21041     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21042 }
21043   [(set_attr "type" "ssecmp")
21044    (set_attr "mode" "SF")])
21045
21046 (define_insn "sse_comi"
21047   [(set (reg:CCFP FLAGS_REG)
21048         (compare:CCFP (vec_select:SF
21049                        (match_operand:V4SF 0 "register_operand" "x")
21050                        (parallel [(const_int 0)]))
21051                       (vec_select:SF
21052                        (match_operand:V4SF 1 "register_operand" "x")
21053                        (parallel [(const_int 0)]))))]
21054   "TARGET_SSE"
21055   "comiss\t{%1, %0|%0, %1}"
21056   [(set_attr "type" "ssecomi")
21057    (set_attr "mode" "SF")])
21058
21059 (define_insn "sse_ucomi"
21060   [(set (reg:CCFPU FLAGS_REG)
21061         (compare:CCFPU (vec_select:SF
21062                         (match_operand:V4SF 0 "register_operand" "x")
21063                         (parallel [(const_int 0)]))
21064                        (vec_select:SF
21065                         (match_operand:V4SF 1 "register_operand" "x")
21066                         (parallel [(const_int 0)]))))]
21067   "TARGET_SSE"
21068   "ucomiss\t{%1, %0|%0, %1}"
21069   [(set_attr "type" "ssecomi")
21070    (set_attr "mode" "SF")])
21071
21072
21073 ;; SSE unpack
21074
21075 (define_insn "sse_unpckhps"
21076   [(set (match_operand:V4SF 0 "register_operand" "=x")
21077         (vec_merge:V4SF
21078          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21079                           (parallel [(const_int 2)
21080                                      (const_int 0)
21081                                      (const_int 3)
21082                                      (const_int 1)]))
21083          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21084                           (parallel [(const_int 0)
21085                                      (const_int 2)
21086                                      (const_int 1)
21087                                      (const_int 3)]))
21088          (const_int 5)))]
21089   "TARGET_SSE"
21090   "unpckhps\t{%2, %0|%0, %2}"
21091   [(set_attr "type" "ssecvt")
21092    (set_attr "mode" "V4SF")])
21093
21094 (define_insn "sse_unpcklps"
21095   [(set (match_operand:V4SF 0 "register_operand" "=x")
21096         (vec_merge:V4SF
21097          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21098                           (parallel [(const_int 0)
21099                                      (const_int 2)
21100                                      (const_int 1)
21101                                      (const_int 3)]))
21102          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21103                           (parallel [(const_int 2)
21104                                      (const_int 0)
21105                                      (const_int 3)
21106                                      (const_int 1)]))
21107          (const_int 5)))]
21108   "TARGET_SSE"
21109   "unpcklps\t{%2, %0|%0, %2}"
21110   [(set_attr "type" "ssecvt")
21111    (set_attr "mode" "V4SF")])
21112
21113
21114 ;; SSE min/max
21115
21116 (define_insn "smaxv4sf3"
21117   [(set (match_operand:V4SF 0 "register_operand" "=x")
21118         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21119                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21120   "TARGET_SSE"
21121   "maxps\t{%2, %0|%0, %2}"
21122   [(set_attr "type" "sse")
21123    (set_attr "mode" "V4SF")])
21124
21125 (define_insn "vmsmaxv4sf3"
21126   [(set (match_operand:V4SF 0 "register_operand" "=x")
21127         (vec_merge:V4SF
21128          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21129                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21130          (match_dup 1)
21131          (const_int 1)))]
21132   "TARGET_SSE"
21133   "maxss\t{%2, %0|%0, %2}"
21134   [(set_attr "type" "sse")
21135    (set_attr "mode" "SF")])
21136
21137 (define_insn "sminv4sf3"
21138   [(set (match_operand:V4SF 0 "register_operand" "=x")
21139         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21140                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21141   "TARGET_SSE"
21142   "minps\t{%2, %0|%0, %2}"
21143   [(set_attr "type" "sse")
21144    (set_attr "mode" "V4SF")])
21145
21146 (define_insn "vmsminv4sf3"
21147   [(set (match_operand:V4SF 0 "register_operand" "=x")
21148         (vec_merge:V4SF
21149          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21150                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21151          (match_dup 1)
21152          (const_int 1)))]
21153   "TARGET_SSE"
21154   "minss\t{%2, %0|%0, %2}"
21155   [(set_attr "type" "sse")
21156    (set_attr "mode" "SF")])
21157
21158 ;; SSE <-> integer/MMX conversions
21159
21160 (define_insn "cvtpi2ps"
21161   [(set (match_operand:V4SF 0 "register_operand" "=x")
21162         (vec_merge:V4SF
21163          (match_operand:V4SF 1 "register_operand" "0")
21164          (vec_duplicate:V4SF
21165           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21166          (const_int 12)))]
21167   "TARGET_SSE"
21168   "cvtpi2ps\t{%2, %0|%0, %2}"
21169   [(set_attr "type" "ssecvt")
21170    (set_attr "mode" "V4SF")])
21171
21172 (define_insn "cvtps2pi"
21173   [(set (match_operand:V2SI 0 "register_operand" "=y")
21174         (vec_select:V2SI
21175          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21176          (parallel [(const_int 0) (const_int 1)])))]
21177   "TARGET_SSE"
21178   "cvtps2pi\t{%1, %0|%0, %1}"
21179   [(set_attr "type" "ssecvt")
21180    (set_attr "mode" "V4SF")])
21181
21182 (define_insn "cvttps2pi"
21183   [(set (match_operand:V2SI 0 "register_operand" "=y")
21184         (vec_select:V2SI
21185          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21186                       UNSPEC_FIX)
21187          (parallel [(const_int 0) (const_int 1)])))]
21188   "TARGET_SSE"
21189   "cvttps2pi\t{%1, %0|%0, %1}"
21190   [(set_attr "type" "ssecvt")
21191    (set_attr "mode" "SF")])
21192
21193 (define_insn "cvtsi2ss"
21194   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21195         (vec_merge:V4SF
21196          (match_operand:V4SF 1 "register_operand" "0,0")
21197          (vec_duplicate:V4SF
21198           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21199          (const_int 14)))]
21200   "TARGET_SSE"
21201   "cvtsi2ss\t{%2, %0|%0, %2}"
21202   [(set_attr "type" "sseicvt")
21203    (set_attr "athlon_decode" "vector,double")
21204    (set_attr "mode" "SF")])
21205
21206 (define_insn "cvtsi2ssq"
21207   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21208         (vec_merge:V4SF
21209          (match_operand:V4SF 1 "register_operand" "0,0")
21210          (vec_duplicate:V4SF
21211           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21212          (const_int 14)))]
21213   "TARGET_SSE && TARGET_64BIT"
21214   "cvtsi2ssq\t{%2, %0|%0, %2}"
21215   [(set_attr "type" "sseicvt")
21216    (set_attr "athlon_decode" "vector,double")
21217    (set_attr "mode" "SF")])
21218
21219 (define_insn "cvtss2si"
21220   [(set (match_operand:SI 0 "register_operand" "=r,r")
21221         (vec_select:SI
21222          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21223          (parallel [(const_int 0)])))]
21224   "TARGET_SSE"
21225   "cvtss2si\t{%1, %0|%0, %1}"
21226   [(set_attr "type" "sseicvt")
21227    (set_attr "athlon_decode" "double,vector")
21228    (set_attr "mode" "SI")])
21229
21230 (define_insn "cvtss2siq"
21231   [(set (match_operand:DI 0 "register_operand" "=r,r")
21232         (vec_select:DI
21233          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21234          (parallel [(const_int 0)])))]
21235   "TARGET_SSE"
21236   "cvtss2siq\t{%1, %0|%0, %1}"
21237   [(set_attr "type" "sseicvt")
21238    (set_attr "athlon_decode" "double,vector")
21239    (set_attr "mode" "DI")])
21240
21241 (define_insn "cvttss2si"
21242   [(set (match_operand:SI 0 "register_operand" "=r,r")
21243         (vec_select:SI
21244          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21245                       UNSPEC_FIX)
21246          (parallel [(const_int 0)])))]
21247   "TARGET_SSE"
21248   "cvttss2si\t{%1, %0|%0, %1}"
21249   [(set_attr "type" "sseicvt")
21250    (set_attr "mode" "SF")
21251    (set_attr "athlon_decode" "double,vector")])
21252
21253 (define_insn "cvttss2siq"
21254   [(set (match_operand:DI 0 "register_operand" "=r,r")
21255         (vec_select:DI
21256          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21257                       UNSPEC_FIX)
21258          (parallel [(const_int 0)])))]
21259   "TARGET_SSE && TARGET_64BIT"
21260   "cvttss2siq\t{%1, %0|%0, %1}"
21261   [(set_attr "type" "sseicvt")
21262    (set_attr "mode" "SF")
21263    (set_attr "athlon_decode" "double,vector")])
21264
21265
21266 ;; MMX insns
21267
21268 ;; MMX arithmetic
21269
21270 (define_insn "addv8qi3"
21271   [(set (match_operand:V8QI 0 "register_operand" "=y")
21272         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21273                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21274   "TARGET_MMX"
21275   "paddb\t{%2, %0|%0, %2}"
21276   [(set_attr "type" "mmxadd")
21277    (set_attr "mode" "DI")])
21278
21279 (define_insn "addv4hi3"
21280   [(set (match_operand:V4HI 0 "register_operand" "=y")
21281         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21282                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21283   "TARGET_MMX"
21284   "paddw\t{%2, %0|%0, %2}"
21285   [(set_attr "type" "mmxadd")
21286    (set_attr "mode" "DI")])
21287
21288 (define_insn "addv2si3"
21289   [(set (match_operand:V2SI 0 "register_operand" "=y")
21290         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21291                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21292   "TARGET_MMX"
21293   "paddd\t{%2, %0|%0, %2}"
21294   [(set_attr "type" "mmxadd")
21295    (set_attr "mode" "DI")])
21296
21297 (define_insn "mmx_adddi3"
21298   [(set (match_operand:DI 0 "register_operand" "=y")
21299         (unspec:DI
21300          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21301                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21302          UNSPEC_NOP))]
21303   "TARGET_MMX"
21304   "paddq\t{%2, %0|%0, %2}"
21305   [(set_attr "type" "mmxadd")
21306    (set_attr "mode" "DI")])
21307
21308 (define_insn "ssaddv8qi3"
21309   [(set (match_operand:V8QI 0 "register_operand" "=y")
21310         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21311                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21312   "TARGET_MMX"
21313   "paddsb\t{%2, %0|%0, %2}"
21314   [(set_attr "type" "mmxadd")
21315    (set_attr "mode" "DI")])
21316
21317 (define_insn "ssaddv4hi3"
21318   [(set (match_operand:V4HI 0 "register_operand" "=y")
21319         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21320                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21321   "TARGET_MMX"
21322   "paddsw\t{%2, %0|%0, %2}"
21323   [(set_attr "type" "mmxadd")
21324    (set_attr "mode" "DI")])
21325
21326 (define_insn "usaddv8qi3"
21327   [(set (match_operand:V8QI 0 "register_operand" "=y")
21328         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21329                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21330   "TARGET_MMX"
21331   "paddusb\t{%2, %0|%0, %2}"
21332   [(set_attr "type" "mmxadd")
21333    (set_attr "mode" "DI")])
21334
21335 (define_insn "usaddv4hi3"
21336   [(set (match_operand:V4HI 0 "register_operand" "=y")
21337         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21338                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21339   "TARGET_MMX"
21340   "paddusw\t{%2, %0|%0, %2}"
21341   [(set_attr "type" "mmxadd")
21342    (set_attr "mode" "DI")])
21343
21344 (define_insn "subv8qi3"
21345   [(set (match_operand:V8QI 0 "register_operand" "=y")
21346         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21347                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21348   "TARGET_MMX"
21349   "psubb\t{%2, %0|%0, %2}"
21350   [(set_attr "type" "mmxadd")
21351    (set_attr "mode" "DI")])
21352
21353 (define_insn "subv4hi3"
21354   [(set (match_operand:V4HI 0 "register_operand" "=y")
21355         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21356                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21357   "TARGET_MMX"
21358   "psubw\t{%2, %0|%0, %2}"
21359   [(set_attr "type" "mmxadd")
21360    (set_attr "mode" "DI")])
21361
21362 (define_insn "subv2si3"
21363   [(set (match_operand:V2SI 0 "register_operand" "=y")
21364         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21365                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21366   "TARGET_MMX"
21367   "psubd\t{%2, %0|%0, %2}"
21368   [(set_attr "type" "mmxadd")
21369    (set_attr "mode" "DI")])
21370
21371 (define_insn "mmx_subdi3"
21372   [(set (match_operand:DI 0 "register_operand" "=y")
21373         (unspec:DI
21374          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21375                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21376          UNSPEC_NOP))]
21377   "TARGET_MMX"
21378   "psubq\t{%2, %0|%0, %2}"
21379   [(set_attr "type" "mmxadd")
21380    (set_attr "mode" "DI")])
21381
21382 (define_insn "sssubv8qi3"
21383   [(set (match_operand:V8QI 0 "register_operand" "=y")
21384         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21385                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21386   "TARGET_MMX"
21387   "psubsb\t{%2, %0|%0, %2}"
21388   [(set_attr "type" "mmxadd")
21389    (set_attr "mode" "DI")])
21390
21391 (define_insn "sssubv4hi3"
21392   [(set (match_operand:V4HI 0 "register_operand" "=y")
21393         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21394                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21395   "TARGET_MMX"
21396   "psubsw\t{%2, %0|%0, %2}"
21397   [(set_attr "type" "mmxadd")
21398    (set_attr "mode" "DI")])
21399
21400 (define_insn "ussubv8qi3"
21401   [(set (match_operand:V8QI 0 "register_operand" "=y")
21402         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21403                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21404   "TARGET_MMX"
21405   "psubusb\t{%2, %0|%0, %2}"
21406   [(set_attr "type" "mmxadd")
21407    (set_attr "mode" "DI")])
21408
21409 (define_insn "ussubv4hi3"
21410   [(set (match_operand:V4HI 0 "register_operand" "=y")
21411         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21412                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21413   "TARGET_MMX"
21414   "psubusw\t{%2, %0|%0, %2}"
21415   [(set_attr "type" "mmxadd")
21416    (set_attr "mode" "DI")])
21417
21418 (define_insn "mulv4hi3"
21419   [(set (match_operand:V4HI 0 "register_operand" "=y")
21420         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21421                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21422   "TARGET_MMX"
21423   "pmullw\t{%2, %0|%0, %2}"
21424   [(set_attr "type" "mmxmul")
21425    (set_attr "mode" "DI")])
21426
21427 (define_insn "smulv4hi3_highpart"
21428   [(set (match_operand:V4HI 0 "register_operand" "=y")
21429         (truncate:V4HI
21430          (lshiftrt:V4SI
21431           (mult:V4SI (sign_extend:V4SI
21432                       (match_operand:V4HI 1 "register_operand" "0"))
21433                      (sign_extend:V4SI
21434                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21435           (const_int 16))))]
21436   "TARGET_MMX"
21437   "pmulhw\t{%2, %0|%0, %2}"
21438   [(set_attr "type" "mmxmul")
21439    (set_attr "mode" "DI")])
21440
21441 (define_insn "umulv4hi3_highpart"
21442   [(set (match_operand:V4HI 0 "register_operand" "=y")
21443         (truncate:V4HI
21444          (lshiftrt:V4SI
21445           (mult:V4SI (zero_extend:V4SI
21446                       (match_operand:V4HI 1 "register_operand" "0"))
21447                      (zero_extend:V4SI
21448                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21449           (const_int 16))))]
21450   "TARGET_SSE || TARGET_3DNOW_A"
21451   "pmulhuw\t{%2, %0|%0, %2}"
21452   [(set_attr "type" "mmxmul")
21453    (set_attr "mode" "DI")])
21454
21455 (define_insn "mmx_pmaddwd"
21456   [(set (match_operand:V2SI 0 "register_operand" "=y")
21457         (plus:V2SI
21458          (mult:V2SI
21459           (sign_extend:V2SI
21460            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21461                             (parallel [(const_int 0) (const_int 2)])))
21462           (sign_extend:V2SI
21463            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21464                             (parallel [(const_int 0) (const_int 2)]))))
21465          (mult:V2SI
21466           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21467                                              (parallel [(const_int 1)
21468                                                         (const_int 3)])))
21469           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21470                                              (parallel [(const_int 1)
21471                                                         (const_int 3)]))))))]
21472   "TARGET_MMX"
21473   "pmaddwd\t{%2, %0|%0, %2}"
21474   [(set_attr "type" "mmxmul")
21475    (set_attr "mode" "DI")])
21476
21477
21478 ;; MMX logical operations
21479 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21480 ;; normal code that also wants to use the FPU from getting broken.
21481 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21482 (define_insn "mmx_iordi3"
21483   [(set (match_operand:DI 0 "register_operand" "=y")
21484         (unspec:DI
21485          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21486                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21487          UNSPEC_NOP))]
21488   "TARGET_MMX"
21489   "por\t{%2, %0|%0, %2}"
21490   [(set_attr "type" "mmxadd")
21491    (set_attr "mode" "DI")])
21492
21493 (define_insn "mmx_xordi3"
21494   [(set (match_operand:DI 0 "register_operand" "=y")
21495         (unspec:DI
21496          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21497                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21498          UNSPEC_NOP))]
21499   "TARGET_MMX"
21500   "pxor\t{%2, %0|%0, %2}"
21501   [(set_attr "type" "mmxadd")
21502    (set_attr "mode" "DI")
21503    (set_attr "memory" "none")])
21504
21505 ;; Same as pxor, but don't show input operands so that we don't think
21506 ;; they are live.
21507 (define_insn "mmx_clrdi"
21508   [(set (match_operand:DI 0 "register_operand" "=y")
21509         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21510   "TARGET_MMX"
21511   "pxor\t{%0, %0|%0, %0}"
21512   [(set_attr "type" "mmxadd")
21513    (set_attr "mode" "DI")
21514    (set_attr "memory" "none")])
21515
21516 (define_insn "mmx_anddi3"
21517   [(set (match_operand:DI 0 "register_operand" "=y")
21518         (unspec:DI
21519          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21520                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21521          UNSPEC_NOP))]
21522   "TARGET_MMX"
21523   "pand\t{%2, %0|%0, %2}"
21524   [(set_attr "type" "mmxadd")
21525    (set_attr "mode" "DI")])
21526
21527 (define_insn "mmx_nanddi3"
21528   [(set (match_operand:DI 0 "register_operand" "=y")
21529         (unspec:DI
21530          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21531                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21532          UNSPEC_NOP))]
21533   "TARGET_MMX"
21534   "pandn\t{%2, %0|%0, %2}"
21535   [(set_attr "type" "mmxadd")
21536    (set_attr "mode" "DI")])
21537
21538
21539 ;; MMX unsigned averages/sum of absolute differences
21540
21541 (define_insn "mmx_uavgv8qi3"
21542   [(set (match_operand:V8QI 0 "register_operand" "=y")
21543         (ashiftrt:V8QI
21544          (plus:V8QI (plus:V8QI
21545                      (match_operand:V8QI 1 "register_operand" "0")
21546                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21547                     (const_vector:V8QI [(const_int 1)
21548                                         (const_int 1)
21549                                         (const_int 1)
21550                                         (const_int 1)
21551                                         (const_int 1)
21552                                         (const_int 1)
21553                                         (const_int 1)
21554                                         (const_int 1)]))
21555          (const_int 1)))]
21556   "TARGET_SSE || TARGET_3DNOW_A"
21557   "pavgb\t{%2, %0|%0, %2}"
21558   [(set_attr "type" "mmxshft")
21559    (set_attr "mode" "DI")])
21560
21561 (define_insn "mmx_uavgv4hi3"
21562   [(set (match_operand:V4HI 0 "register_operand" "=y")
21563         (ashiftrt:V4HI
21564          (plus:V4HI (plus:V4HI
21565                      (match_operand:V4HI 1 "register_operand" "0")
21566                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21567                     (const_vector:V4HI [(const_int 1)
21568                                         (const_int 1)
21569                                         (const_int 1)
21570                                         (const_int 1)]))
21571          (const_int 1)))]
21572   "TARGET_SSE || TARGET_3DNOW_A"
21573   "pavgw\t{%2, %0|%0, %2}"
21574   [(set_attr "type" "mmxshft")
21575    (set_attr "mode" "DI")])
21576
21577 (define_insn "mmx_psadbw"
21578   [(set (match_operand:DI 0 "register_operand" "=y")
21579         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21580                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21581                    UNSPEC_PSADBW))]
21582   "TARGET_SSE || TARGET_3DNOW_A"
21583   "psadbw\t{%2, %0|%0, %2}"
21584   [(set_attr "type" "mmxshft")
21585    (set_attr "mode" "DI")])
21586
21587
21588 ;; MMX insert/extract/shuffle
21589
21590 (define_insn "mmx_pinsrw"
21591   [(set (match_operand:V4HI 0 "register_operand" "=y")
21592         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21593                         (vec_duplicate:V4HI
21594                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21595                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21596   "TARGET_SSE || TARGET_3DNOW_A"
21597   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21598   [(set_attr "type" "mmxcvt")
21599    (set_attr "mode" "DI")])
21600
21601 (define_insn "mmx_pextrw"
21602   [(set (match_operand:SI 0 "register_operand" "=r")
21603         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21604                                        (parallel
21605                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21606   "TARGET_SSE || TARGET_3DNOW_A"
21607   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21608   [(set_attr "type" "mmxcvt")
21609    (set_attr "mode" "DI")])
21610
21611 (define_insn "mmx_pshufw"
21612   [(set (match_operand:V4HI 0 "register_operand" "=y")
21613         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21614                       (match_operand:SI 2 "immediate_operand" "i")]
21615                      UNSPEC_SHUFFLE))]
21616   "TARGET_SSE || TARGET_3DNOW_A"
21617   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21618   [(set_attr "type" "mmxcvt")
21619    (set_attr "mode" "DI")])
21620
21621
21622 ;; MMX mask-generating comparisons
21623
21624 (define_insn "eqv8qi3"
21625   [(set (match_operand:V8QI 0 "register_operand" "=y")
21626         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21627                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21628   "TARGET_MMX"
21629   "pcmpeqb\t{%2, %0|%0, %2}"
21630   [(set_attr "type" "mmxcmp")
21631    (set_attr "mode" "DI")])
21632
21633 (define_insn "eqv4hi3"
21634   [(set (match_operand:V4HI 0 "register_operand" "=y")
21635         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21636                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21637   "TARGET_MMX"
21638   "pcmpeqw\t{%2, %0|%0, %2}"
21639   [(set_attr "type" "mmxcmp")
21640    (set_attr "mode" "DI")])
21641
21642 (define_insn "eqv2si3"
21643   [(set (match_operand:V2SI 0 "register_operand" "=y")
21644         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21645                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21646   "TARGET_MMX"
21647   "pcmpeqd\t{%2, %0|%0, %2}"
21648   [(set_attr "type" "mmxcmp")
21649    (set_attr "mode" "DI")])
21650
21651 (define_insn "gtv8qi3"
21652   [(set (match_operand:V8QI 0 "register_operand" "=y")
21653         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21654                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21655   "TARGET_MMX"
21656   "pcmpgtb\t{%2, %0|%0, %2}"
21657   [(set_attr "type" "mmxcmp")
21658    (set_attr "mode" "DI")])
21659
21660 (define_insn "gtv4hi3"
21661   [(set (match_operand:V4HI 0 "register_operand" "=y")
21662         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21663                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21664   "TARGET_MMX"
21665   "pcmpgtw\t{%2, %0|%0, %2}"
21666   [(set_attr "type" "mmxcmp")
21667    (set_attr "mode" "DI")])
21668
21669 (define_insn "gtv2si3"
21670   [(set (match_operand:V2SI 0 "register_operand" "=y")
21671         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21672                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21673   "TARGET_MMX"
21674   "pcmpgtd\t{%2, %0|%0, %2}"
21675   [(set_attr "type" "mmxcmp")
21676    (set_attr "mode" "DI")])
21677
21678
21679 ;; MMX max/min insns
21680
21681 (define_insn "umaxv8qi3"
21682   [(set (match_operand:V8QI 0 "register_operand" "=y")
21683         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21684                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21685   "TARGET_SSE || TARGET_3DNOW_A"
21686   "pmaxub\t{%2, %0|%0, %2}"
21687   [(set_attr "type" "mmxadd")
21688    (set_attr "mode" "DI")])
21689
21690 (define_insn "smaxv4hi3"
21691   [(set (match_operand:V4HI 0 "register_operand" "=y")
21692         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21693                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21694   "TARGET_SSE || TARGET_3DNOW_A"
21695   "pmaxsw\t{%2, %0|%0, %2}"
21696   [(set_attr "type" "mmxadd")
21697    (set_attr "mode" "DI")])
21698
21699 (define_insn "uminv8qi3"
21700   [(set (match_operand:V8QI 0 "register_operand" "=y")
21701         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21702                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21703   "TARGET_SSE || TARGET_3DNOW_A"
21704   "pminub\t{%2, %0|%0, %2}"
21705   [(set_attr "type" "mmxadd")
21706    (set_attr "mode" "DI")])
21707
21708 (define_insn "sminv4hi3"
21709   [(set (match_operand:V4HI 0 "register_operand" "=y")
21710         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21711                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21712   "TARGET_SSE || TARGET_3DNOW_A"
21713   "pminsw\t{%2, %0|%0, %2}"
21714   [(set_attr "type" "mmxadd")
21715    (set_attr "mode" "DI")])
21716
21717
21718 ;; MMX shifts
21719
21720 (define_insn "ashrv4hi3"
21721   [(set (match_operand:V4HI 0 "register_operand" "=y")
21722         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21723                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21724   "TARGET_MMX"
21725   "psraw\t{%2, %0|%0, %2}"
21726   [(set_attr "type" "mmxshft")
21727    (set_attr "mode" "DI")])
21728
21729 (define_insn "ashrv2si3"
21730   [(set (match_operand:V2SI 0 "register_operand" "=y")
21731         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21732                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21733   "TARGET_MMX"
21734   "psrad\t{%2, %0|%0, %2}"
21735   [(set_attr "type" "mmxshft")
21736    (set_attr "mode" "DI")])
21737
21738 (define_insn "lshrv4hi3"
21739   [(set (match_operand:V4HI 0 "register_operand" "=y")
21740         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21741                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21742   "TARGET_MMX"
21743   "psrlw\t{%2, %0|%0, %2}"
21744   [(set_attr "type" "mmxshft")
21745    (set_attr "mode" "DI")])
21746
21747 (define_insn "lshrv2si3"
21748   [(set (match_operand:V2SI 0 "register_operand" "=y")
21749         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21750                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21751   "TARGET_MMX"
21752   "psrld\t{%2, %0|%0, %2}"
21753   [(set_attr "type" "mmxshft")
21754    (set_attr "mode" "DI")])
21755
21756 ;; See logical MMX insns.
21757 (define_insn "mmx_lshrdi3"
21758   [(set (match_operand:DI 0 "register_operand" "=y")
21759         (unspec:DI
21760           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21761                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21762           UNSPEC_NOP))]
21763   "TARGET_MMX"
21764   "psrlq\t{%2, %0|%0, %2}"
21765   [(set_attr "type" "mmxshft")
21766    (set_attr "mode" "DI")])
21767
21768 (define_insn "ashlv4hi3"
21769   [(set (match_operand:V4HI 0 "register_operand" "=y")
21770         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21771                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21772   "TARGET_MMX"
21773   "psllw\t{%2, %0|%0, %2}"
21774   [(set_attr "type" "mmxshft")
21775    (set_attr "mode" "DI")])
21776
21777 (define_insn "ashlv2si3"
21778   [(set (match_operand:V2SI 0 "register_operand" "=y")
21779         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21780                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21781   "TARGET_MMX"
21782   "pslld\t{%2, %0|%0, %2}"
21783   [(set_attr "type" "mmxshft")
21784    (set_attr "mode" "DI")])
21785
21786 ;; See logical MMX insns.
21787 (define_insn "mmx_ashldi3"
21788   [(set (match_operand:DI 0 "register_operand" "=y")
21789         (unspec:DI
21790          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21791                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21792          UNSPEC_NOP))]
21793   "TARGET_MMX"
21794   "psllq\t{%2, %0|%0, %2}"
21795   [(set_attr "type" "mmxshft")
21796    (set_attr "mode" "DI")])
21797
21798
21799 ;; MMX pack/unpack insns.
21800
21801 (define_insn "mmx_packsswb"
21802   [(set (match_operand:V8QI 0 "register_operand" "=y")
21803         (vec_concat:V8QI
21804          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21805          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21806   "TARGET_MMX"
21807   "packsswb\t{%2, %0|%0, %2}"
21808   [(set_attr "type" "mmxshft")
21809    (set_attr "mode" "DI")])
21810
21811 (define_insn "mmx_packssdw"
21812   [(set (match_operand:V4HI 0 "register_operand" "=y")
21813         (vec_concat:V4HI
21814          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21815          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21816   "TARGET_MMX"
21817   "packssdw\t{%2, %0|%0, %2}"
21818   [(set_attr "type" "mmxshft")
21819    (set_attr "mode" "DI")])
21820
21821 (define_insn "mmx_packuswb"
21822   [(set (match_operand:V8QI 0 "register_operand" "=y")
21823         (vec_concat:V8QI
21824          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21825          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21826   "TARGET_MMX"
21827   "packuswb\t{%2, %0|%0, %2}"
21828   [(set_attr "type" "mmxshft")
21829    (set_attr "mode" "DI")])
21830
21831 (define_insn "mmx_punpckhbw"
21832   [(set (match_operand:V8QI 0 "register_operand" "=y")
21833         (vec_merge:V8QI
21834          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21835                           (parallel [(const_int 4)
21836                                      (const_int 0)
21837                                      (const_int 5)
21838                                      (const_int 1)
21839                                      (const_int 6)
21840                                      (const_int 2)
21841                                      (const_int 7)
21842                                      (const_int 3)]))
21843          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21844                           (parallel [(const_int 0)
21845                                      (const_int 4)
21846                                      (const_int 1)
21847                                      (const_int 5)
21848                                      (const_int 2)
21849                                      (const_int 6)
21850                                      (const_int 3)
21851                                      (const_int 7)]))
21852          (const_int 85)))]
21853   "TARGET_MMX"
21854   "punpckhbw\t{%2, %0|%0, %2}"
21855   [(set_attr "type" "mmxcvt")
21856    (set_attr "mode" "DI")])
21857
21858 (define_insn "mmx_punpckhwd"
21859   [(set (match_operand:V4HI 0 "register_operand" "=y")
21860         (vec_merge:V4HI
21861          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21862                           (parallel [(const_int 0)
21863                                      (const_int 2)
21864                                      (const_int 1)
21865                                      (const_int 3)]))
21866          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21867                           (parallel [(const_int 2)
21868                                      (const_int 0)
21869                                      (const_int 3)
21870                                      (const_int 1)]))
21871          (const_int 5)))]
21872   "TARGET_MMX"
21873   "punpckhwd\t{%2, %0|%0, %2}"
21874   [(set_attr "type" "mmxcvt")
21875    (set_attr "mode" "DI")])
21876
21877 (define_insn "mmx_punpckhdq"
21878   [(set (match_operand:V2SI 0 "register_operand" "=y")
21879         (vec_merge:V2SI
21880          (match_operand:V2SI 1 "register_operand" "0")
21881          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21882                           (parallel [(const_int 1)
21883                                      (const_int 0)]))
21884          (const_int 1)))]
21885   "TARGET_MMX"
21886   "punpckhdq\t{%2, %0|%0, %2}"
21887   [(set_attr "type" "mmxcvt")
21888    (set_attr "mode" "DI")])
21889
21890 (define_insn "mmx_punpcklbw"
21891   [(set (match_operand:V8QI 0 "register_operand" "=y")
21892         (vec_merge:V8QI
21893          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21894                           (parallel [(const_int 0)
21895                                      (const_int 4)
21896                                      (const_int 1)
21897                                      (const_int 5)
21898                                      (const_int 2)
21899                                      (const_int 6)
21900                                      (const_int 3)
21901                                      (const_int 7)]))
21902          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21903                           (parallel [(const_int 4)
21904                                      (const_int 0)
21905                                      (const_int 5)
21906                                      (const_int 1)
21907                                      (const_int 6)
21908                                      (const_int 2)
21909                                      (const_int 7)
21910                                      (const_int 3)]))
21911          (const_int 85)))]
21912   "TARGET_MMX"
21913   "punpcklbw\t{%2, %0|%0, %2}"
21914   [(set_attr "type" "mmxcvt")
21915    (set_attr "mode" "DI")])
21916
21917 (define_insn "mmx_punpcklwd"
21918   [(set (match_operand:V4HI 0 "register_operand" "=y")
21919         (vec_merge:V4HI
21920          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21921                           (parallel [(const_int 2)
21922                                      (const_int 0)
21923                                      (const_int 3)
21924                                      (const_int 1)]))
21925          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21926                           (parallel [(const_int 0)
21927                                      (const_int 2)
21928                                      (const_int 1)
21929                                      (const_int 3)]))
21930          (const_int 5)))]
21931   "TARGET_MMX"
21932   "punpcklwd\t{%2, %0|%0, %2}"
21933   [(set_attr "type" "mmxcvt")
21934    (set_attr "mode" "DI")])
21935
21936 (define_insn "mmx_punpckldq"
21937   [(set (match_operand:V2SI 0 "register_operand" "=y")
21938         (vec_merge:V2SI
21939          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21940                            (parallel [(const_int 1)
21941                                       (const_int 0)]))
21942          (match_operand:V2SI 2 "register_operand" "y")
21943          (const_int 1)))]
21944   "TARGET_MMX"
21945   "punpckldq\t{%2, %0|%0, %2}"
21946   [(set_attr "type" "mmxcvt")
21947    (set_attr "mode" "DI")])
21948
21949
21950 ;; Miscellaneous stuff
21951
21952 (define_insn "emms"
21953   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21954    (clobber (reg:XF 8))
21955    (clobber (reg:XF 9))
21956    (clobber (reg:XF 10))
21957    (clobber (reg:XF 11))
21958    (clobber (reg:XF 12))
21959    (clobber (reg:XF 13))
21960    (clobber (reg:XF 14))
21961    (clobber (reg:XF 15))
21962    (clobber (reg:DI 29))
21963    (clobber (reg:DI 30))
21964    (clobber (reg:DI 31))
21965    (clobber (reg:DI 32))
21966    (clobber (reg:DI 33))
21967    (clobber (reg:DI 34))
21968    (clobber (reg:DI 35))
21969    (clobber (reg:DI 36))]
21970   "TARGET_MMX"
21971   "emms"
21972   [(set_attr "type" "mmx")
21973    (set_attr "memory" "unknown")])
21974
21975 (define_insn "ldmxcsr"
21976   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21977                     UNSPECV_LDMXCSR)]
21978   "TARGET_SSE"
21979   "ldmxcsr\t%0"
21980   [(set_attr "type" "sse")
21981    (set_attr "memory" "load")])
21982
21983 (define_insn "stmxcsr"
21984   [(set (match_operand:SI 0 "memory_operand" "=m")
21985         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21986   "TARGET_SSE"
21987   "stmxcsr\t%0"
21988   [(set_attr "type" "sse")
21989    (set_attr "memory" "store")])
21990
21991 (define_expand "sfence"
21992   [(set (match_dup 0)
21993         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21994   "TARGET_SSE || TARGET_3DNOW_A"
21995 {
21996   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21997   MEM_VOLATILE_P (operands[0]) = 1;
21998 })
21999
22000 (define_insn "*sfence_insn"
22001   [(set (match_operand:BLK 0 "" "")
22002         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22003   "TARGET_SSE || TARGET_3DNOW_A"
22004   "sfence"
22005   [(set_attr "type" "sse")
22006    (set_attr "memory" "unknown")])
22007
22008 (define_expand "sse_prologue_save"
22009   [(parallel [(set (match_operand:BLK 0 "" "")
22010                    (unspec:BLK [(reg:DI 21)
22011                                 (reg:DI 22)
22012                                 (reg:DI 23)
22013                                 (reg:DI 24)
22014                                 (reg:DI 25)
22015                                 (reg:DI 26)
22016                                 (reg:DI 27)
22017                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22018               (use (match_operand:DI 1 "register_operand" ""))
22019               (use (match_operand:DI 2 "immediate_operand" ""))
22020               (use (label_ref:DI (match_operand 3 "" "")))])]
22021   "TARGET_64BIT"
22022   "")
22023
22024 (define_insn "*sse_prologue_save_insn"
22025   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22026                           (match_operand:DI 4 "const_int_operand" "n")))
22027         (unspec:BLK [(reg:DI 21)
22028                      (reg:DI 22)
22029                      (reg:DI 23)
22030                      (reg:DI 24)
22031                      (reg:DI 25)
22032                      (reg:DI 26)
22033                      (reg:DI 27)
22034                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22035    (use (match_operand:DI 1 "register_operand" "r"))
22036    (use (match_operand:DI 2 "const_int_operand" "i"))
22037    (use (label_ref:DI (match_operand 3 "" "X")))]
22038   "TARGET_64BIT
22039    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22040    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22041   "*
22042 {
22043   int i;
22044   operands[0] = gen_rtx_MEM (Pmode,
22045                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22046   output_asm_insn (\"jmp\\t%A1\", operands);
22047   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22048     {
22049       operands[4] = adjust_address (operands[0], DImode, i*16);
22050       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22051       PUT_MODE (operands[4], TImode);
22052       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22053         output_asm_insn (\"rex\", operands);
22054       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22055     }
22056   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22057                              CODE_LABEL_NUMBER (operands[3]));
22058   RET;
22059 }
22060   "
22061   [(set_attr "type" "other")
22062    (set_attr "length_immediate" "0")
22063    (set_attr "length_address" "0")
22064    (set_attr "length" "135")
22065    (set_attr "memory" "store")
22066    (set_attr "modrm" "0")
22067    (set_attr "mode" "DI")])
22068
22069 ;; 3Dnow! instructions
22070
22071 (define_insn "addv2sf3"
22072   [(set (match_operand:V2SF 0 "register_operand" "=y")
22073         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22074                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22075   "TARGET_3DNOW"
22076   "pfadd\\t{%2, %0|%0, %2}"
22077   [(set_attr "type" "mmxadd")
22078    (set_attr "mode" "V2SF")])
22079
22080 (define_insn "subv2sf3"
22081   [(set (match_operand:V2SF 0 "register_operand" "=y")
22082         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22083                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22084   "TARGET_3DNOW"
22085   "pfsub\\t{%2, %0|%0, %2}"
22086   [(set_attr "type" "mmxadd")
22087    (set_attr "mode" "V2SF")])
22088
22089 (define_insn "subrv2sf3"
22090   [(set (match_operand:V2SF 0 "register_operand" "=y")
22091         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22092                     (match_operand:V2SF 1 "register_operand" "0")))]
22093   "TARGET_3DNOW"
22094   "pfsubr\\t{%2, %0|%0, %2}"
22095   [(set_attr "type" "mmxadd")
22096    (set_attr "mode" "V2SF")])
22097
22098 (define_insn "gtv2sf3"
22099   [(set (match_operand:V2SI 0 "register_operand" "=y")
22100         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22101                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22102  "TARGET_3DNOW"
22103   "pfcmpgt\\t{%2, %0|%0, %2}"
22104   [(set_attr "type" "mmxcmp")
22105    (set_attr "mode" "V2SF")])
22106
22107 (define_insn "gev2sf3"
22108   [(set (match_operand:V2SI 0 "register_operand" "=y")
22109         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22110                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22111   "TARGET_3DNOW"
22112   "pfcmpge\\t{%2, %0|%0, %2}"
22113   [(set_attr "type" "mmxcmp")
22114    (set_attr "mode" "V2SF")])
22115
22116 (define_insn "eqv2sf3"
22117   [(set (match_operand:V2SI 0 "register_operand" "=y")
22118         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22119                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22120   "TARGET_3DNOW"
22121   "pfcmpeq\\t{%2, %0|%0, %2}"
22122   [(set_attr "type" "mmxcmp")
22123    (set_attr "mode" "V2SF")])
22124
22125 (define_insn "pfmaxv2sf3"
22126   [(set (match_operand:V2SF 0 "register_operand" "=y")
22127         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22128                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22129   "TARGET_3DNOW"
22130   "pfmax\\t{%2, %0|%0, %2}"
22131   [(set_attr "type" "mmxadd")
22132    (set_attr "mode" "V2SF")])
22133
22134 (define_insn "pfminv2sf3"
22135   [(set (match_operand:V2SF 0 "register_operand" "=y")
22136         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22137                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22138   "TARGET_3DNOW"
22139   "pfmin\\t{%2, %0|%0, %2}"
22140   [(set_attr "type" "mmxadd")
22141    (set_attr "mode" "V2SF")])
22142
22143 (define_insn "mulv2sf3"
22144   [(set (match_operand:V2SF 0 "register_operand" "=y")
22145         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22146                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22147   "TARGET_3DNOW"
22148   "pfmul\\t{%2, %0|%0, %2}"
22149   [(set_attr "type" "mmxmul")
22150    (set_attr "mode" "V2SF")])
22151
22152 (define_insn "femms"
22153   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22154    (clobber (reg:XF 8))
22155    (clobber (reg:XF 9))
22156    (clobber (reg:XF 10))
22157    (clobber (reg:XF 11))
22158    (clobber (reg:XF 12))
22159    (clobber (reg:XF 13))
22160    (clobber (reg:XF 14))
22161    (clobber (reg:XF 15))
22162    (clobber (reg:DI 29))
22163    (clobber (reg:DI 30))
22164    (clobber (reg:DI 31))
22165    (clobber (reg:DI 32))
22166    (clobber (reg:DI 33))
22167    (clobber (reg:DI 34))
22168    (clobber (reg:DI 35))
22169    (clobber (reg:DI 36))]
22170   "TARGET_3DNOW"
22171   "femms"
22172   [(set_attr "type" "mmx")
22173    (set_attr "memory" "none")]) 
22174
22175 (define_insn "pf2id"
22176   [(set (match_operand:V2SI 0 "register_operand" "=y")
22177         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22178   "TARGET_3DNOW"
22179   "pf2id\\t{%1, %0|%0, %1}"
22180   [(set_attr "type" "mmxcvt")
22181    (set_attr "mode" "V2SF")])
22182
22183 (define_insn "pf2iw"
22184   [(set (match_operand:V2SI 0 "register_operand" "=y")
22185         (sign_extend:V2SI
22186            (ss_truncate:V2HI
22187               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22188   "TARGET_3DNOW_A"
22189   "pf2iw\\t{%1, %0|%0, %1}"
22190   [(set_attr "type" "mmxcvt")
22191    (set_attr "mode" "V2SF")])
22192
22193 (define_insn "pfacc"
22194   [(set (match_operand:V2SF 0 "register_operand" "=y")
22195         (vec_concat:V2SF
22196            (plus:SF
22197               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22198                              (parallel [(const_int  0)]))
22199               (vec_select:SF (match_dup 1)
22200                              (parallel [(const_int 1)])))
22201            (plus:SF
22202               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22203                              (parallel [(const_int  0)]))
22204               (vec_select:SF (match_dup 2)
22205                              (parallel [(const_int 1)])))))]
22206   "TARGET_3DNOW"
22207   "pfacc\\t{%2, %0|%0, %2}"
22208   [(set_attr "type" "mmxadd")
22209    (set_attr "mode" "V2SF")])
22210
22211 (define_insn "pfnacc"
22212   [(set (match_operand:V2SF 0 "register_operand" "=y")
22213         (vec_concat:V2SF
22214            (minus:SF
22215               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22216                              (parallel [(const_int 0)]))
22217               (vec_select:SF (match_dup 1)
22218                              (parallel [(const_int 1)])))
22219            (minus:SF
22220               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22221                              (parallel [(const_int  0)]))
22222               (vec_select:SF (match_dup 2)
22223                              (parallel [(const_int 1)])))))]
22224   "TARGET_3DNOW_A"
22225   "pfnacc\\t{%2, %0|%0, %2}"
22226   [(set_attr "type" "mmxadd")
22227    (set_attr "mode" "V2SF")])
22228
22229 (define_insn "pfpnacc"
22230   [(set (match_operand:V2SF 0 "register_operand" "=y")
22231         (vec_concat:V2SF
22232            (minus:SF
22233               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22234                              (parallel [(const_int 0)]))
22235               (vec_select:SF (match_dup 1)
22236                              (parallel [(const_int 1)])))
22237            (plus:SF
22238               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22239                              (parallel [(const_int 0)]))
22240               (vec_select:SF (match_dup 2)
22241                              (parallel [(const_int 1)])))))]
22242   "TARGET_3DNOW_A"
22243   "pfpnacc\\t{%2, %0|%0, %2}"
22244   [(set_attr "type" "mmxadd")
22245    (set_attr "mode" "V2SF")])
22246
22247 (define_insn "pi2fw"
22248   [(set (match_operand:V2SF 0 "register_operand" "=y")
22249         (float:V2SF
22250            (vec_concat:V2SI
22251               (sign_extend:SI
22252                  (truncate:HI
22253                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22254                                    (parallel [(const_int 0)]))))
22255               (sign_extend:SI
22256                  (truncate:HI
22257                     (vec_select:SI (match_dup 1)
22258                                    (parallel [(const_int  1)])))))))]
22259   "TARGET_3DNOW_A"
22260   "pi2fw\\t{%1, %0|%0, %1}"
22261   [(set_attr "type" "mmxcvt")
22262    (set_attr "mode" "V2SF")])
22263
22264 (define_insn "floatv2si2"
22265   [(set (match_operand:V2SF 0 "register_operand" "=y")
22266         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22267   "TARGET_3DNOW"
22268   "pi2fd\\t{%1, %0|%0, %1}"
22269   [(set_attr "type" "mmxcvt")
22270    (set_attr "mode" "V2SF")])
22271
22272 ;; This insn is identical to pavgb in operation, but the opcode is
22273 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22274
22275 (define_insn "pavgusb"
22276  [(set (match_operand:V8QI 0 "register_operand" "=y")
22277        (unspec:V8QI
22278           [(match_operand:V8QI 1 "register_operand" "0")
22279            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22280           UNSPEC_PAVGUSB))]
22281   "TARGET_3DNOW"
22282   "pavgusb\\t{%2, %0|%0, %2}"
22283   [(set_attr "type" "mmxshft")
22284    (set_attr "mode" "TI")])
22285
22286 ;; 3DNow reciprocal and sqrt
22287  
22288 (define_insn "pfrcpv2sf2"
22289   [(set (match_operand:V2SF 0 "register_operand" "=y")
22290         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22291         UNSPEC_PFRCP))]
22292   "TARGET_3DNOW"
22293   "pfrcp\\t{%1, %0|%0, %1}"
22294   [(set_attr "type" "mmx")
22295    (set_attr "mode" "TI")])
22296
22297 (define_insn "pfrcpit1v2sf3"
22298   [(set (match_operand:V2SF 0 "register_operand" "=y")
22299         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22300                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22301                      UNSPEC_PFRCPIT1))]
22302   "TARGET_3DNOW"
22303   "pfrcpit1\\t{%2, %0|%0, %2}"
22304   [(set_attr "type" "mmx")
22305    (set_attr "mode" "TI")])
22306
22307 (define_insn "pfrcpit2v2sf3"
22308   [(set (match_operand:V2SF 0 "register_operand" "=y")
22309         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22310                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22311                      UNSPEC_PFRCPIT2))]
22312   "TARGET_3DNOW"
22313   "pfrcpit2\\t{%2, %0|%0, %2}"
22314   [(set_attr "type" "mmx")
22315    (set_attr "mode" "TI")])
22316
22317 (define_insn "pfrsqrtv2sf2"
22318   [(set (match_operand:V2SF 0 "register_operand" "=y")
22319         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22320                      UNSPEC_PFRSQRT))]
22321   "TARGET_3DNOW"
22322   "pfrsqrt\\t{%1, %0|%0, %1}"
22323   [(set_attr "type" "mmx")
22324    (set_attr "mode" "TI")])
22325                 
22326 (define_insn "pfrsqit1v2sf3"
22327   [(set (match_operand:V2SF 0 "register_operand" "=y")
22328         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22329                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22330                      UNSPEC_PFRSQIT1))]
22331   "TARGET_3DNOW"
22332   "pfrsqit1\\t{%2, %0|%0, %2}"
22333   [(set_attr "type" "mmx")
22334    (set_attr "mode" "TI")])
22335
22336 (define_insn "pmulhrwv4hi3"
22337   [(set (match_operand:V4HI 0 "register_operand" "=y")
22338         (truncate:V4HI
22339            (lshiftrt:V4SI
22340               (plus:V4SI
22341                  (mult:V4SI
22342                     (sign_extend:V4SI
22343                        (match_operand:V4HI 1 "register_operand" "0"))
22344                     (sign_extend:V4SI
22345                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22346                  (const_vector:V4SI [(const_int 32768)
22347                                      (const_int 32768)
22348                                      (const_int 32768)
22349                                      (const_int 32768)]))
22350               (const_int 16))))]
22351   "TARGET_3DNOW"
22352   "pmulhrw\\t{%2, %0|%0, %2}"
22353   [(set_attr "type" "mmxmul")
22354    (set_attr "mode" "TI")])
22355
22356 (define_insn "pswapdv2si2"
22357   [(set (match_operand:V2SI 0 "register_operand" "=y")
22358         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22359                          (parallel [(const_int 1) (const_int 0)])))]
22360   "TARGET_3DNOW_A"
22361   "pswapd\\t{%1, %0|%0, %1}"
22362   [(set_attr "type" "mmxcvt")
22363    (set_attr "mode" "TI")])
22364
22365 (define_insn "pswapdv2sf2"
22366   [(set (match_operand:V2SF 0 "register_operand" "=y")
22367         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22368                          (parallel [(const_int 1) (const_int 0)])))]
22369   "TARGET_3DNOW_A"
22370   "pswapd\\t{%1, %0|%0, %1}"
22371   [(set_attr "type" "mmxcvt")
22372    (set_attr "mode" "TI")])
22373
22374 (define_expand "prefetch"
22375   [(prefetch (match_operand 0 "address_operand" "")
22376              (match_operand:SI 1 "const_int_operand" "")
22377              (match_operand:SI 2 "const_int_operand" ""))]
22378   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22379 {
22380   int rw = INTVAL (operands[1]);
22381   int locality = INTVAL (operands[2]);
22382
22383   if (rw != 0 && rw != 1)
22384     abort ();
22385   if (locality < 0 || locality > 3)
22386     abort ();
22387   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22388     abort ();
22389
22390   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22391      suported by SSE counterpart or the SSE prefetch is not available
22392      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22393      of locality.  */
22394   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22395     operands[2] = GEN_INT (3);
22396   else
22397     operands[1] = const0_rtx;
22398 })
22399
22400 (define_insn "*prefetch_sse"
22401   [(prefetch (match_operand:SI 0 "address_operand" "p")
22402              (const_int 0)
22403              (match_operand:SI 1 "const_int_operand" ""))]
22404   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22405 {
22406   static const char * const patterns[4] = {
22407    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22408   };
22409
22410   int locality = INTVAL (operands[1]);
22411   if (locality < 0 || locality > 3)
22412     abort ();
22413
22414   return patterns[locality];  
22415 }
22416   [(set_attr "type" "sse")
22417    (set_attr "memory" "none")])
22418
22419 (define_insn "*prefetch_sse_rex"
22420   [(prefetch (match_operand:DI 0 "address_operand" "p")
22421              (const_int 0)
22422              (match_operand:SI 1 "const_int_operand" ""))]
22423   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22424 {
22425   static const char * const patterns[4] = {
22426    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22427   };
22428
22429   int locality = INTVAL (operands[1]);
22430   if (locality < 0 || locality > 3)
22431     abort ();
22432
22433   return patterns[locality];  
22434 }
22435   [(set_attr "type" "sse")
22436    (set_attr "memory" "none")])
22437
22438 (define_insn "*prefetch_3dnow"
22439   [(prefetch (match_operand:SI 0 "address_operand" "p")
22440              (match_operand:SI 1 "const_int_operand" "n")
22441              (const_int 3))]
22442   "TARGET_3DNOW && !TARGET_64BIT"
22443 {
22444   if (INTVAL (operands[1]) == 0)
22445     return "prefetch\t%a0";
22446   else
22447     return "prefetchw\t%a0";
22448 }
22449   [(set_attr "type" "mmx")
22450    (set_attr "memory" "none")])
22451
22452 (define_insn "*prefetch_3dnow_rex"
22453   [(prefetch (match_operand:DI 0 "address_operand" "p")
22454              (match_operand:SI 1 "const_int_operand" "n")
22455              (const_int 3))]
22456   "TARGET_3DNOW && TARGET_64BIT"
22457 {
22458   if (INTVAL (operands[1]) == 0)
22459     return "prefetch\t%a0";
22460   else
22461     return "prefetchw\t%a0";
22462 }
22463   [(set_attr "type" "mmx")
22464    (set_attr "memory" "none")])
22465
22466 ;; SSE2 support
22467
22468 (define_insn "addv2df3"
22469   [(set (match_operand:V2DF 0 "register_operand" "=x")
22470         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22471                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22472   "TARGET_SSE2"
22473   "addpd\t{%2, %0|%0, %2}"
22474   [(set_attr "type" "sseadd")
22475    (set_attr "mode" "V2DF")])
22476
22477 (define_insn "vmaddv2df3"
22478   [(set (match_operand:V2DF 0 "register_operand" "=x")
22479         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22480                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22481                         (match_dup 1)
22482                         (const_int 1)))]
22483   "TARGET_SSE2"
22484   "addsd\t{%2, %0|%0, %2}"
22485   [(set_attr "type" "sseadd")
22486    (set_attr "mode" "DF")])
22487
22488 (define_insn "subv2df3"
22489   [(set (match_operand:V2DF 0 "register_operand" "=x")
22490         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22491                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22492   "TARGET_SSE2"
22493   "subpd\t{%2, %0|%0, %2}"
22494   [(set_attr "type" "sseadd")
22495    (set_attr "mode" "V2DF")])
22496
22497 (define_insn "vmsubv2df3"
22498   [(set (match_operand:V2DF 0 "register_operand" "=x")
22499         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22500                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22501                         (match_dup 1)
22502                         (const_int 1)))]
22503   "TARGET_SSE2"
22504   "subsd\t{%2, %0|%0, %2}"
22505   [(set_attr "type" "sseadd")
22506    (set_attr "mode" "DF")])
22507
22508 (define_insn "mulv2df3"
22509   [(set (match_operand:V2DF 0 "register_operand" "=x")
22510         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22511                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22512   "TARGET_SSE2"
22513   "mulpd\t{%2, %0|%0, %2}"
22514   [(set_attr "type" "ssemul")
22515    (set_attr "mode" "V2DF")])
22516
22517 (define_insn "vmmulv2df3"
22518   [(set (match_operand:V2DF 0 "register_operand" "=x")
22519         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22520                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22521                         (match_dup 1)
22522                         (const_int 1)))]
22523   "TARGET_SSE2"
22524   "mulsd\t{%2, %0|%0, %2}"
22525   [(set_attr "type" "ssemul")
22526    (set_attr "mode" "DF")])
22527
22528 (define_insn "divv2df3"
22529   [(set (match_operand:V2DF 0 "register_operand" "=x")
22530         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22531                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22532   "TARGET_SSE2"
22533   "divpd\t{%2, %0|%0, %2}"
22534   [(set_attr "type" "ssediv")
22535    (set_attr "mode" "V2DF")])
22536
22537 (define_insn "vmdivv2df3"
22538   [(set (match_operand:V2DF 0 "register_operand" "=x")
22539         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22540                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22541                         (match_dup 1)
22542                         (const_int 1)))]
22543   "TARGET_SSE2"
22544   "divsd\t{%2, %0|%0, %2}"
22545   [(set_attr "type" "ssediv")
22546    (set_attr "mode" "DF")])
22547
22548 ;; SSE min/max
22549
22550 (define_insn "smaxv2df3"
22551   [(set (match_operand:V2DF 0 "register_operand" "=x")
22552         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22553                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22554   "TARGET_SSE2"
22555   "maxpd\t{%2, %0|%0, %2}"
22556   [(set_attr "type" "sseadd")
22557    (set_attr "mode" "V2DF")])
22558
22559 (define_insn "vmsmaxv2df3"
22560   [(set (match_operand:V2DF 0 "register_operand" "=x")
22561         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22562                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22563                         (match_dup 1)
22564                         (const_int 1)))]
22565   "TARGET_SSE2"
22566   "maxsd\t{%2, %0|%0, %2}"
22567   [(set_attr "type" "sseadd")
22568    (set_attr "mode" "DF")])
22569
22570 (define_insn "sminv2df3"
22571   [(set (match_operand:V2DF 0 "register_operand" "=x")
22572         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22573                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22574   "TARGET_SSE2"
22575   "minpd\t{%2, %0|%0, %2}"
22576   [(set_attr "type" "sseadd")
22577    (set_attr "mode" "V2DF")])
22578
22579 (define_insn "vmsminv2df3"
22580   [(set (match_operand:V2DF 0 "register_operand" "=x")
22581         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22582                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22583                         (match_dup 1)
22584                         (const_int 1)))]
22585   "TARGET_SSE2"
22586   "minsd\t{%2, %0|%0, %2}"
22587   [(set_attr "type" "sseadd")
22588    (set_attr "mode" "DF")])
22589 ;; SSE2 square root.  There doesn't appear to be an extension for the
22590 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22591
22592 (define_insn "sqrtv2df2"
22593   [(set (match_operand:V2DF 0 "register_operand" "=x")
22594         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22595   "TARGET_SSE2"
22596   "sqrtpd\t{%1, %0|%0, %1}"
22597   [(set_attr "type" "sse")
22598    (set_attr "mode" "V2DF")])
22599
22600 (define_insn "vmsqrtv2df2"
22601   [(set (match_operand:V2DF 0 "register_operand" "=x")
22602         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22603                         (match_operand:V2DF 2 "register_operand" "0")
22604                         (const_int 1)))]
22605   "TARGET_SSE2"
22606   "sqrtsd\t{%1, %0|%0, %1}"
22607   [(set_attr "type" "sse")
22608    (set_attr "mode" "SF")])
22609
22610 ;; SSE mask-generating compares
22611
22612 (define_insn "maskcmpv2df3"
22613   [(set (match_operand:V2DI 0 "register_operand" "=x")
22614         (match_operator:V2DI 3 "sse_comparison_operator"
22615                              [(match_operand:V2DF 1 "register_operand" "0")
22616                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22617   "TARGET_SSE2"
22618   "cmp%D3pd\t{%2, %0|%0, %2}"
22619   [(set_attr "type" "ssecmp")
22620    (set_attr "mode" "V2DF")])
22621
22622 (define_insn "maskncmpv2df3"
22623   [(set (match_operand:V2DI 0 "register_operand" "=x")
22624         (not:V2DI
22625          (match_operator:V2DI 3 "sse_comparison_operator"
22626                               [(match_operand:V2DF 1 "register_operand" "0")
22627                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22628   "TARGET_SSE2"
22629 {
22630   if (GET_CODE (operands[3]) == UNORDERED)
22631     return "cmpordps\t{%2, %0|%0, %2}";
22632   else
22633     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22634 }
22635   [(set_attr "type" "ssecmp")
22636    (set_attr "mode" "V2DF")])
22637
22638 (define_insn "vmmaskcmpv2df3"
22639   [(set (match_operand:V2DI 0 "register_operand" "=x")
22640         (vec_merge:V2DI
22641          (match_operator:V2DI 3 "sse_comparison_operator"
22642                               [(match_operand:V2DF 1 "register_operand" "0")
22643                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22644          (subreg:V2DI (match_dup 1) 0)
22645          (const_int 1)))]
22646   "TARGET_SSE2"
22647   "cmp%D3sd\t{%2, %0|%0, %2}"
22648   [(set_attr "type" "ssecmp")
22649    (set_attr "mode" "DF")])
22650
22651 (define_insn "vmmaskncmpv2df3"
22652   [(set (match_operand:V2DI 0 "register_operand" "=x")
22653         (vec_merge:V2DI
22654          (not:V2DI
22655           (match_operator:V2DI 3 "sse_comparison_operator"
22656                                [(match_operand:V2DF 1 "register_operand" "0")
22657                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22658          (subreg:V2DI (match_dup 1) 0)
22659          (const_int 1)))]
22660   "TARGET_SSE2"
22661 {
22662   if (GET_CODE (operands[3]) == UNORDERED)
22663     return "cmpordsd\t{%2, %0|%0, %2}";
22664   else
22665     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22666 }
22667   [(set_attr "type" "ssecmp")
22668    (set_attr "mode" "DF")])
22669
22670 (define_insn "sse2_comi"
22671   [(set (reg:CCFP FLAGS_REG)
22672         (compare:CCFP (vec_select:DF
22673                        (match_operand:V2DF 0 "register_operand" "x")
22674                        (parallel [(const_int 0)]))
22675                       (vec_select:DF
22676                        (match_operand:V2DF 1 "register_operand" "x")
22677                        (parallel [(const_int 0)]))))]
22678   "TARGET_SSE2"
22679   "comisd\t{%1, %0|%0, %1}"
22680   [(set_attr "type" "ssecomi")
22681    (set_attr "mode" "DF")])
22682
22683 (define_insn "sse2_ucomi"
22684   [(set (reg:CCFPU FLAGS_REG)
22685         (compare:CCFPU (vec_select:DF
22686                          (match_operand:V2DF 0 "register_operand" "x")
22687                          (parallel [(const_int 0)]))
22688                         (vec_select:DF
22689                          (match_operand:V2DF 1 "register_operand" "x")
22690                          (parallel [(const_int 0)]))))]
22691   "TARGET_SSE2"
22692   "ucomisd\t{%1, %0|%0, %1}"
22693   [(set_attr "type" "ssecomi")
22694    (set_attr "mode" "DF")])
22695
22696 ;; SSE Strange Moves.
22697
22698 (define_insn "sse2_movmskpd"
22699   [(set (match_operand:SI 0 "register_operand" "=r")
22700         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22701                    UNSPEC_MOVMSK))]
22702   "TARGET_SSE2"
22703   "movmskpd\t{%1, %0|%0, %1}"
22704   [(set_attr "type" "ssecvt")
22705    (set_attr "mode" "V2DF")])
22706
22707 (define_insn "sse2_pmovmskb"
22708   [(set (match_operand:SI 0 "register_operand" "=r")
22709         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22710                    UNSPEC_MOVMSK))]
22711   "TARGET_SSE2"
22712   "pmovmskb\t{%1, %0|%0, %1}"
22713   [(set_attr "type" "ssecvt")
22714    (set_attr "mode" "V2DF")])
22715
22716 (define_insn "sse2_maskmovdqu"
22717   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22718         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22719                        (match_operand:V16QI 2 "register_operand" "x")]
22720                       UNSPEC_MASKMOV))]
22721   "TARGET_SSE2"
22722   ;; @@@ check ordering of operands in intel/nonintel syntax
22723   "maskmovdqu\t{%2, %1|%1, %2}"
22724   [(set_attr "type" "ssecvt")
22725    (set_attr "mode" "TI")])
22726
22727 (define_insn "sse2_maskmovdqu_rex64"
22728   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22729         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22730                        (match_operand:V16QI 2 "register_operand" "x")]
22731                       UNSPEC_MASKMOV))]
22732   "TARGET_SSE2"
22733   ;; @@@ check ordering of operands in intel/nonintel syntax
22734   "maskmovdqu\t{%2, %1|%1, %2}"
22735   [(set_attr "type" "ssecvt")
22736    (set_attr "mode" "TI")])
22737
22738 (define_insn "sse2_movntv2df"
22739   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22740         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22741                      UNSPEC_MOVNT))]
22742   "TARGET_SSE2"
22743   "movntpd\t{%1, %0|%0, %1}"
22744   [(set_attr "type" "ssecvt")
22745    (set_attr "mode" "V2DF")])
22746
22747 (define_insn "sse2_movntv2di"
22748   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22749         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22750                      UNSPEC_MOVNT))]
22751   "TARGET_SSE2"
22752   "movntdq\t{%1, %0|%0, %1}"
22753   [(set_attr "type" "ssecvt")
22754    (set_attr "mode" "TI")])
22755
22756 (define_insn "sse2_movntsi"
22757   [(set (match_operand:SI 0 "memory_operand" "=m")
22758         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22759                    UNSPEC_MOVNT))]
22760   "TARGET_SSE2"
22761   "movnti\t{%1, %0|%0, %1}"
22762   [(set_attr "type" "ssecvt")
22763    (set_attr "mode" "V2DF")])
22764
22765 ;; SSE <-> integer/MMX conversions
22766
22767 ;; Conversions between SI and SF
22768
22769 (define_insn "cvtdq2ps"
22770   [(set (match_operand:V4SF 0 "register_operand" "=x")
22771         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22772   "TARGET_SSE2"
22773   "cvtdq2ps\t{%1, %0|%0, %1}"
22774   [(set_attr "type" "ssecvt")
22775    (set_attr "mode" "V2DF")])
22776
22777 (define_insn "cvtps2dq"
22778   [(set (match_operand:V4SI 0 "register_operand" "=x")
22779         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22780   "TARGET_SSE2"
22781   "cvtps2dq\t{%1, %0|%0, %1}"
22782   [(set_attr "type" "ssecvt")
22783    (set_attr "mode" "TI")])
22784
22785 (define_insn "cvttps2dq"
22786   [(set (match_operand:V4SI 0 "register_operand" "=x")
22787         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22788                      UNSPEC_FIX))]
22789   "TARGET_SSE2"
22790   "cvttps2dq\t{%1, %0|%0, %1}"
22791   [(set_attr "type" "ssecvt")
22792    (set_attr "mode" "TI")])
22793
22794 ;; Conversions between SI and DF
22795
22796 (define_insn "cvtdq2pd"
22797   [(set (match_operand:V2DF 0 "register_operand" "=x")
22798         (float:V2DF (vec_select:V2SI
22799                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22800                      (parallel
22801                       [(const_int 0)
22802                        (const_int 1)]))))]
22803   "TARGET_SSE2"
22804   "cvtdq2pd\t{%1, %0|%0, %1}"
22805   [(set_attr "type" "ssecvt")
22806    (set_attr "mode" "V2DF")])
22807
22808 (define_insn "cvtpd2dq"
22809   [(set (match_operand:V4SI 0 "register_operand" "=x")
22810         (vec_concat:V4SI
22811          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22812          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22813   "TARGET_SSE2"
22814   "cvtpd2dq\t{%1, %0|%0, %1}"
22815   [(set_attr "type" "ssecvt")
22816    (set_attr "mode" "TI")])
22817
22818 (define_insn "cvttpd2dq"
22819   [(set (match_operand:V4SI 0 "register_operand" "=x")
22820         (vec_concat:V4SI
22821          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22822                       UNSPEC_FIX)
22823          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22824   "TARGET_SSE2"
22825   "cvttpd2dq\t{%1, %0|%0, %1}"
22826   [(set_attr "type" "ssecvt")
22827    (set_attr "mode" "TI")])
22828
22829 (define_insn "cvtpd2pi"
22830   [(set (match_operand:V2SI 0 "register_operand" "=y")
22831         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22832   "TARGET_SSE2"
22833   "cvtpd2pi\t{%1, %0|%0, %1}"
22834   [(set_attr "type" "ssecvt")
22835    (set_attr "mode" "TI")])
22836
22837 (define_insn "cvttpd2pi"
22838   [(set (match_operand:V2SI 0 "register_operand" "=y")
22839         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22840                      UNSPEC_FIX))]
22841   "TARGET_SSE2"
22842   "cvttpd2pi\t{%1, %0|%0, %1}"
22843   [(set_attr "type" "ssecvt")
22844    (set_attr "mode" "TI")])
22845
22846 (define_insn "cvtpi2pd"
22847   [(set (match_operand:V2DF 0 "register_operand" "=x")
22848         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22849   "TARGET_SSE2"
22850   "cvtpi2pd\t{%1, %0|%0, %1}"
22851   [(set_attr "type" "ssecvt")
22852    (set_attr "mode" "TI")])
22853
22854 ;; Conversions between SI and DF
22855
22856 (define_insn "cvtsd2si"
22857   [(set (match_operand:SI 0 "register_operand" "=r,r")
22858         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22859                                (parallel [(const_int 0)]))))]
22860   "TARGET_SSE2"
22861   "cvtsd2si\t{%1, %0|%0, %1}"
22862   [(set_attr "type" "sseicvt")
22863    (set_attr "athlon_decode" "double,vector")
22864    (set_attr "mode" "SI")])
22865
22866 (define_insn "cvtsd2siq"
22867   [(set (match_operand:DI 0 "register_operand" "=r,r")
22868         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22869                                (parallel [(const_int 0)]))))]
22870   "TARGET_SSE2 && TARGET_64BIT"
22871   "cvtsd2siq\t{%1, %0|%0, %1}"
22872   [(set_attr "type" "sseicvt")
22873    (set_attr "athlon_decode" "double,vector")
22874    (set_attr "mode" "DI")])
22875
22876 (define_insn "cvttsd2si"
22877   [(set (match_operand:SI 0 "register_operand" "=r,r")
22878         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22879                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22880   "TARGET_SSE2"
22881   "cvttsd2si\t{%1, %0|%0, %1}"
22882   [(set_attr "type" "sseicvt")
22883    (set_attr "mode" "SI")
22884    (set_attr "athlon_decode" "double,vector")])
22885
22886 (define_insn "cvttsd2siq"
22887   [(set (match_operand:DI 0 "register_operand" "=r,r")
22888         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22889                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22890   "TARGET_SSE2 && TARGET_64BIT"
22891   "cvttsd2siq\t{%1, %0|%0, %1}"
22892   [(set_attr "type" "sseicvt")
22893    (set_attr "mode" "DI")
22894    (set_attr "athlon_decode" "double,vector")])
22895
22896 (define_insn "cvtsi2sd"
22897   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22898         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22899                         (vec_duplicate:V2DF
22900                           (float:DF
22901                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22902                         (const_int 2)))]
22903   "TARGET_SSE2"
22904   "cvtsi2sd\t{%2, %0|%0, %2}"
22905   [(set_attr "type" "sseicvt")
22906    (set_attr "mode" "DF")
22907    (set_attr "athlon_decode" "double,direct")])
22908
22909 (define_insn "cvtsi2sdq"
22910   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22911         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22912                         (vec_duplicate:V2DF
22913                           (float:DF
22914                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22915                         (const_int 2)))]
22916   "TARGET_SSE2 && TARGET_64BIT"
22917   "cvtsi2sdq\t{%2, %0|%0, %2}"
22918   [(set_attr "type" "sseicvt")
22919    (set_attr "mode" "DF")
22920    (set_attr "athlon_decode" "double,direct")])
22921
22922 ;; Conversions between SF and DF
22923
22924 (define_insn "cvtsd2ss"
22925   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22926         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22927                         (vec_duplicate:V4SF
22928                           (float_truncate:V2SF
22929                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22930                         (const_int 14)))]
22931   "TARGET_SSE2"
22932   "cvtsd2ss\t{%2, %0|%0, %2}"
22933   [(set_attr "type" "ssecvt")
22934    (set_attr "athlon_decode" "vector,double")
22935    (set_attr "mode" "SF")])
22936
22937 (define_insn "cvtss2sd"
22938   [(set (match_operand:V2DF 0 "register_operand" "=x")
22939         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22940                         (float_extend:V2DF
22941                           (vec_select:V2SF
22942                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22943                             (parallel [(const_int 0)
22944                                        (const_int 1)])))
22945                         (const_int 2)))]
22946   "TARGET_SSE2"
22947   "cvtss2sd\t{%2, %0|%0, %2}"
22948   [(set_attr "type" "ssecvt")
22949    (set_attr "mode" "DF")])
22950
22951 (define_insn "cvtpd2ps"
22952   [(set (match_operand:V4SF 0 "register_operand" "=x")
22953         (subreg:V4SF
22954           (vec_concat:V4SI
22955             (subreg:V2SI (float_truncate:V2SF
22956                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22957             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22958   "TARGET_SSE2"
22959   "cvtpd2ps\t{%1, %0|%0, %1}"
22960   [(set_attr "type" "ssecvt")
22961    (set_attr "mode" "V4SF")])
22962
22963 (define_insn "cvtps2pd"
22964   [(set (match_operand:V2DF 0 "register_operand" "=x")
22965         (float_extend:V2DF
22966           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22967                            (parallel [(const_int 0)
22968                                       (const_int 1)]))))]
22969   "TARGET_SSE2"
22970   "cvtps2pd\t{%1, %0|%0, %1}"
22971   [(set_attr "type" "ssecvt")
22972    (set_attr "mode" "V2DF")])
22973
22974 ;; SSE2 variants of MMX insns
22975
22976 ;; MMX arithmetic
22977
22978 (define_insn "addv16qi3"
22979   [(set (match_operand:V16QI 0 "register_operand" "=x")
22980         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22981                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22982   "TARGET_SSE2"
22983   "paddb\t{%2, %0|%0, %2}"
22984   [(set_attr "type" "sseiadd")
22985    (set_attr "mode" "TI")])
22986
22987 (define_insn "addv8hi3"
22988   [(set (match_operand:V8HI 0 "register_operand" "=x")
22989         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22990                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22991   "TARGET_SSE2"
22992   "paddw\t{%2, %0|%0, %2}"
22993   [(set_attr "type" "sseiadd")
22994    (set_attr "mode" "TI")])
22995
22996 (define_insn "addv4si3"
22997   [(set (match_operand:V4SI 0 "register_operand" "=x")
22998         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22999                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23000   "TARGET_SSE2"
23001   "paddd\t{%2, %0|%0, %2}"
23002   [(set_attr "type" "sseiadd")
23003    (set_attr "mode" "TI")])
23004
23005 (define_insn "addv2di3"
23006   [(set (match_operand:V2DI 0 "register_operand" "=x")
23007         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23008                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23009   "TARGET_SSE2"
23010   "paddq\t{%2, %0|%0, %2}"
23011   [(set_attr "type" "sseiadd")
23012    (set_attr "mode" "TI")])
23013
23014 (define_insn "ssaddv16qi3"
23015   [(set (match_operand:V16QI 0 "register_operand" "=x")
23016         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23017                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23018   "TARGET_SSE2"
23019   "paddsb\t{%2, %0|%0, %2}"
23020   [(set_attr "type" "sseiadd")
23021    (set_attr "mode" "TI")])
23022
23023 (define_insn "ssaddv8hi3"
23024   [(set (match_operand:V8HI 0 "register_operand" "=x")
23025         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23026                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23027   "TARGET_SSE2"
23028   "paddsw\t{%2, %0|%0, %2}"
23029   [(set_attr "type" "sseiadd")
23030    (set_attr "mode" "TI")])
23031
23032 (define_insn "usaddv16qi3"
23033   [(set (match_operand:V16QI 0 "register_operand" "=x")
23034         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23035                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23036   "TARGET_SSE2"
23037   "paddusb\t{%2, %0|%0, %2}"
23038   [(set_attr "type" "sseiadd")
23039    (set_attr "mode" "TI")])
23040
23041 (define_insn "usaddv8hi3"
23042   [(set (match_operand:V8HI 0 "register_operand" "=x")
23043         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23044                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23045   "TARGET_SSE2"
23046   "paddusw\t{%2, %0|%0, %2}"
23047   [(set_attr "type" "sseiadd")
23048    (set_attr "mode" "TI")])
23049
23050 (define_insn "subv16qi3"
23051   [(set (match_operand:V16QI 0 "register_operand" "=x")
23052         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23053                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23054   "TARGET_SSE2"
23055   "psubb\t{%2, %0|%0, %2}"
23056   [(set_attr "type" "sseiadd")
23057    (set_attr "mode" "TI")])
23058
23059 (define_insn "subv8hi3"
23060   [(set (match_operand:V8HI 0 "register_operand" "=x")
23061         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23062                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23063   "TARGET_SSE2"
23064   "psubw\t{%2, %0|%0, %2}"
23065   [(set_attr "type" "sseiadd")
23066    (set_attr "mode" "TI")])
23067
23068 (define_insn "subv4si3"
23069   [(set (match_operand:V4SI 0 "register_operand" "=x")
23070         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23071                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23072   "TARGET_SSE2"
23073   "psubd\t{%2, %0|%0, %2}"
23074   [(set_attr "type" "sseiadd")
23075    (set_attr "mode" "TI")])
23076
23077 (define_insn "subv2di3"
23078   [(set (match_operand:V2DI 0 "register_operand" "=x")
23079         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23080                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23081   "TARGET_SSE2"
23082   "psubq\t{%2, %0|%0, %2}"
23083   [(set_attr "type" "sseiadd")
23084    (set_attr "mode" "TI")])
23085
23086 (define_insn "sssubv16qi3"
23087   [(set (match_operand:V16QI 0 "register_operand" "=x")
23088         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23089                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23090   "TARGET_SSE2"
23091   "psubsb\t{%2, %0|%0, %2}"
23092   [(set_attr "type" "sseiadd")
23093    (set_attr "mode" "TI")])
23094
23095 (define_insn "sssubv8hi3"
23096   [(set (match_operand:V8HI 0 "register_operand" "=x")
23097         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23098                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23099   "TARGET_SSE2"
23100   "psubsw\t{%2, %0|%0, %2}"
23101   [(set_attr "type" "sseiadd")
23102    (set_attr "mode" "TI")])
23103
23104 (define_insn "ussubv16qi3"
23105   [(set (match_operand:V16QI 0 "register_operand" "=x")
23106         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23107                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23108   "TARGET_SSE2"
23109   "psubusb\t{%2, %0|%0, %2}"
23110   [(set_attr "type" "sseiadd")
23111    (set_attr "mode" "TI")])
23112
23113 (define_insn "ussubv8hi3"
23114   [(set (match_operand:V8HI 0 "register_operand" "=x")
23115         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23116                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23117   "TARGET_SSE2"
23118   "psubusw\t{%2, %0|%0, %2}"
23119   [(set_attr "type" "sseiadd")
23120    (set_attr "mode" "TI")])
23121
23122 (define_insn "mulv8hi3"
23123   [(set (match_operand:V8HI 0 "register_operand" "=x")
23124         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23125                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23126   "TARGET_SSE2"
23127   "pmullw\t{%2, %0|%0, %2}"
23128   [(set_attr "type" "sseimul")
23129    (set_attr "mode" "TI")])
23130
23131 (define_insn "smulv8hi3_highpart"
23132   [(set (match_operand:V8HI 0 "register_operand" "=x")
23133         (truncate:V8HI
23134          (lshiftrt:V8SI
23135           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23136                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23137           (const_int 16))))]
23138   "TARGET_SSE2"
23139   "pmulhw\t{%2, %0|%0, %2}"
23140   [(set_attr "type" "sseimul")
23141    (set_attr "mode" "TI")])
23142
23143 (define_insn "umulv8hi3_highpart"
23144   [(set (match_operand:V8HI 0 "register_operand" "=x")
23145         (truncate:V8HI
23146          (lshiftrt:V8SI
23147           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23148                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23149           (const_int 16))))]
23150   "TARGET_SSE2"
23151   "pmulhuw\t{%2, %0|%0, %2}"
23152   [(set_attr "type" "sseimul")
23153    (set_attr "mode" "TI")])
23154
23155 (define_insn "sse2_umulsidi3"
23156   [(set (match_operand:DI 0 "register_operand" "=y")
23157         (mult:DI (zero_extend:DI (vec_select:SI
23158                                   (match_operand:V2SI 1 "register_operand" "0")
23159                                   (parallel [(const_int 0)])))
23160                  (zero_extend:DI (vec_select:SI
23161                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23162                                   (parallel [(const_int 0)])))))]
23163   "TARGET_SSE2"
23164   "pmuludq\t{%2, %0|%0, %2}"
23165   [(set_attr "type" "mmxmul")
23166    (set_attr "mode" "DI")])
23167
23168 (define_insn "sse2_umulv2siv2di3"
23169   [(set (match_operand:V2DI 0 "register_operand" "=x")
23170         (mult:V2DI (zero_extend:V2DI
23171                      (vec_select:V2SI
23172                        (match_operand:V4SI 1 "register_operand" "0")
23173                        (parallel [(const_int 0) (const_int 2)])))
23174                    (zero_extend:V2DI
23175                      (vec_select:V2SI
23176                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23177                        (parallel [(const_int 0) (const_int 2)])))))]
23178   "TARGET_SSE2"
23179   "pmuludq\t{%2, %0|%0, %2}"
23180   [(set_attr "type" "sseimul")
23181    (set_attr "mode" "TI")])
23182
23183 (define_insn "sse2_pmaddwd"
23184   [(set (match_operand:V4SI 0 "register_operand" "=x")
23185         (plus:V4SI
23186          (mult:V4SI
23187           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23188                                              (parallel [(const_int 0)
23189                                                         (const_int 2)
23190                                                         (const_int 4)
23191                                                         (const_int 6)])))
23192           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23193                                              (parallel [(const_int 0)
23194                                                         (const_int 2)
23195                                                         (const_int 4)
23196                                                         (const_int 6)]))))
23197          (mult:V4SI
23198           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23199                                              (parallel [(const_int 1)
23200                                                         (const_int 3)
23201                                                         (const_int 5)
23202                                                         (const_int 7)])))
23203           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23204                                              (parallel [(const_int 1)
23205                                                         (const_int 3)
23206                                                         (const_int 5)
23207                                                         (const_int 7)]))))))]
23208   "TARGET_SSE2"
23209   "pmaddwd\t{%2, %0|%0, %2}"
23210   [(set_attr "type" "sseiadd")
23211    (set_attr "mode" "TI")])
23212
23213 ;; Same as pxor, but don't show input operands so that we don't think
23214 ;; they are live.
23215 (define_insn "sse2_clrti"
23216   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23217   "TARGET_SSE2"
23218 {
23219   if (get_attr_mode (insn) == MODE_TI)
23220     return "pxor\t%0, %0";
23221   else
23222     return "xorps\t%0, %0";
23223 }
23224   [(set_attr "type" "ssemov")
23225    (set_attr "memory" "none")
23226    (set (attr "mode")
23227               (if_then_else
23228                 (ne (symbol_ref "optimize_size")
23229                     (const_int 0))
23230                 (const_string "V4SF")
23231                 (const_string "TI")))])
23232
23233 ;; MMX unsigned averages/sum of absolute differences
23234
23235 (define_insn "sse2_uavgv16qi3"
23236   [(set (match_operand:V16QI 0 "register_operand" "=x")
23237         (ashiftrt:V16QI
23238          (plus:V16QI (plus:V16QI
23239                      (match_operand:V16QI 1 "register_operand" "0")
23240                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23241                      (const_vector:V16QI [(const_int 1) (const_int 1)
23242                                           (const_int 1) (const_int 1)
23243                                           (const_int 1) (const_int 1)
23244                                           (const_int 1) (const_int 1)
23245                                           (const_int 1) (const_int 1)
23246                                           (const_int 1) (const_int 1)
23247                                           (const_int 1) (const_int 1)
23248                                           (const_int 1) (const_int 1)]))
23249          (const_int 1)))]
23250   "TARGET_SSE2"
23251   "pavgb\t{%2, %0|%0, %2}"
23252   [(set_attr "type" "sseiadd")
23253    (set_attr "mode" "TI")])
23254
23255 (define_insn "sse2_uavgv8hi3"
23256   [(set (match_operand:V8HI 0 "register_operand" "=x")
23257         (ashiftrt:V8HI
23258          (plus:V8HI (plus:V8HI
23259                      (match_operand:V8HI 1 "register_operand" "0")
23260                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23261                     (const_vector:V8HI [(const_int 1) (const_int 1)
23262                                         (const_int 1) (const_int 1)
23263                                         (const_int 1) (const_int 1)
23264                                         (const_int 1) (const_int 1)]))
23265          (const_int 1)))]
23266   "TARGET_SSE2"
23267   "pavgw\t{%2, %0|%0, %2}"
23268   [(set_attr "type" "sseiadd")
23269    (set_attr "mode" "TI")])
23270
23271 ;; @@@ this isn't the right representation.
23272 (define_insn "sse2_psadbw"
23273   [(set (match_operand:V2DI 0 "register_operand" "=x")
23274         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23275                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23276                      UNSPEC_PSADBW))]
23277   "TARGET_SSE2"
23278   "psadbw\t{%2, %0|%0, %2}"
23279   [(set_attr "type" "sseiadd")
23280    (set_attr "mode" "TI")])
23281
23282
23283 ;; MMX insert/extract/shuffle
23284
23285 (define_insn "sse2_pinsrw"
23286   [(set (match_operand:V8HI 0 "register_operand" "=x")
23287         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23288                         (vec_duplicate:V8HI
23289                          (truncate:HI
23290                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23291                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23292   "TARGET_SSE2"
23293   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23294   [(set_attr "type" "ssecvt")
23295    (set_attr "mode" "TI")])
23296
23297 (define_insn "sse2_pextrw"
23298   [(set (match_operand:SI 0 "register_operand" "=r")
23299         (zero_extend:SI
23300           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23301                          (parallel
23302                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23303   "TARGET_SSE2"
23304   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23305   [(set_attr "type" "ssecvt")
23306    (set_attr "mode" "TI")])
23307
23308 (define_insn "sse2_pshufd"
23309   [(set (match_operand:V4SI 0 "register_operand" "=x")
23310         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23311                       (match_operand:SI 2 "immediate_operand" "i")]
23312                      UNSPEC_SHUFFLE))]
23313   "TARGET_SSE2"
23314   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23315   [(set_attr "type" "ssecvt")
23316    (set_attr "mode" "TI")])
23317
23318 (define_insn "sse2_pshuflw"
23319   [(set (match_operand:V8HI 0 "register_operand" "=x")
23320         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23321                       (match_operand:SI 2 "immediate_operand" "i")]
23322                      UNSPEC_PSHUFLW))]
23323   "TARGET_SSE2"
23324   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23325   [(set_attr "type" "ssecvt")
23326    (set_attr "mode" "TI")])
23327
23328 (define_insn "sse2_pshufhw"
23329   [(set (match_operand:V8HI 0 "register_operand" "=x")
23330         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23331                       (match_operand:SI 2 "immediate_operand" "i")]
23332                      UNSPEC_PSHUFHW))]
23333   "TARGET_SSE2"
23334   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23335   [(set_attr "type" "ssecvt")
23336    (set_attr "mode" "TI")])
23337
23338 ;; MMX mask-generating comparisons
23339
23340 (define_insn "eqv16qi3"
23341   [(set (match_operand:V16QI 0 "register_operand" "=x")
23342         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23343                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23344   "TARGET_SSE2"
23345   "pcmpeqb\t{%2, %0|%0, %2}"
23346   [(set_attr "type" "ssecmp")
23347    (set_attr "mode" "TI")])
23348
23349 (define_insn "eqv8hi3"
23350   [(set (match_operand:V8HI 0 "register_operand" "=x")
23351         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23352                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23353   "TARGET_SSE2"
23354   "pcmpeqw\t{%2, %0|%0, %2}"
23355   [(set_attr "type" "ssecmp")
23356    (set_attr "mode" "TI")])
23357
23358 (define_insn "eqv4si3"
23359   [(set (match_operand:V4SI 0 "register_operand" "=x")
23360         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23361                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23362   "TARGET_SSE2"
23363   "pcmpeqd\t{%2, %0|%0, %2}"
23364   [(set_attr "type" "ssecmp")
23365    (set_attr "mode" "TI")])
23366
23367 (define_insn "gtv16qi3"
23368   [(set (match_operand:V16QI 0 "register_operand" "=x")
23369         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23370                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23371   "TARGET_SSE2"
23372   "pcmpgtb\t{%2, %0|%0, %2}"
23373   [(set_attr "type" "ssecmp")
23374    (set_attr "mode" "TI")])
23375
23376 (define_insn "gtv8hi3"
23377   [(set (match_operand:V8HI 0 "register_operand" "=x")
23378         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23379                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23380   "TARGET_SSE2"
23381   "pcmpgtw\t{%2, %0|%0, %2}"
23382   [(set_attr "type" "ssecmp")
23383    (set_attr "mode" "TI")])
23384
23385 (define_insn "gtv4si3"
23386   [(set (match_operand:V4SI 0 "register_operand" "=x")
23387         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23388                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23389   "TARGET_SSE2"
23390   "pcmpgtd\t{%2, %0|%0, %2}"
23391   [(set_attr "type" "ssecmp")
23392    (set_attr "mode" "TI")])
23393
23394
23395 ;; MMX max/min insns
23396
23397 (define_insn "umaxv16qi3"
23398   [(set (match_operand:V16QI 0 "register_operand" "=x")
23399         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23400                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23401   "TARGET_SSE2"
23402   "pmaxub\t{%2, %0|%0, %2}"
23403   [(set_attr "type" "sseiadd")
23404    (set_attr "mode" "TI")])
23405
23406 (define_insn "smaxv8hi3"
23407   [(set (match_operand:V8HI 0 "register_operand" "=x")
23408         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23409                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23410   "TARGET_SSE2"
23411   "pmaxsw\t{%2, %0|%0, %2}"
23412   [(set_attr "type" "sseiadd")
23413    (set_attr "mode" "TI")])
23414
23415 (define_insn "uminv16qi3"
23416   [(set (match_operand:V16QI 0 "register_operand" "=x")
23417         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23418                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23419   "TARGET_SSE2"
23420   "pminub\t{%2, %0|%0, %2}"
23421   [(set_attr "type" "sseiadd")
23422    (set_attr "mode" "TI")])
23423
23424 (define_insn "sminv8hi3"
23425   [(set (match_operand:V8HI 0 "register_operand" "=x")
23426         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23427                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23428   "TARGET_SSE2"
23429   "pminsw\t{%2, %0|%0, %2}"
23430   [(set_attr "type" "sseiadd")
23431    (set_attr "mode" "TI")])
23432
23433
23434 ;; MMX shifts
23435
23436 (define_insn "ashrv8hi3"
23437   [(set (match_operand:V8HI 0 "register_operand" "=x")
23438         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23439                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23440   "TARGET_SSE2"
23441   "psraw\t{%2, %0|%0, %2}"
23442   [(set_attr "type" "sseishft")
23443    (set_attr "mode" "TI")])
23444
23445 (define_insn "ashrv4si3"
23446   [(set (match_operand:V4SI 0 "register_operand" "=x")
23447         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23448                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23449   "TARGET_SSE2"
23450   "psrad\t{%2, %0|%0, %2}"
23451   [(set_attr "type" "sseishft")
23452    (set_attr "mode" "TI")])
23453
23454 (define_insn "lshrv8hi3"
23455   [(set (match_operand:V8HI 0 "register_operand" "=x")
23456         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23457                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23458   "TARGET_SSE2"
23459   "psrlw\t{%2, %0|%0, %2}"
23460   [(set_attr "type" "sseishft")
23461    (set_attr "mode" "TI")])
23462
23463 (define_insn "lshrv4si3"
23464   [(set (match_operand:V4SI 0 "register_operand" "=x")
23465         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23466                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23467   "TARGET_SSE2"
23468   "psrld\t{%2, %0|%0, %2}"
23469   [(set_attr "type" "sseishft")
23470    (set_attr "mode" "TI")])
23471
23472 (define_insn "lshrv2di3"
23473   [(set (match_operand:V2DI 0 "register_operand" "=x")
23474         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23475                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23476   "TARGET_SSE2"
23477   "psrlq\t{%2, %0|%0, %2}"
23478   [(set_attr "type" "sseishft")
23479    (set_attr "mode" "TI")])
23480
23481 (define_insn "ashlv8hi3"
23482   [(set (match_operand:V8HI 0 "register_operand" "=x")
23483         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23484                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23485   "TARGET_SSE2"
23486   "psllw\t{%2, %0|%0, %2}"
23487   [(set_attr "type" "sseishft")
23488    (set_attr "mode" "TI")])
23489
23490 (define_insn "ashlv4si3"
23491   [(set (match_operand:V4SI 0 "register_operand" "=x")
23492         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23493                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23494   "TARGET_SSE2"
23495   "pslld\t{%2, %0|%0, %2}"
23496   [(set_attr "type" "sseishft")
23497    (set_attr "mode" "TI")])
23498
23499 (define_insn "ashlv2di3"
23500   [(set (match_operand:V2DI 0 "register_operand" "=x")
23501         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23502                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23503   "TARGET_SSE2"
23504   "psllq\t{%2, %0|%0, %2}"
23505   [(set_attr "type" "sseishft")
23506    (set_attr "mode" "TI")])
23507
23508 (define_insn "ashrv8hi3_ti"
23509   [(set (match_operand:V8HI 0 "register_operand" "=x")
23510         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23511                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23512   "TARGET_SSE2"
23513   "psraw\t{%2, %0|%0, %2}"
23514   [(set_attr "type" "sseishft")
23515    (set_attr "mode" "TI")])
23516
23517 (define_insn "ashrv4si3_ti"
23518   [(set (match_operand:V4SI 0 "register_operand" "=x")
23519         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23520                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23521   "TARGET_SSE2"
23522   "psrad\t{%2, %0|%0, %2}"
23523   [(set_attr "type" "sseishft")
23524    (set_attr "mode" "TI")])
23525
23526 (define_insn "lshrv8hi3_ti"
23527   [(set (match_operand:V8HI 0 "register_operand" "=x")
23528         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23529                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23530   "TARGET_SSE2"
23531   "psrlw\t{%2, %0|%0, %2}"
23532   [(set_attr "type" "sseishft")
23533    (set_attr "mode" "TI")])
23534
23535 (define_insn "lshrv4si3_ti"
23536   [(set (match_operand:V4SI 0 "register_operand" "=x")
23537         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23538                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23539   "TARGET_SSE2"
23540   "psrld\t{%2, %0|%0, %2}"
23541   [(set_attr "type" "sseishft")
23542    (set_attr "mode" "TI")])
23543
23544 (define_insn "lshrv2di3_ti"
23545   [(set (match_operand:V2DI 0 "register_operand" "=x")
23546         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23547                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23548   "TARGET_SSE2"
23549   "psrlq\t{%2, %0|%0, %2}"
23550   [(set_attr "type" "sseishft")
23551    (set_attr "mode" "TI")])
23552
23553 (define_insn "ashlv8hi3_ti"
23554   [(set (match_operand:V8HI 0 "register_operand" "=x")
23555         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23556                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23557   "TARGET_SSE2"
23558   "psllw\t{%2, %0|%0, %2}"
23559   [(set_attr "type" "sseishft")
23560    (set_attr "mode" "TI")])
23561
23562 (define_insn "ashlv4si3_ti"
23563   [(set (match_operand:V4SI 0 "register_operand" "=x")
23564         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23565                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23566   "TARGET_SSE2"
23567   "pslld\t{%2, %0|%0, %2}"
23568   [(set_attr "type" "sseishft")
23569    (set_attr "mode" "TI")])
23570
23571 (define_insn "ashlv2di3_ti"
23572   [(set (match_operand:V2DI 0 "register_operand" "=x")
23573         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23574                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23575   "TARGET_SSE2"
23576   "psllq\t{%2, %0|%0, %2}"
23577   [(set_attr "type" "sseishft")
23578    (set_attr "mode" "TI")])
23579
23580 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23581 ;; we wouldn't need here it since we never generate TImode arithmetic.
23582
23583 ;; There has to be some kind of prize for the weirdest new instruction...
23584 (define_insn "sse2_ashlti3"
23585   [(set (match_operand:TI 0 "register_operand" "=x")
23586         (unspec:TI
23587          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23588                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23589                                (const_int 8)))] UNSPEC_NOP))]
23590   "TARGET_SSE2"
23591   "pslldq\t{%2, %0|%0, %2}"
23592   [(set_attr "type" "sseishft")
23593    (set_attr "mode" "TI")])
23594
23595 (define_insn "sse2_lshrti3"
23596   [(set (match_operand:TI 0 "register_operand" "=x")
23597         (unspec:TI
23598          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23599                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23600                                 (const_int 8)))] UNSPEC_NOP))]
23601   "TARGET_SSE2"
23602   "psrldq\t{%2, %0|%0, %2}"
23603   [(set_attr "type" "sseishft")
23604    (set_attr "mode" "TI")])
23605
23606 ;; SSE unpack
23607
23608 (define_insn "sse2_unpckhpd"
23609   [(set (match_operand:V2DF 0 "register_operand" "=x")
23610         (vec_concat:V2DF
23611          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23612                         (parallel [(const_int 1)]))
23613          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23614                         (parallel [(const_int 1)]))))]
23615   "TARGET_SSE2"
23616   "unpckhpd\t{%2, %0|%0, %2}"
23617   [(set_attr "type" "ssecvt")
23618    (set_attr "mode" "V2DF")])
23619
23620 (define_insn "sse2_unpcklpd"
23621   [(set (match_operand:V2DF 0 "register_operand" "=x")
23622         (vec_concat:V2DF
23623          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23624                         (parallel [(const_int 0)]))
23625          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23626                         (parallel [(const_int 0)]))))]
23627   "TARGET_SSE2"
23628   "unpcklpd\t{%2, %0|%0, %2}"
23629   [(set_attr "type" "ssecvt")
23630    (set_attr "mode" "V2DF")])
23631
23632 ;; MMX pack/unpack insns.
23633
23634 (define_insn "sse2_packsswb"
23635   [(set (match_operand:V16QI 0 "register_operand" "=x")
23636         (vec_concat:V16QI
23637          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23638          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23639   "TARGET_SSE2"
23640   "packsswb\t{%2, %0|%0, %2}"
23641   [(set_attr "type" "ssecvt")
23642    (set_attr "mode" "TI")])
23643
23644 (define_insn "sse2_packssdw"
23645   [(set (match_operand:V8HI 0 "register_operand" "=x")
23646         (vec_concat:V8HI
23647          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23648          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23649   "TARGET_SSE2"
23650   "packssdw\t{%2, %0|%0, %2}"
23651   [(set_attr "type" "ssecvt")
23652    (set_attr "mode" "TI")])
23653
23654 (define_insn "sse2_packuswb"
23655   [(set (match_operand:V16QI 0 "register_operand" "=x")
23656         (vec_concat:V16QI
23657          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23658          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23659   "TARGET_SSE2"
23660   "packuswb\t{%2, %0|%0, %2}"
23661   [(set_attr "type" "ssecvt")
23662    (set_attr "mode" "TI")])
23663
23664 (define_insn "sse2_punpckhbw"
23665   [(set (match_operand:V16QI 0 "register_operand" "=x")
23666         (vec_merge:V16QI
23667          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23668                            (parallel [(const_int 8) (const_int 0)
23669                                       (const_int 9) (const_int 1)
23670                                       (const_int 10) (const_int 2)
23671                                       (const_int 11) (const_int 3)
23672                                       (const_int 12) (const_int 4)
23673                                       (const_int 13) (const_int 5)
23674                                       (const_int 14) (const_int 6)
23675                                       (const_int 15) (const_int 7)]))
23676          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23677                            (parallel [(const_int 0) (const_int 8)
23678                                       (const_int 1) (const_int 9)
23679                                       (const_int 2) (const_int 10)
23680                                       (const_int 3) (const_int 11)
23681                                       (const_int 4) (const_int 12)
23682                                       (const_int 5) (const_int 13)
23683                                       (const_int 6) (const_int 14)
23684                                       (const_int 7) (const_int 15)]))
23685          (const_int 21845)))]
23686   "TARGET_SSE2"
23687   "punpckhbw\t{%2, %0|%0, %2}"
23688   [(set_attr "type" "ssecvt")
23689    (set_attr "mode" "TI")])
23690
23691 (define_insn "sse2_punpckhwd"
23692   [(set (match_operand:V8HI 0 "register_operand" "=x")
23693         (vec_merge:V8HI
23694          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23695                           (parallel [(const_int 4) (const_int 0)
23696                                      (const_int 5) (const_int 1)
23697                                      (const_int 6) (const_int 2)
23698                                      (const_int 7) (const_int 3)]))
23699          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23700                           (parallel [(const_int 0) (const_int 4)
23701                                      (const_int 1) (const_int 5)
23702                                      (const_int 2) (const_int 6)
23703                                      (const_int 3) (const_int 7)]))
23704          (const_int 85)))]
23705   "TARGET_SSE2"
23706   "punpckhwd\t{%2, %0|%0, %2}"
23707   [(set_attr "type" "ssecvt")
23708    (set_attr "mode" "TI")])
23709
23710 (define_insn "sse2_punpckhdq"
23711   [(set (match_operand:V4SI 0 "register_operand" "=x")
23712         (vec_merge:V4SI
23713          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23714                           (parallel [(const_int 2) (const_int 0)
23715                                      (const_int 3) (const_int 1)]))
23716          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23717                           (parallel [(const_int 0) (const_int 2)
23718                                      (const_int 1) (const_int 3)]))
23719          (const_int 5)))]
23720   "TARGET_SSE2"
23721   "punpckhdq\t{%2, %0|%0, %2}"
23722   [(set_attr "type" "ssecvt")
23723    (set_attr "mode" "TI")])
23724
23725 (define_insn "sse2_punpcklbw"
23726   [(set (match_operand:V16QI 0 "register_operand" "=x")
23727         (vec_merge:V16QI
23728          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23729                            (parallel [(const_int 0) (const_int 8)
23730                                       (const_int 1) (const_int 9)
23731                                       (const_int 2) (const_int 10)
23732                                       (const_int 3) (const_int 11)
23733                                       (const_int 4) (const_int 12)
23734                                       (const_int 5) (const_int 13)
23735                                       (const_int 6) (const_int 14)
23736                                       (const_int 7) (const_int 15)]))
23737          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23738                            (parallel [(const_int 8) (const_int 0)
23739                                       (const_int 9) (const_int 1)
23740                                       (const_int 10) (const_int 2)
23741                                       (const_int 11) (const_int 3)
23742                                       (const_int 12) (const_int 4)
23743                                       (const_int 13) (const_int 5)
23744                                       (const_int 14) (const_int 6)
23745                                       (const_int 15) (const_int 7)]))
23746          (const_int 21845)))]
23747   "TARGET_SSE2"
23748   "punpcklbw\t{%2, %0|%0, %2}"
23749   [(set_attr "type" "ssecvt")
23750    (set_attr "mode" "TI")])
23751
23752 (define_insn "sse2_punpcklwd"
23753   [(set (match_operand:V8HI 0 "register_operand" "=x")
23754         (vec_merge:V8HI
23755          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23756                           (parallel [(const_int 0) (const_int 4)
23757                                      (const_int 1) (const_int 5)
23758                                      (const_int 2) (const_int 6)
23759                                      (const_int 3) (const_int 7)]))
23760          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23761                           (parallel [(const_int 4) (const_int 0)
23762                                      (const_int 5) (const_int 1)
23763                                      (const_int 6) (const_int 2)
23764                                      (const_int 7) (const_int 3)]))
23765          (const_int 85)))]
23766   "TARGET_SSE2"
23767   "punpcklwd\t{%2, %0|%0, %2}"
23768   [(set_attr "type" "ssecvt")
23769    (set_attr "mode" "TI")])
23770
23771 (define_insn "sse2_punpckldq"
23772   [(set (match_operand:V4SI 0 "register_operand" "=x")
23773         (vec_merge:V4SI
23774          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23775                           (parallel [(const_int 0) (const_int 2)
23776                                      (const_int 1) (const_int 3)]))
23777          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23778                           (parallel [(const_int 2) (const_int 0)
23779                                      (const_int 3) (const_int 1)]))
23780          (const_int 5)))]
23781   "TARGET_SSE2"
23782   "punpckldq\t{%2, %0|%0, %2}"
23783   [(set_attr "type" "ssecvt")
23784    (set_attr "mode" "TI")])
23785
23786 (define_insn "sse2_punpcklqdq"
23787   [(set (match_operand:V2DI 0 "register_operand" "=x")
23788         (vec_merge:V2DI
23789          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23790                           (parallel [(const_int 1)
23791                                      (const_int 0)]))
23792          (match_operand:V2DI 1 "register_operand" "0")
23793          (const_int 1)))]
23794   "TARGET_SSE2"
23795   "punpcklqdq\t{%2, %0|%0, %2}"
23796   [(set_attr "type" "ssecvt")
23797    (set_attr "mode" "TI")])
23798
23799 (define_insn "sse2_punpckhqdq"
23800   [(set (match_operand:V2DI 0 "register_operand" "=x")
23801         (vec_merge:V2DI
23802          (match_operand:V2DI 1 "register_operand" "0")
23803          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23804                           (parallel [(const_int 1)
23805                                      (const_int 0)]))
23806          (const_int 1)))]
23807   "TARGET_SSE2"
23808   "punpckhqdq\t{%2, %0|%0, %2}"
23809   [(set_attr "type" "ssecvt")
23810    (set_attr "mode" "TI")])
23811
23812 ;; SSE2 moves
23813
23814 (define_insn "sse2_movapd"
23815   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23816         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23817                      UNSPEC_MOVA))]
23818   "TARGET_SSE2
23819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23820   "movapd\t{%1, %0|%0, %1}"
23821   [(set_attr "type" "ssemov")
23822    (set_attr "mode" "V2DF")])
23823
23824 (define_insn "sse2_movupd"
23825   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23826         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23827                      UNSPEC_MOVU))]
23828   "TARGET_SSE2
23829    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23830   "movupd\t{%1, %0|%0, %1}"
23831   [(set_attr "type" "ssecvt")
23832    (set_attr "mode" "V2DF")])
23833
23834 (define_insn "sse2_movdqa"
23835   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23836         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23837                        UNSPEC_MOVA))]
23838   "TARGET_SSE2
23839    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23840   "movdqa\t{%1, %0|%0, %1}"
23841   [(set_attr "type" "ssemov")
23842    (set_attr "mode" "TI")])
23843
23844 (define_insn "sse2_movdqu"
23845   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23846         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23847                        UNSPEC_MOVU))]
23848   "TARGET_SSE2
23849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23850   "movdqu\t{%1, %0|%0, %1}"
23851   [(set_attr "type" "ssecvt")
23852    (set_attr "mode" "TI")])
23853
23854 (define_insn "sse2_movdq2q"
23855   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23856         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23857                        (parallel [(const_int 0)])))]
23858   "TARGET_SSE2 && !TARGET_64BIT"
23859   "@
23860    movq\t{%1, %0|%0, %1}
23861    movdq2q\t{%1, %0|%0, %1}"
23862   [(set_attr "type" "ssecvt")
23863    (set_attr "mode" "TI")])
23864
23865 (define_insn "sse2_movdq2q_rex64"
23866   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23867         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23868                        (parallel [(const_int 0)])))]
23869   "TARGET_SSE2 && TARGET_64BIT"
23870   "@
23871    movq\t{%1, %0|%0, %1}
23872    movdq2q\t{%1, %0|%0, %1}
23873    movd\t{%1, %0|%0, %1}"
23874   [(set_attr "type" "ssecvt")
23875    (set_attr "mode" "TI")])
23876
23877 (define_insn "sse2_movq2dq"
23878   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23879         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23880                          (const_int 0)))]
23881   "TARGET_SSE2 && !TARGET_64BIT"
23882   "@
23883    movq\t{%1, %0|%0, %1}
23884    movq2dq\t{%1, %0|%0, %1}"
23885   [(set_attr "type" "ssecvt,ssemov")
23886    (set_attr "mode" "TI")])
23887
23888 (define_insn "sse2_movq2dq_rex64"
23889   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23890         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23891                          (const_int 0)))]
23892   "TARGET_SSE2 && TARGET_64BIT"
23893   "@
23894    movq\t{%1, %0|%0, %1}
23895    movq2dq\t{%1, %0|%0, %1}
23896    movd\t{%1, %0|%0, %1}"
23897   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23898    (set_attr "mode" "TI")])
23899
23900 (define_insn "sse2_movq"
23901   [(set (match_operand:V2DI 0 "register_operand" "=x")
23902         (vec_concat:V2DI (vec_select:DI
23903                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23904                           (parallel [(const_int 0)]))
23905                          (const_int 0)))]
23906   "TARGET_SSE2"
23907   "movq\t{%1, %0|%0, %1}"
23908   [(set_attr "type" "ssemov")
23909    (set_attr "mode" "TI")])
23910
23911 (define_insn "sse2_loadd"
23912   [(set (match_operand:V4SI 0 "register_operand" "=x")
23913         (vec_merge:V4SI
23914          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23915          (const_vector:V4SI [(const_int 0)
23916                              (const_int 0)
23917                              (const_int 0)
23918                              (const_int 0)])
23919          (const_int 1)))]
23920   "TARGET_SSE2"
23921   "movd\t{%1, %0|%0, %1}"
23922   [(set_attr "type" "ssemov")
23923    (set_attr "mode" "TI")])
23924
23925 (define_insn "sse2_stored"
23926   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23927         (vec_select:SI
23928          (match_operand:V4SI 1 "register_operand" "x")
23929          (parallel [(const_int 0)])))]
23930   "TARGET_SSE2"
23931   "movd\t{%1, %0|%0, %1}"
23932   [(set_attr "type" "ssemov")
23933    (set_attr "mode" "TI")])
23934
23935 (define_insn "sse2_movhpd"
23936   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23937         (vec_merge:V2DF
23938          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23939          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23940          (const_int 2)))]
23941   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23942   "movhpd\t{%2, %0|%0, %2}"
23943   [(set_attr "type" "ssecvt")
23944    (set_attr "mode" "V2DF")])
23945
23946 (define_expand "sse2_loadsd"
23947   [(match_operand:V2DF 0 "register_operand" "")
23948    (match_operand:DF 1 "memory_operand" "")]
23949   "TARGET_SSE2"
23950 {
23951   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23952                                 CONST0_RTX (V2DFmode)));
23953   DONE;
23954 })
23955
23956 (define_insn "sse2_loadsd_1"
23957   [(set (match_operand:V2DF 0 "register_operand" "=x")
23958         (vec_merge:V2DF
23959          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23960          (match_operand:V2DF 2 "const0_operand" "X")
23961          (const_int 1)))]
23962   "TARGET_SSE2"
23963   "movsd\t{%1, %0|%0, %1}"
23964   [(set_attr "type" "ssecvt")
23965    (set_attr "mode" "DF")])
23966
23967 (define_insn "sse2_movsd"
23968   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23969         (vec_merge:V2DF
23970          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23971          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23972          (const_int 1)))]
23973   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
23974   "@movsd\t{%2, %0|%0, %2}
23975     movlpd\t{%2, %0|%0, %2}
23976     movlpd\t{%2, %0|%0, %2}"
23977   [(set_attr "type" "ssecvt")
23978    (set_attr "mode" "DF,V2DF,V2DF")])
23979
23980 (define_insn "sse2_storesd"
23981   [(set (match_operand:DF 0 "memory_operand" "=m")
23982         (vec_select:DF
23983          (match_operand:V2DF 1 "register_operand" "x")
23984          (parallel [(const_int 0)])))]
23985   "TARGET_SSE2"
23986   "movsd\t{%1, %0|%0, %1}"
23987   [(set_attr "type" "ssecvt")
23988    (set_attr "mode" "DF")])
23989
23990 (define_insn "sse2_shufpd"
23991   [(set (match_operand:V2DF 0 "register_operand" "=x")
23992         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23993                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23994                       (match_operand:SI 3 "immediate_operand" "i")]
23995                      UNSPEC_SHUFFLE))]
23996   "TARGET_SSE2"
23997   ;; @@@ check operand order for intel/nonintel syntax
23998   "shufpd\t{%3, %2, %0|%0, %2, %3}"
23999   [(set_attr "type" "ssecvt")
24000    (set_attr "mode" "V2DF")])
24001
24002 (define_insn "sse2_clflush"
24003   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24004                     UNSPECV_CLFLUSH)]
24005   "TARGET_SSE2"
24006   "clflush\t%a0"
24007   [(set_attr "type" "sse")
24008    (set_attr "memory" "unknown")])
24009
24010 (define_expand "sse2_mfence"
24011   [(set (match_dup 0)
24012         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24013   "TARGET_SSE2"
24014 {
24015   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24016   MEM_VOLATILE_P (operands[0]) = 1;
24017 })
24018
24019 (define_insn "*mfence_insn"
24020   [(set (match_operand:BLK 0 "" "")
24021         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24022   "TARGET_SSE2"
24023   "mfence"
24024   [(set_attr "type" "sse")
24025    (set_attr "memory" "unknown")])
24026
24027 (define_expand "sse2_lfence"
24028   [(set (match_dup 0)
24029         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24030   "TARGET_SSE2"
24031 {
24032   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24033   MEM_VOLATILE_P (operands[0]) = 1;
24034 })
24035
24036 (define_insn "*lfence_insn"
24037   [(set (match_operand:BLK 0 "" "")
24038         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24039   "TARGET_SSE2"
24040   "lfence"
24041   [(set_attr "type" "sse")
24042    (set_attr "memory" "unknown")])
24043
24044 ;; SSE3
24045
24046 (define_insn "mwait"
24047   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24048                      (match_operand:SI 1 "register_operand" "c")]
24049                     UNSPECV_MWAIT)]
24050   "TARGET_SSE3"
24051   "mwait\t%0, %1"
24052   [(set_attr "length" "3")])
24053
24054 (define_insn "monitor"
24055   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24056                      (match_operand:SI 1 "register_operand" "c")
24057                      (match_operand:SI 2 "register_operand" "d")]
24058                     UNSPECV_MONITOR)]
24059   "TARGET_SSE3"
24060   "monitor\t%0, %1, %2"
24061   [(set_attr "length" "3")])
24062
24063 ;; SSE3 arithmetic
24064
24065 (define_insn "addsubv4sf3"
24066   [(set (match_operand:V4SF 0 "register_operand" "=x")
24067         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24068                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24069                      UNSPEC_ADDSUB))]
24070   "TARGET_SSE3"
24071   "addsubps\t{%2, %0|%0, %2}"
24072   [(set_attr "type" "sseadd")
24073    (set_attr "mode" "V4SF")])
24074
24075 (define_insn "addsubv2df3"
24076   [(set (match_operand:V2DF 0 "register_operand" "=x")
24077         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24078                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24079                      UNSPEC_ADDSUB))]
24080   "TARGET_SSE3"
24081   "addsubpd\t{%2, %0|%0, %2}"
24082   [(set_attr "type" "sseadd")
24083    (set_attr "mode" "V2DF")])
24084
24085 (define_insn "haddv4sf3"
24086   [(set (match_operand:V4SF 0 "register_operand" "=x")
24087         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24088                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24089                      UNSPEC_HADD))]
24090   "TARGET_SSE3"
24091   "haddps\t{%2, %0|%0, %2}"
24092   [(set_attr "type" "sseadd")
24093    (set_attr "mode" "V4SF")])
24094
24095 (define_insn "haddv2df3"
24096   [(set (match_operand:V2DF 0 "register_operand" "=x")
24097         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24098                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24099                      UNSPEC_HADD))]
24100   "TARGET_SSE3"
24101   "haddpd\t{%2, %0|%0, %2}"
24102   [(set_attr "type" "sseadd")
24103    (set_attr "mode" "V2DF")])
24104
24105 (define_insn "hsubv4sf3"
24106   [(set (match_operand:V4SF 0 "register_operand" "=x")
24107         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24108                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24109                      UNSPEC_HSUB))]
24110   "TARGET_SSE3"
24111   "hsubps\t{%2, %0|%0, %2}"
24112   [(set_attr "type" "sseadd")
24113    (set_attr "mode" "V4SF")])
24114
24115 (define_insn "hsubv2df3"
24116   [(set (match_operand:V2DF 0 "register_operand" "=x")
24117         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24118                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24119                      UNSPEC_HSUB))]
24120   "TARGET_SSE3"
24121   "hsubpd\t{%2, %0|%0, %2}"
24122   [(set_attr "type" "sseadd")
24123    (set_attr "mode" "V2DF")])
24124
24125 (define_insn "movshdup"
24126   [(set (match_operand:V4SF 0 "register_operand" "=x")
24127         (unspec:V4SF
24128          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24129   "TARGET_SSE3"
24130   "movshdup\t{%1, %0|%0, %1}"
24131   [(set_attr "type" "sse")
24132    (set_attr "mode" "V4SF")])
24133
24134 (define_insn "movsldup"
24135   [(set (match_operand:V4SF 0 "register_operand" "=x")
24136         (unspec:V4SF
24137          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24138   "TARGET_SSE3"
24139   "movsldup\t{%1, %0|%0, %1}"
24140   [(set_attr "type" "sse")
24141    (set_attr "mode" "V4SF")])
24142
24143 (define_insn "lddqu"
24144   [(set (match_operand:V16QI 0 "register_operand" "=x")
24145         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24146                        UNSPEC_LDQQU))]
24147   "TARGET_SSE3"
24148   "lddqu\t{%1, %0|%0, %1}"
24149   [(set_attr "type" "ssecvt")
24150    (set_attr "mode" "TI")])
24151
24152 (define_insn "loadddup"
24153   [(set (match_operand:V2DF 0 "register_operand" "=x")
24154         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24155   "TARGET_SSE3"
24156   "movddup\t{%1, %0|%0, %1}"
24157   [(set_attr "type" "ssecvt")
24158    (set_attr "mode" "DF")])
24159
24160 (define_insn "movddup"
24161   [(set (match_operand:V2DF 0 "register_operand" "=x")
24162         (vec_duplicate:V2DF
24163          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24164                         (parallel [(const_int 0)]))))]
24165   "TARGET_SSE3"
24166   "movddup\t{%1, %0|%0, %1}"
24167   [(set_attr "type" "ssecvt")
24168    (set_attr "mode" "DF")])