OSDN Git Service

* config/i386/i386.md (*floathisf2_i387, *floathidf2_i387):
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1108  
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1116 {
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1126         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1127   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1128    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1129 {
1130   switch (get_attr_type (insn))
1131     {
1132     case TYPE_SSEMOV:
1133       if (get_attr_mode (insn) == MODE_TI)
1134         return "movdqa\t{%1, %0|%0, %1}";
1135       return "movd\t{%1, %0|%0, %1}";
1136
1137     case TYPE_MMXMOV:
1138       if (get_attr_mode (insn) == MODE_DI)
1139         return "movq\t{%1, %0|%0, %1}";
1140       return "movd\t{%1, %0|%0, %1}";
1141
1142     case TYPE_LEA:
1143       return "lea{l}\t{%1, %0|%0, %1}";
1144
1145     default:
1146       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1147         abort();
1148       return "mov{l}\t{%1, %0|%0, %1}";
1149     }
1150 }
1151   [(set (attr "type")
1152      (cond [(eq_attr "alternative" "2,3,4")
1153               (const_string "mmxmov")
1154             (eq_attr "alternative" "5,6,7")
1155               (const_string "ssemov")
1156             (and (ne (symbol_ref "flag_pic") (const_int 0))
1157                  (match_operand:SI 1 "symbolic_operand" ""))
1158               (const_string "lea")
1159            ]
1160            (const_string "imov")))
1161    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1162
1163 (define_insn "*movsi_1_nointernunit"
1164   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1165         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1166   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1168 {
1169   switch (get_attr_type (insn))
1170     {
1171     case TYPE_SSEMOV:
1172       if (get_attr_mode (insn) == MODE_TI)
1173         return "movdqa\t{%1, %0|%0, %1}";
1174       return "movd\t{%1, %0|%0, %1}";
1175
1176     case TYPE_MMXMOV:
1177       if (get_attr_mode (insn) == MODE_DI)
1178         return "movq\t{%1, %0|%0, %1}";
1179       return "movd\t{%1, %0|%0, %1}";
1180
1181     case TYPE_LEA:
1182       return "lea{l}\t{%1, %0|%0, %1}";
1183
1184     default:
1185       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1186         abort();
1187       return "mov{l}\t{%1, %0|%0, %1}";
1188     }
1189 }
1190   [(set (attr "type")
1191      (cond [(eq_attr "alternative" "2,3,4")
1192               (const_string "mmxmov")
1193             (eq_attr "alternative" "5,6,7")
1194               (const_string "ssemov")
1195             (and (ne (symbol_ref "flag_pic") (const_int 0))
1196                  (match_operand:SI 1 "symbolic_operand" ""))
1197               (const_string "lea")
1198            ]
1199            (const_string "imov")))
1200    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1201
1202 ;; Stores and loads of ax to arbitrary constant address.
1203 ;; We fake an second form of instruction to force reload to load address
1204 ;; into register when rax is not available
1205 (define_insn "*movabssi_1_rex64"
1206   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1207         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1208   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1209   "@
1210    movabs{l}\t{%1, %P0|%P0, %1}
1211    mov{l}\t{%1, %a0|%a0, %1}"
1212   [(set_attr "type" "imov")
1213    (set_attr "modrm" "0,*")
1214    (set_attr "length_address" "8,0")
1215    (set_attr "length_immediate" "0,*")
1216    (set_attr "memory" "store")
1217    (set_attr "mode" "SI")])
1218
1219 (define_insn "*movabssi_2_rex64"
1220   [(set (match_operand:SI 0 "register_operand" "=a,r")
1221         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1222   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1223   "@
1224    movabs{l}\t{%P1, %0|%0, %P1}
1225    mov{l}\t{%a1, %0|%0, %a1}"
1226   [(set_attr "type" "imov")
1227    (set_attr "modrm" "0,*")
1228    (set_attr "length_address" "8,0")
1229    (set_attr "length_immediate" "0")
1230    (set_attr "memory" "load")
1231    (set_attr "mode" "SI")])
1232
1233 (define_insn "*swapsi"
1234   [(set (match_operand:SI 0 "register_operand" "+r")
1235         (match_operand:SI 1 "register_operand" "+r"))
1236    (set (match_dup 1)
1237         (match_dup 0))]
1238   ""
1239   "xchg{l}\t%1, %0"
1240   [(set_attr "type" "imov")
1241    (set_attr "pent_pair" "np")
1242    (set_attr "athlon_decode" "vector")
1243    (set_attr "mode" "SI")
1244    (set_attr "modrm" "0")])
1245
1246 (define_expand "movhi"
1247   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248         (match_operand:HI 1 "general_operand" ""))]
1249   ""
1250   "ix86_expand_move (HImode, operands); DONE;")
1251
1252 (define_insn "*pushhi2"
1253   [(set (match_operand:HI 0 "push_operand" "=<,<")
1254         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1255   "!TARGET_64BIT"
1256   "@
1257    push{w}\t{|WORD PTR }%1
1258    push{w}\t%1"
1259   [(set_attr "type" "push")
1260    (set_attr "mode" "HI")])
1261
1262 ;; For 64BIT abi we always round up to 8 bytes.
1263 (define_insn "*pushhi2_rex64"
1264   [(set (match_operand:HI 0 "push_operand" "=X")
1265         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1266   "TARGET_64BIT"
1267   "push{q}\t%q1"
1268   [(set_attr "type" "push")
1269    (set_attr "mode" "QI")])
1270
1271 (define_insn "*movhi_1"
1272   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1274   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1275 {
1276   switch (get_attr_type (insn))
1277     {
1278     case TYPE_IMOVX:
1279       /* movzwl is faster than movw on p2 due to partial word stalls,
1280          though not as fast as an aligned movl.  */
1281       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1282     default:
1283       if (get_attr_mode (insn) == MODE_SI)
1284         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1285       else
1286         return "mov{w}\t{%1, %0|%0, %1}";
1287     }
1288 }
1289   [(set (attr "type")
1290      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291               (const_string "imov")
1292             (and (eq_attr "alternative" "0")
1293                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1294                           (const_int 0))
1295                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1296                           (const_int 0))))
1297               (const_string "imov")
1298             (and (eq_attr "alternative" "1,2")
1299                  (match_operand:HI 1 "aligned_operand" ""))
1300               (const_string "imov")
1301             (and (ne (symbol_ref "TARGET_MOVX")
1302                      (const_int 0))
1303                  (eq_attr "alternative" "0,2"))
1304               (const_string "imovx")
1305            ]
1306            (const_string "imov")))
1307     (set (attr "mode")
1308       (cond [(eq_attr "type" "imovx")
1309                (const_string "SI")
1310              (and (eq_attr "alternative" "1,2")
1311                   (match_operand:HI 1 "aligned_operand" ""))
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "0")
1314                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315                            (const_int 0))
1316                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1317                            (const_int 0))))
1318                (const_string "SI")
1319             ]
1320             (const_string "HI")))])
1321
1322 ;; Stores and loads of ax to arbitrary constant address.
1323 ;; We fake an second form of instruction to force reload to load address
1324 ;; into register when rax is not available
1325 (define_insn "*movabshi_1_rex64"
1326   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1329   "@
1330    movabs{w}\t{%1, %P0|%P0, %1}
1331    mov{w}\t{%1, %a0|%a0, %1}"
1332   [(set_attr "type" "imov")
1333    (set_attr "modrm" "0,*")
1334    (set_attr "length_address" "8,0")
1335    (set_attr "length_immediate" "0,*")
1336    (set_attr "memory" "store")
1337    (set_attr "mode" "HI")])
1338
1339 (define_insn "*movabshi_2_rex64"
1340   [(set (match_operand:HI 0 "register_operand" "=a,r")
1341         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1342   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1343   "@
1344    movabs{w}\t{%P1, %0|%0, %P1}
1345    mov{w}\t{%a1, %0|%0, %a1}"
1346   [(set_attr "type" "imov")
1347    (set_attr "modrm" "0,*")
1348    (set_attr "length_address" "8,0")
1349    (set_attr "length_immediate" "0")
1350    (set_attr "memory" "load")
1351    (set_attr "mode" "HI")])
1352
1353 (define_insn "*swaphi_1"
1354   [(set (match_operand:HI 0 "register_operand" "+r")
1355         (match_operand:HI 1 "register_operand" "+r"))
1356    (set (match_dup 1)
1357         (match_dup 0))]
1358   "TARGET_PARTIAL_REG_STALL"
1359   "xchg{w}\t%1, %0"
1360   [(set_attr "type" "imov")
1361    (set_attr "pent_pair" "np")
1362    (set_attr "mode" "HI")
1363    (set_attr "modrm" "0")])
1364
1365 (define_insn "*swaphi_2"
1366   [(set (match_operand:HI 0 "register_operand" "+r")
1367         (match_operand:HI 1 "register_operand" "+r"))
1368    (set (match_dup 1)
1369         (match_dup 0))]
1370   "! TARGET_PARTIAL_REG_STALL"
1371   "xchg{l}\t%k1, %k0"
1372   [(set_attr "type" "imov")
1373    (set_attr "pent_pair" "np")
1374    (set_attr "mode" "SI")
1375    (set_attr "modrm" "0")])
1376
1377 (define_expand "movstricthi"
1378   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1379         (match_operand:HI 1 "general_operand" ""))]
1380   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1381 {
1382   /* Don't generate memory->memory moves, go through a register */
1383   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384     operands[1] = force_reg (HImode, operands[1]);
1385 })
1386
1387 (define_insn "*movstricthi_1"
1388   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1389         (match_operand:HI 1 "general_operand" "rn,m"))]
1390   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1391    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1392   "mov{w}\t{%1, %0|%0, %1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "mode" "HI")])
1395
1396 (define_insn "*movstricthi_xor"
1397   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1398         (match_operand:HI 1 "const0_operand" "i"))
1399    (clobber (reg:CC FLAGS_REG))]
1400   "reload_completed
1401    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1402   "xor{w}\t{%0, %0|%0, %0}"
1403   [(set_attr "type" "alu1")
1404    (set_attr "mode" "HI")
1405    (set_attr "length_immediate" "0")])
1406
1407 (define_expand "movqi"
1408   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1409         (match_operand:QI 1 "general_operand" ""))]
1410   ""
1411   "ix86_expand_move (QImode, operands); DONE;")
1412
1413 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1414 ;; "push a byte".  But actually we use pushw, which has the effect
1415 ;; of rounding the amount pushed up to a halfword.
1416
1417 (define_insn "*pushqi2"
1418   [(set (match_operand:QI 0 "push_operand" "=X,X")
1419         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1420   "!TARGET_64BIT"
1421   "@
1422    push{w}\t{|word ptr }%1
1423    push{w}\t%w1"
1424   [(set_attr "type" "push")
1425    (set_attr "mode" "HI")])
1426
1427 ;; For 64BIT abi we always round up to 8 bytes.
1428 (define_insn "*pushqi2_rex64"
1429   [(set (match_operand:QI 0 "push_operand" "=X")
1430         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1431   "TARGET_64BIT"
1432   "push{q}\t%q1"
1433   [(set_attr "type" "push")
1434    (set_attr "mode" "QI")])
1435
1436 ;; Situation is quite tricky about when to choose full sized (SImode) move
1437 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1438 ;; partial register dependency machines (such as AMD Athlon), where QImode
1439 ;; moves issue extra dependency and for partial register stalls machines
1440 ;; that don't use QImode patterns (and QImode move cause stall on the next
1441 ;; instruction).
1442 ;;
1443 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444 ;; register stall machines with, where we use QImode instructions, since
1445 ;; partial register stall can be caused there.  Then we use movzx.
1446 (define_insn "*movqi_1"
1447   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1449   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1450 {
1451   switch (get_attr_type (insn))
1452     {
1453     case TYPE_IMOVX:
1454       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1455         abort ();
1456       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1457     default:
1458       if (get_attr_mode (insn) == MODE_SI)
1459         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1460       else
1461         return "mov{b}\t{%1, %0|%0, %1}";
1462     }
1463 }
1464   [(set (attr "type")
1465      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1466               (const_string "imov")
1467             (and (eq_attr "alternative" "3")
1468                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1469                           (const_int 0))
1470                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1471                           (const_int 0))))
1472               (const_string "imov")
1473             (eq_attr "alternative" "3,5")
1474               (const_string "imovx")
1475             (and (ne (symbol_ref "TARGET_MOVX")
1476                      (const_int 0))
1477                  (eq_attr "alternative" "2"))
1478               (const_string "imovx")
1479            ]
1480            (const_string "imov")))
1481    (set (attr "mode")
1482       (cond [(eq_attr "alternative" "3,4,5")
1483                (const_string "SI")
1484              (eq_attr "alternative" "6")
1485                (const_string "QI")
1486              (eq_attr "type" "imovx")
1487                (const_string "SI")
1488              (and (eq_attr "type" "imov")
1489                   (and (eq_attr "alternative" "0,1,2")
1490                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1491                            (const_int 0))))
1492                (const_string "SI")
1493              ;; Avoid partial register stalls when not using QImode arithmetic
1494              (and (eq_attr "type" "imov")
1495                   (and (eq_attr "alternative" "0,1,2")
1496                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1497                                 (const_int 0))
1498                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1499                                 (const_int 0)))))
1500                (const_string "SI")
1501            ]
1502            (const_string "QI")))])
1503
1504 (define_expand "reload_outqi"
1505   [(parallel [(match_operand:QI 0 "" "=m")
1506               (match_operand:QI 1 "register_operand" "r")
1507               (match_operand:QI 2 "register_operand" "=&q")])]
1508   ""
1509 {
1510   rtx op0, op1, op2;
1511   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1512
1513   if (reg_overlap_mentioned_p (op2, op0))
1514     abort ();
1515   if (! q_regs_operand (op1, QImode))
1516     {
1517       emit_insn (gen_movqi (op2, op1));
1518       op1 = op2;
1519     }
1520   emit_insn (gen_movqi (op0, op1));
1521   DONE;
1522 })
1523
1524 (define_insn "*swapqi"
1525   [(set (match_operand:QI 0 "register_operand" "+r")
1526         (match_operand:QI 1 "register_operand" "+r"))
1527    (set (match_dup 1)
1528         (match_dup 0))]
1529   ""
1530   "xchg{b}\t%1, %0"
1531   [(set_attr "type" "imov")
1532    (set_attr "pent_pair" "np")
1533    (set_attr "mode" "QI")
1534    (set_attr "modrm" "0")])
1535
1536 (define_expand "movstrictqi"
1537   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1538         (match_operand:QI 1 "general_operand" ""))]
1539   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1540 {
1541   /* Don't generate memory->memory moves, go through a register.  */
1542   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1543     operands[1] = force_reg (QImode, operands[1]);
1544 })
1545
1546 (define_insn "*movstrictqi_1"
1547   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1548         (match_operand:QI 1 "general_operand" "*qn,m"))]
1549   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1550    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1551   "mov{b}\t{%1, %0|%0, %1}"
1552   [(set_attr "type" "imov")
1553    (set_attr "mode" "QI")])
1554
1555 (define_insn "*movstrictqi_xor"
1556   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1557         (match_operand:QI 1 "const0_operand" "i"))
1558    (clobber (reg:CC FLAGS_REG))]
1559   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1560   "xor{b}\t{%0, %0|%0, %0}"
1561   [(set_attr "type" "alu1")
1562    (set_attr "mode" "QI")
1563    (set_attr "length_immediate" "0")])
1564
1565 (define_insn "*movsi_extv_1"
1566   [(set (match_operand:SI 0 "register_operand" "=R")
1567         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1568                          (const_int 8)
1569                          (const_int 8)))]
1570   ""
1571   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1572   [(set_attr "type" "imovx")
1573    (set_attr "mode" "SI")])
1574
1575 (define_insn "*movhi_extv_1"
1576   [(set (match_operand:HI 0 "register_operand" "=R")
1577         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1578                          (const_int 8)
1579                          (const_int 8)))]
1580   ""
1581   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1582   [(set_attr "type" "imovx")
1583    (set_attr "mode" "SI")])
1584
1585 (define_insn "*movqi_extv_1"
1586   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1587         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1588                          (const_int 8)
1589                          (const_int 8)))]
1590   "!TARGET_64BIT"
1591 {
1592   switch (get_attr_type (insn))
1593     {
1594     case TYPE_IMOVX:
1595       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1596     default:
1597       return "mov{b}\t{%h1, %0|%0, %h1}";
1598     }
1599 }
1600   [(set (attr "type")
1601      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1602                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1603                              (ne (symbol_ref "TARGET_MOVX")
1604                                  (const_int 0))))
1605         (const_string "imovx")
1606         (const_string "imov")))
1607    (set (attr "mode")
1608      (if_then_else (eq_attr "type" "imovx")
1609         (const_string "SI")
1610         (const_string "QI")))])
1611
1612 (define_insn "*movqi_extv_1_rex64"
1613   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1614         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1615                          (const_int 8)
1616                          (const_int 8)))]
1617   "TARGET_64BIT"
1618 {
1619   switch (get_attr_type (insn))
1620     {
1621     case TYPE_IMOVX:
1622       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1623     default:
1624       return "mov{b}\t{%h1, %0|%0, %h1}";
1625     }
1626 }
1627   [(set (attr "type")
1628      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630                              (ne (symbol_ref "TARGET_MOVX")
1631                                  (const_int 0))))
1632         (const_string "imovx")
1633         (const_string "imov")))
1634    (set (attr "mode")
1635      (if_then_else (eq_attr "type" "imovx")
1636         (const_string "SI")
1637         (const_string "QI")))])
1638
1639 ;; Stores and loads of ax to arbitrary constant address.
1640 ;; We fake an second form of instruction to force reload to load address
1641 ;; into register when rax is not available
1642 (define_insn "*movabsqi_1_rex64"
1643   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1644         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1645   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1646   "@
1647    movabs{b}\t{%1, %P0|%P0, %1}
1648    mov{b}\t{%1, %a0|%a0, %1}"
1649   [(set_attr "type" "imov")
1650    (set_attr "modrm" "0,*")
1651    (set_attr "length_address" "8,0")
1652    (set_attr "length_immediate" "0,*")
1653    (set_attr "memory" "store")
1654    (set_attr "mode" "QI")])
1655
1656 (define_insn "*movabsqi_2_rex64"
1657   [(set (match_operand:QI 0 "register_operand" "=a,r")
1658         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1659   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1660   "@
1661    movabs{b}\t{%P1, %0|%0, %P1}
1662    mov{b}\t{%a1, %0|%0, %a1}"
1663   [(set_attr "type" "imov")
1664    (set_attr "modrm" "0,*")
1665    (set_attr "length_address" "8,0")
1666    (set_attr "length_immediate" "0")
1667    (set_attr "memory" "load")
1668    (set_attr "mode" "QI")])
1669
1670 (define_insn "*movsi_extzv_1"
1671   [(set (match_operand:SI 0 "register_operand" "=R")
1672         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1673                          (const_int 8)
1674                          (const_int 8)))]
1675   ""
1676   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1677   [(set_attr "type" "imovx")
1678    (set_attr "mode" "SI")])
1679
1680 (define_insn "*movqi_extzv_2"
1681   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1682         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1683                                     (const_int 8)
1684                                     (const_int 8)) 0))]
1685   "!TARGET_64BIT"
1686 {
1687   switch (get_attr_type (insn))
1688     {
1689     case TYPE_IMOVX:
1690       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1691     default:
1692       return "mov{b}\t{%h1, %0|%0, %h1}";
1693     }
1694 }
1695   [(set (attr "type")
1696      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1697                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1698                              (ne (symbol_ref "TARGET_MOVX")
1699                                  (const_int 0))))
1700         (const_string "imovx")
1701         (const_string "imov")))
1702    (set (attr "mode")
1703      (if_then_else (eq_attr "type" "imovx")
1704         (const_string "SI")
1705         (const_string "QI")))])
1706
1707 (define_insn "*movqi_extzv_2_rex64"
1708   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1709         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1710                                     (const_int 8)
1711                                     (const_int 8)) 0))]
1712   "TARGET_64BIT"
1713 {
1714   switch (get_attr_type (insn))
1715     {
1716     case TYPE_IMOVX:
1717       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1718     default:
1719       return "mov{b}\t{%h1, %0|%0, %h1}";
1720     }
1721 }
1722   [(set (attr "type")
1723      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1724                         (ne (symbol_ref "TARGET_MOVX")
1725                             (const_int 0)))
1726         (const_string "imovx")
1727         (const_string "imov")))
1728    (set (attr "mode")
1729      (if_then_else (eq_attr "type" "imovx")
1730         (const_string "SI")
1731         (const_string "QI")))])
1732
1733 (define_insn "movsi_insv_1"
1734   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1735                          (const_int 8)
1736                          (const_int 8))
1737         (match_operand:SI 1 "general_operand" "Qmn"))]
1738   "!TARGET_64BIT"
1739   "mov{b}\t{%b1, %h0|%h0, %b1}"
1740   [(set_attr "type" "imov")
1741    (set_attr "mode" "QI")])
1742
1743 (define_insn "movdi_insv_1_rex64"
1744   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1745                          (const_int 8)
1746                          (const_int 8))
1747         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1748   "TARGET_64BIT"
1749   "mov{b}\t{%b1, %h0|%h0, %b1}"
1750   [(set_attr "type" "imov")
1751    (set_attr "mode" "QI")])
1752
1753 (define_insn "*movqi_insv_2"
1754   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1755                          (const_int 8)
1756                          (const_int 8))
1757         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1758                      (const_int 8)))]
1759   ""
1760   "mov{b}\t{%h1, %h0|%h0, %h1}"
1761   [(set_attr "type" "imov")
1762    (set_attr "mode" "QI")])
1763
1764 (define_expand "movdi"
1765   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1766         (match_operand:DI 1 "general_operand" ""))]
1767   ""
1768   "ix86_expand_move (DImode, operands); DONE;")
1769
1770 (define_insn "*pushdi"
1771   [(set (match_operand:DI 0 "push_operand" "=<")
1772         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1773   "!TARGET_64BIT"
1774   "#")
1775
1776 (define_insn "pushdi2_rex64"
1777   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1778         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1779   "TARGET_64BIT"
1780   "@
1781    push{q}\t%1
1782    #"
1783   [(set_attr "type" "push,multi")
1784    (set_attr "mode" "DI")])
1785
1786 ;; Convert impossible pushes of immediate to existing instructions.
1787 ;; First try to get scratch register and go through it.  In case this
1788 ;; fails, push sign extended lower part first and then overwrite
1789 ;; upper part by 32bit move.
1790 (define_peephole2
1791   [(match_scratch:DI 2 "r")
1792    (set (match_operand:DI 0 "push_operand" "")
1793         (match_operand:DI 1 "immediate_operand" ""))]
1794   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1795    && !x86_64_immediate_operand (operands[1], DImode)"
1796   [(set (match_dup 2) (match_dup 1))
1797    (set (match_dup 0) (match_dup 2))]
1798   "")
1799
1800 ;; We need to define this as both peepholer and splitter for case
1801 ;; peephole2 pass is not run.
1802 ;; "&& 1" is needed to keep it from matching the previous pattern.
1803 (define_peephole2
1804   [(set (match_operand:DI 0 "push_operand" "")
1805         (match_operand:DI 1 "immediate_operand" ""))]
1806   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1808   [(set (match_dup 0) (match_dup 1))
1809    (set (match_dup 2) (match_dup 3))]
1810   "split_di (operands + 1, 1, operands + 2, operands + 3);
1811    operands[1] = gen_lowpart (DImode, operands[2]);
1812    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1813                                                     GEN_INT (4)));
1814   ")
1815
1816 (define_split
1817   [(set (match_operand:DI 0 "push_operand" "")
1818         (match_operand:DI 1 "immediate_operand" ""))]
1819   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1820    && !symbolic_operand (operands[1], DImode)
1821    && !x86_64_immediate_operand (operands[1], DImode)"
1822   [(set (match_dup 0) (match_dup 1))
1823    (set (match_dup 2) (match_dup 3))]
1824   "split_di (operands + 1, 1, operands + 2, operands + 3);
1825    operands[1] = gen_lowpart (DImode, operands[2]);
1826    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1827                                                     GEN_INT (4)));
1828   ")
1829
1830 (define_insn "*pushdi2_prologue_rex64"
1831   [(set (match_operand:DI 0 "push_operand" "=<")
1832         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1833    (clobber (mem:BLK (scratch)))]
1834   "TARGET_64BIT"
1835   "push{q}\t%1"
1836   [(set_attr "type" "push")
1837    (set_attr "mode" "DI")])
1838
1839 (define_insn "*popdi1_epilogue_rex64"
1840   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1841         (mem:DI (reg:DI SP_REG)))
1842    (set (reg:DI SP_REG)
1843         (plus:DI (reg:DI SP_REG) (const_int 8)))
1844    (clobber (mem:BLK (scratch)))]
1845   "TARGET_64BIT"
1846   "pop{q}\t%0"
1847   [(set_attr "type" "pop")
1848    (set_attr "mode" "DI")])
1849
1850 (define_insn "popdi1"
1851   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1852         (mem:DI (reg:DI SP_REG)))
1853    (set (reg:DI SP_REG)
1854         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1855   "TARGET_64BIT"
1856   "pop{q}\t%0"
1857   [(set_attr "type" "pop")
1858    (set_attr "mode" "DI")])
1859
1860 (define_insn "*movdi_xor_rex64"
1861   [(set (match_operand:DI 0 "register_operand" "=r")
1862         (match_operand:DI 1 "const0_operand" "i"))
1863    (clobber (reg:CC FLAGS_REG))]
1864   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1865    && reload_completed"
1866   "xor{l}\t{%k0, %k0|%k0, %k0}"
1867   [(set_attr "type" "alu1")
1868    (set_attr "mode" "SI")
1869    (set_attr "length_immediate" "0")])
1870
1871 (define_insn "*movdi_or_rex64"
1872   [(set (match_operand:DI 0 "register_operand" "=r")
1873         (match_operand:DI 1 "const_int_operand" "i"))
1874    (clobber (reg:CC FLAGS_REG))]
1875   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1876    && reload_completed
1877    && operands[1] == constm1_rtx"
1878 {
1879   operands[1] = constm1_rtx;
1880   return "or{q}\t{%1, %0|%0, %1}";
1881 }
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "DI")
1884    (set_attr "length_immediate" "1")])
1885
1886 (define_insn "*movdi_2"
1887   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1888         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1889   "!TARGET_64BIT
1890    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1891   "@
1892    #
1893    #
1894    movq\t{%1, %0|%0, %1}
1895    movq\t{%1, %0|%0, %1}
1896    movq\t{%1, %0|%0, %1}
1897    movdqa\t{%1, %0|%0, %1}
1898    movq\t{%1, %0|%0, %1}"
1899   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1900    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1901
1902 (define_split
1903   [(set (match_operand:DI 0 "push_operand" "")
1904         (match_operand:DI 1 "general_operand" ""))]
1905   "!TARGET_64BIT && reload_completed
1906    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1907   [(const_int 0)]
1908   "ix86_split_long_move (operands); DONE;")
1909
1910 ;; %%% This multiword shite has got to go.
1911 (define_split
1912   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1913         (match_operand:DI 1 "general_operand" ""))]
1914   "!TARGET_64BIT && reload_completed
1915    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1916    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1917   [(const_int 0)]
1918   "ix86_split_long_move (operands); DONE;")
1919
1920 (define_insn "*movdi_1_rex64"
1921   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1922         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1923   "TARGET_64BIT
1924    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1925    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1926 {
1927   switch (get_attr_type (insn))
1928     {
1929     case TYPE_SSECVT:
1930       if (which_alternative == 11)
1931         return "movq2dq\t{%1, %0|%0, %1}";
1932       else
1933         return "movdq2q\t{%1, %0|%0, %1}";
1934     case TYPE_SSEMOV:
1935       if (get_attr_mode (insn) == MODE_TI)
1936           return "movdqa\t{%1, %0|%0, %1}";
1937       /* FALLTHRU */
1938     case TYPE_MMXMOV:
1939       /* Moves from and into integer register is done using movd opcode with
1940          REX prefix.  */
1941       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942           return "movd\t{%1, %0|%0, %1}";
1943       return "movq\t{%1, %0|%0, %1}";
1944     case TYPE_MULTI:
1945       return "#";
1946     case TYPE_LEA:
1947       return "lea{q}\t{%a1, %0|%0, %a1}";
1948     default:
1949       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1950         abort ();
1951       if (get_attr_mode (insn) == MODE_SI)
1952         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1953       else if (which_alternative == 2)
1954         return "movabs{q}\t{%1, %0|%0, %1}";
1955       else
1956         return "mov{q}\t{%1, %0|%0, %1}";
1957     }
1958 }
1959   [(set (attr "type")
1960      (cond [(eq_attr "alternative" "5,6,7")
1961               (const_string "mmxmov")
1962             (eq_attr "alternative" "8,9,10")
1963               (const_string "ssemov")
1964             (eq_attr "alternative" "11,12")
1965               (const_string "ssecvt")
1966             (eq_attr "alternative" "4")
1967               (const_string "multi")
1968             (and (ne (symbol_ref "flag_pic") (const_int 0))
1969                  (match_operand:DI 1 "symbolic_operand" ""))
1970               (const_string "lea")
1971            ]
1972            (const_string "imov")))
1973    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1974    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1975    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1976
1977 (define_insn "*movdi_1_rex64_nointerunit"
1978   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1979         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1980   "TARGET_64BIT
1981    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1982    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1983 {
1984   switch (get_attr_type (insn))
1985     {
1986     case TYPE_SSEMOV:
1987       if (get_attr_mode (insn) == MODE_TI)
1988           return "movdqa\t{%1, %0|%0, %1}";
1989       /* FALLTHRU */
1990     case TYPE_MMXMOV:
1991       return "movq\t{%1, %0|%0, %1}";
1992     case TYPE_MULTI:
1993       return "#";
1994     case TYPE_LEA:
1995       return "lea{q}\t{%a1, %0|%0, %a1}";
1996     default:
1997       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1998         abort ();
1999       if (get_attr_mode (insn) == MODE_SI)
2000         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2001       else if (which_alternative == 2)
2002         return "movabs{q}\t{%1, %0|%0, %1}";
2003       else
2004         return "mov{q}\t{%1, %0|%0, %1}";
2005     }
2006 }
2007   [(set (attr "type")
2008      (cond [(eq_attr "alternative" "5,6,7")
2009               (const_string "mmxmov")
2010             (eq_attr "alternative" "8,9,10")
2011               (const_string "ssemov")
2012             (eq_attr "alternative" "4")
2013               (const_string "multi")
2014             (and (ne (symbol_ref "flag_pic") (const_int 0))
2015                  (match_operand:DI 1 "symbolic_operand" ""))
2016               (const_string "lea")
2017            ]
2018            (const_string "imov")))
2019    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2020    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2021    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2022
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsdi_1_rex64"
2027   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2029   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030   "@
2031    movabs{q}\t{%1, %P0|%P0, %1}
2032    mov{q}\t{%1, %a0|%a0, %1}"
2033   [(set_attr "type" "imov")
2034    (set_attr "modrm" "0,*")
2035    (set_attr "length_address" "8,0")
2036    (set_attr "length_immediate" "0,*")
2037    (set_attr "memory" "store")
2038    (set_attr "mode" "DI")])
2039
2040 (define_insn "*movabsdi_2_rex64"
2041   [(set (match_operand:DI 0 "register_operand" "=a,r")
2042         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044   "@
2045    movabs{q}\t{%P1, %0|%0, %P1}
2046    mov{q}\t{%a1, %0|%0, %a1}"
2047   [(set_attr "type" "imov")
2048    (set_attr "modrm" "0,*")
2049    (set_attr "length_address" "8,0")
2050    (set_attr "length_immediate" "0")
2051    (set_attr "memory" "load")
2052    (set_attr "mode" "DI")])
2053
2054 ;; Convert impossible stores of immediate to existing instructions.
2055 ;; First try to get scratch register and go through it.  In case this
2056 ;; fails, move by 32bit parts.
2057 (define_peephole2
2058   [(match_scratch:DI 2 "r")
2059    (set (match_operand:DI 0 "memory_operand" "")
2060         (match_operand:DI 1 "immediate_operand" ""))]
2061   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2062    && !x86_64_immediate_operand (operands[1], DImode)"
2063   [(set (match_dup 2) (match_dup 1))
2064    (set (match_dup 0) (match_dup 2))]
2065   "")
2066
2067 ;; We need to define this as both peepholer and splitter for case
2068 ;; peephole2 pass is not run.
2069 ;; "&& 1" is needed to keep it from matching the previous pattern.
2070 (define_peephole2
2071   [(set (match_operand:DI 0 "memory_operand" "")
2072         (match_operand:DI 1 "immediate_operand" ""))]
2073   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2075   [(set (match_dup 2) (match_dup 3))
2076    (set (match_dup 4) (match_dup 5))]
2077   "split_di (operands, 2, operands + 2, operands + 4);")
2078
2079 (define_split
2080   [(set (match_operand:DI 0 "memory_operand" "")
2081         (match_operand:DI 1 "immediate_operand" ""))]
2082   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2083    && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode)"
2085   [(set (match_dup 2) (match_dup 3))
2086    (set (match_dup 4) (match_dup 5))]
2087   "split_di (operands, 2, operands + 2, operands + 4);")
2088
2089 (define_insn "*swapdi_rex64"
2090   [(set (match_operand:DI 0 "register_operand" "+r")
2091         (match_operand:DI 1 "register_operand" "+r"))
2092    (set (match_dup 1)
2093         (match_dup 0))]
2094   "TARGET_64BIT"
2095   "xchg{q}\t%1, %0"
2096   [(set_attr "type" "imov")
2097    (set_attr "pent_pair" "np")
2098    (set_attr "athlon_decode" "vector")
2099    (set_attr "mode" "DI")
2100    (set_attr "modrm" "0")])
2101
2102   
2103 (define_expand "movsf"
2104   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2105         (match_operand:SF 1 "general_operand" ""))]
2106   ""
2107   "ix86_expand_move (SFmode, operands); DONE;")
2108
2109 (define_insn "*pushsf"
2110   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2111         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2112   "!TARGET_64BIT"
2113 {
2114   switch (which_alternative)
2115     {
2116     case 1:
2117       return "push{l}\t%1";
2118
2119     default:
2120       /* This insn should be already split before reg-stack.  */
2121       abort ();
2122     }
2123 }
2124   [(set_attr "type" "multi,push,multi")
2125    (set_attr "mode" "SF,SI,SF")])
2126
2127 (define_insn "*pushsf_rex64"
2128   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2129         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2130   "TARGET_64BIT"
2131 {
2132   switch (which_alternative)
2133     {
2134     case 1:
2135       return "push{q}\t%q1";
2136
2137     default:
2138       /* This insn should be already split before reg-stack.  */
2139       abort ();
2140     }
2141 }
2142   [(set_attr "type" "multi,push,multi")
2143    (set_attr "mode" "SF,DI,SF")])
2144
2145 (define_split
2146   [(set (match_operand:SF 0 "push_operand" "")
2147         (match_operand:SF 1 "memory_operand" ""))]
2148   "reload_completed
2149    && GET_CODE (operands[1]) == MEM
2150    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2151    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2152   [(set (match_dup 0)
2153         (match_dup 1))]
2154   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2155
2156
2157 ;; %%% Kill this when call knows how to work this out.
2158 (define_split
2159   [(set (match_operand:SF 0 "push_operand" "")
2160         (match_operand:SF 1 "any_fp_register_operand" ""))]
2161   "!TARGET_64BIT"
2162   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2163    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2164
2165 (define_split
2166   [(set (match_operand:SF 0 "push_operand" "")
2167         (match_operand:SF 1 "any_fp_register_operand" ""))]
2168   "TARGET_64BIT"
2169   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2170    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2171
2172 (define_insn "*movsf_1"
2173   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2174         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2175   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2176    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2177    && (reload_in_progress || reload_completed
2178        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2179        || GET_CODE (operands[1]) != CONST_DOUBLE
2180        || memory_operand (operands[0], SFmode))" 
2181 {
2182   switch (which_alternative)
2183     {
2184     case 0:
2185       return output_387_reg_move (insn, operands);
2186
2187     case 1:
2188       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2189         return "fstp%z0\t%y0";
2190       else
2191         return "fst%z0\t%y0";
2192
2193     case 2:
2194       return standard_80387_constant_opcode (operands[1]);
2195
2196     case 3:
2197     case 4:
2198       return "mov{l}\t{%1, %0|%0, %1}";
2199     case 5:
2200       if (get_attr_mode (insn) == MODE_TI)
2201         return "pxor\t%0, %0";
2202       else
2203         return "xorps\t%0, %0";
2204     case 6:
2205       if (get_attr_mode (insn) == MODE_V4SF)
2206         return "movaps\t{%1, %0|%0, %1}";
2207       else
2208         return "movss\t{%1, %0|%0, %1}";
2209     case 7:
2210     case 8:
2211       return "movss\t{%1, %0|%0, %1}";
2212
2213     case 9:
2214     case 10:
2215       return "movd\t{%1, %0|%0, %1}";
2216
2217     case 11:
2218       return "movq\t{%1, %0|%0, %1}";
2219
2220     default:
2221       abort();
2222     }
2223 }
2224   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2225    (set (attr "mode")
2226         (cond [(eq_attr "alternative" "3,4,9,10")
2227                  (const_string "SI")
2228                (eq_attr "alternative" "5")
2229                  (if_then_else
2230                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2231                                  (const_int 0))
2232                              (ne (symbol_ref "TARGET_SSE2")
2233                                  (const_int 0)))
2234                         (eq (symbol_ref "optimize_size")
2235                             (const_int 0)))
2236                    (const_string "TI")
2237                    (const_string "V4SF"))
2238                /* For architectures resolving dependencies on
2239                   whole SSE registers use APS move to break dependency
2240                   chains, otherwise use short move to avoid extra work. 
2241
2242                   Do the same for architectures resolving dependencies on
2243                   the parts.  While in DF mode it is better to always handle
2244                   just register parts, the SF mode is different due to lack
2245                   of instructions to load just part of the register.  It is
2246                   better to maintain the whole registers in single format
2247                   to avoid problems on using packed logical operations.  */
2248                (eq_attr "alternative" "6")
2249                  (if_then_else
2250                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2251                             (const_int 0))
2252                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2253                             (const_int 0)))
2254                    (const_string "V4SF")
2255                    (const_string "SF"))
2256                (eq_attr "alternative" "11")
2257                  (const_string "DI")]
2258                (const_string "SF")))])
2259
2260 (define_insn "*movsf_1_nointerunit"
2261   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2262         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2263   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2264    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2265    && (reload_in_progress || reload_completed
2266        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2267        || GET_CODE (operands[1]) != CONST_DOUBLE
2268        || memory_operand (operands[0], SFmode))" 
2269 {
2270   switch (which_alternative)
2271     {
2272     case 0:
2273       return output_387_reg_move (insn, operands);
2274
2275     case 1:
2276       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2277         return "fstp%z0\t%y0";
2278       else
2279         return "fst%z0\t%y0";
2280
2281     case 2:
2282       return standard_80387_constant_opcode (operands[1]);
2283
2284     case 3:
2285     case 4:
2286       return "mov{l}\t{%1, %0|%0, %1}";
2287     case 5:
2288       if (get_attr_mode (insn) == MODE_TI)
2289         return "pxor\t%0, %0";
2290       else
2291         return "xorps\t%0, %0";
2292     case 6:
2293       if (get_attr_mode (insn) == MODE_V4SF)
2294         return "movaps\t{%1, %0|%0, %1}";
2295       else
2296         return "movss\t{%1, %0|%0, %1}";
2297     case 7:
2298     case 8:
2299       return "movss\t{%1, %0|%0, %1}";
2300
2301     case 9:
2302     case 10:
2303       return "movd\t{%1, %0|%0, %1}";
2304
2305     case 11:
2306       return "movq\t{%1, %0|%0, %1}";
2307
2308     default:
2309       abort();
2310     }
2311 }
2312   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2313    (set (attr "mode")
2314         (cond [(eq_attr "alternative" "3,4,9,10")
2315                  (const_string "SI")
2316                (eq_attr "alternative" "5")
2317                  (if_then_else
2318                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2319                                  (const_int 0))
2320                              (ne (symbol_ref "TARGET_SSE2")
2321                                  (const_int 0)))
2322                         (eq (symbol_ref "optimize_size")
2323                             (const_int 0)))
2324                    (const_string "TI")
2325                    (const_string "V4SF"))
2326                /* For architectures resolving dependencies on
2327                   whole SSE registers use APS move to break dependency
2328                   chains, otherwise use short move to avoid extra work. 
2329
2330                   Do the same for architectures resolving dependencies on
2331                   the parts.  While in DF mode it is better to always handle
2332                   just register parts, the SF mode is different due to lack
2333                   of instructions to load just part of the register.  It is
2334                   better to maintain the whole registers in single format
2335                   to avoid problems on using packed logical operations.  */
2336                (eq_attr "alternative" "6")
2337                  (if_then_else
2338                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2339                             (const_int 0))
2340                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2341                             (const_int 0)))
2342                    (const_string "V4SF")
2343                    (const_string "SF"))
2344                (eq_attr "alternative" "11")
2345                  (const_string "DI")]
2346                (const_string "SF")))])
2347
2348 (define_insn "*swapsf"
2349   [(set (match_operand:SF 0 "register_operand" "+f")
2350         (match_operand:SF 1 "register_operand" "+f"))
2351    (set (match_dup 1)
2352         (match_dup 0))]
2353   "reload_completed || !TARGET_SSE"
2354 {
2355   if (STACK_TOP_P (operands[0]))
2356     return "fxch\t%1";
2357   else
2358     return "fxch\t%0";
2359 }
2360   [(set_attr "type" "fxch")
2361    (set_attr "mode" "SF")])
2362
2363 (define_expand "movdf"
2364   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2365         (match_operand:DF 1 "general_operand" ""))]
2366   ""
2367   "ix86_expand_move (DFmode, operands); DONE;")
2368
2369 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2370 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2371 ;; On the average, pushdf using integers can be still shorter.  Allow this
2372 ;; pattern for optimize_size too.
2373
2374 (define_insn "*pushdf_nointeger"
2375   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2376         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2377   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2378 {
2379   /* This insn should be already split before reg-stack.  */
2380   abort ();
2381 }
2382   [(set_attr "type" "multi")
2383    (set_attr "mode" "DF,SI,SI,DF")])
2384
2385 (define_insn "*pushdf_integer"
2386   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2387         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2388   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2389 {
2390   /* This insn should be already split before reg-stack.  */
2391   abort ();
2392 }
2393   [(set_attr "type" "multi")
2394    (set_attr "mode" "DF,SI,DF")])
2395
2396 ;; %%% Kill this when call knows how to work this out.
2397 (define_split
2398   [(set (match_operand:DF 0 "push_operand" "")
2399         (match_operand:DF 1 "any_fp_register_operand" ""))]
2400   "!TARGET_64BIT && reload_completed"
2401   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2402    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2403   "")
2404
2405 (define_split
2406   [(set (match_operand:DF 0 "push_operand" "")
2407         (match_operand:DF 1 "any_fp_register_operand" ""))]
2408   "TARGET_64BIT && reload_completed"
2409   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2410    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2411   "")
2412
2413 (define_split
2414   [(set (match_operand:DF 0 "push_operand" "")
2415         (match_operand:DF 1 "general_operand" ""))]
2416   "reload_completed"
2417   [(const_int 0)]
2418   "ix86_split_long_move (operands); DONE;")
2419
2420 ;; Moving is usually shorter when only FP registers are used. This separate
2421 ;; movdf pattern avoids the use of integer registers for FP operations
2422 ;; when optimizing for size.
2423
2424 (define_insn "*movdf_nointeger"
2425   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2426         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2427   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2428    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2429    && (reload_in_progress || reload_completed
2430        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2431        || GET_CODE (operands[1]) != CONST_DOUBLE
2432        || memory_operand (operands[0], DFmode))" 
2433 {
2434   switch (which_alternative)
2435     {
2436     case 0:
2437       return output_387_reg_move (insn, operands);
2438
2439     case 1:
2440       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2441         return "fstp%z0\t%y0";
2442       else
2443         return "fst%z0\t%y0";
2444
2445     case 2:
2446       return standard_80387_constant_opcode (operands[1]);
2447
2448     case 3:
2449     case 4:
2450       return "#";
2451     case 5:
2452       switch (get_attr_mode (insn))
2453         {
2454         case MODE_V4SF:
2455           return "xorps\t%0, %0";
2456         case MODE_V2DF:
2457           return "xorpd\t%0, %0";
2458         case MODE_TI:
2459           return "pxor\t%0, %0";
2460         default:
2461           abort ();
2462         }
2463     case 6:
2464       switch (get_attr_mode (insn))
2465         {
2466         case MODE_V4SF:
2467           return "movaps\t{%1, %0|%0, %1}";
2468         case MODE_V2DF:
2469           return "movapd\t{%1, %0|%0, %1}";
2470         case MODE_DF:
2471           return "movsd\t{%1, %0|%0, %1}";
2472         default:
2473           abort ();
2474         }
2475     case 7:
2476       if (get_attr_mode (insn) == MODE_V2DF)
2477         return "movlpd\t{%1, %0|%0, %1}";
2478       else
2479         return "movsd\t{%1, %0|%0, %1}";
2480     case 8:
2481       return "movsd\t{%1, %0|%0, %1}";
2482
2483     default:
2484       abort();
2485     }
2486 }
2487   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2488    (set (attr "mode")
2489         (cond [(eq_attr "alternative" "3,4")
2490                  (const_string "SI")
2491                /* xorps is one byte shorter.  */
2492                (eq_attr "alternative" "5")
2493                  (cond [(ne (symbol_ref "optimize_size")
2494                             (const_int 0))
2495                           (const_string "V4SF")
2496                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2497                             (const_int 0))
2498                           (const_string "TI")]
2499                        (const_string "V2DF"))
2500                /* For architectures resolving dependencies on
2501                   whole SSE registers use APD move to break dependency
2502                   chains, otherwise use short move to avoid extra work.
2503
2504                   movaps encodes one byte shorter.  */
2505                (eq_attr "alternative" "6")
2506                  (cond
2507                   [(ne (symbol_ref "optimize_size")
2508                        (const_int 0))
2509                      (const_string "V4SF")
2510                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2511                        (const_int 0))
2512                      (const_string "V2DF")]
2513                    (const_string "DF"))
2514                /* For architectures resolving dependencies on register
2515                   parts we may avoid extra work to zero out upper part
2516                   of register.  */
2517                (eq_attr "alternative" "7")
2518                  (if_then_else
2519                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2520                        (const_int 0))
2521                    (const_string "V2DF")
2522                    (const_string "DF"))]
2523                (const_string "DF")))])
2524
2525 (define_insn "*movdf_integer"
2526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2527         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2528   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2529    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2530    && (reload_in_progress || reload_completed
2531        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2532        || GET_CODE (operands[1]) != CONST_DOUBLE
2533        || memory_operand (operands[0], DFmode))" 
2534 {
2535   switch (which_alternative)
2536     {
2537     case 0:
2538       return output_387_reg_move (insn, operands);
2539
2540     case 1:
2541       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2542         return "fstp%z0\t%y0";
2543       else
2544         return "fst%z0\t%y0";
2545
2546     case 2:
2547       return standard_80387_constant_opcode (operands[1]);
2548
2549     case 3:
2550     case 4:
2551       return "#";
2552
2553     case 5:
2554       switch (get_attr_mode (insn))
2555         {
2556         case MODE_V4SF:
2557           return "xorps\t%0, %0";
2558         case MODE_V2DF:
2559           return "xorpd\t%0, %0";
2560         case MODE_TI:
2561           return "pxor\t%0, %0";
2562         default:
2563           abort ();
2564         }
2565     case 6:
2566       switch (get_attr_mode (insn))
2567         {
2568         case MODE_V4SF:
2569           return "movaps\t{%1, %0|%0, %1}";
2570         case MODE_V2DF:
2571           return "movapd\t{%1, %0|%0, %1}";
2572         case MODE_DF:
2573           return "movsd\t{%1, %0|%0, %1}";
2574         default:
2575           abort ();
2576         }
2577     case 7:
2578       if (get_attr_mode (insn) == MODE_V2DF)
2579         return "movlpd\t{%1, %0|%0, %1}";
2580       else
2581         return "movsd\t{%1, %0|%0, %1}";
2582     case 8:
2583       return "movsd\t{%1, %0|%0, %1}";
2584
2585     default:
2586       abort();
2587     }
2588 }
2589   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2590    (set (attr "mode")
2591         (cond [(eq_attr "alternative" "3,4")
2592                  (const_string "SI")
2593                /* xorps is one byte shorter.  */
2594                (eq_attr "alternative" "5")
2595                  (cond [(ne (symbol_ref "optimize_size")
2596                             (const_int 0))
2597                           (const_string "V4SF")
2598                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2599                             (const_int 0))
2600                           (const_string "TI")]
2601                        (const_string "V2DF"))
2602                /* For architectures resolving dependencies on
2603                   whole SSE registers use APD move to break dependency
2604                   chains, otherwise use short move to avoid extra work.  
2605
2606                   movaps encodes one byte shorter.  */
2607                (eq_attr "alternative" "6")
2608                  (cond
2609                   [(ne (symbol_ref "optimize_size")
2610                        (const_int 0))
2611                      (const_string "V4SF")
2612                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2613                        (const_int 0))
2614                      (const_string "V2DF")]
2615                    (const_string "DF"))
2616                /* For architectures resolving dependencies on register
2617                   parts we may avoid extra work to zero out upper part
2618                   of register.  */
2619                (eq_attr "alternative" "7")
2620                  (if_then_else
2621                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2622                        (const_int 0))
2623                    (const_string "V2DF")
2624                    (const_string "DF"))]
2625                (const_string "DF")))])
2626
2627 (define_split
2628   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2629         (match_operand:DF 1 "general_operand" ""))]
2630   "reload_completed
2631    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2632    && ! (ANY_FP_REG_P (operands[0]) || 
2633          (GET_CODE (operands[0]) == SUBREG
2634           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2635    && ! (ANY_FP_REG_P (operands[1]) || 
2636          (GET_CODE (operands[1]) == SUBREG
2637           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2638   [(const_int 0)]
2639   "ix86_split_long_move (operands); DONE;")
2640
2641 (define_insn "*swapdf"
2642   [(set (match_operand:DF 0 "register_operand" "+f")
2643         (match_operand:DF 1 "register_operand" "+f"))
2644    (set (match_dup 1)
2645         (match_dup 0))]
2646   "reload_completed || !TARGET_SSE2"
2647 {
2648   if (STACK_TOP_P (operands[0]))
2649     return "fxch\t%1";
2650   else
2651     return "fxch\t%0";
2652 }
2653   [(set_attr "type" "fxch")
2654    (set_attr "mode" "DF")])
2655
2656 (define_expand "movxf"
2657   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2658         (match_operand:XF 1 "general_operand" ""))]
2659   ""
2660   "ix86_expand_move (XFmode, operands); DONE;")
2661
2662 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references.
2666 ;; (assuming that any given constant is pushed only once, but this ought to be
2667 ;;  handled elsewhere).
2668
2669 (define_insn "*pushxf_nointeger"
2670   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2671         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2672   "optimize_size"
2673 {
2674   /* This insn should be already split before reg-stack.  */
2675   abort ();
2676 }
2677   [(set_attr "type" "multi")
2678    (set_attr "mode" "XF,SI,SI")])
2679
2680 (define_insn "*pushxf_integer"
2681   [(set (match_operand:XF 0 "push_operand" "=<,<")
2682         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2683   "!optimize_size"
2684 {
2685   /* This insn should be already split before reg-stack.  */
2686   abort ();
2687 }
2688   [(set_attr "type" "multi")
2689    (set_attr "mode" "XF,SI")])
2690
2691 (define_split
2692   [(set (match_operand 0 "push_operand" "")
2693         (match_operand 1 "general_operand" ""))]
2694   "reload_completed
2695    && (GET_MODE (operands[0]) == XFmode
2696        || GET_MODE (operands[0]) == DFmode)
2697    && !ANY_FP_REG_P (operands[1])"
2698   [(const_int 0)]
2699   "ix86_split_long_move (operands); DONE;")
2700
2701 (define_split
2702   [(set (match_operand:XF 0 "push_operand" "")
2703         (match_operand:XF 1 "any_fp_register_operand" ""))]
2704   "!TARGET_64BIT"
2705   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2706    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2707   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2708
2709 (define_split
2710   [(set (match_operand:XF 0 "push_operand" "")
2711         (match_operand:XF 1 "any_fp_register_operand" ""))]
2712   "TARGET_64BIT"
2713   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2714    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2715   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2716
2717 ;; Do not use integer registers when optimizing for size
2718 (define_insn "*movxf_nointeger"
2719   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2720         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2721   "optimize_size
2722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2723    && (reload_in_progress || reload_completed
2724        || GET_CODE (operands[1]) != CONST_DOUBLE
2725        || memory_operand (operands[0], XFmode))" 
2726 {
2727   switch (which_alternative)
2728     {
2729     case 0:
2730       return output_387_reg_move (insn, operands);
2731
2732     case 1:
2733       /* There is no non-popping store to memory for XFmode.  So if
2734          we need one, follow the store with a load.  */
2735       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2736         return "fstp%z0\t%y0\;fld%z0\t%y0";
2737       else
2738         return "fstp%z0\t%y0";
2739
2740     case 2:
2741       return standard_80387_constant_opcode (operands[1]);
2742
2743     case 3: case 4:
2744       return "#";
2745     }
2746   abort();
2747 }
2748   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2749    (set_attr "mode" "XF,XF,XF,SI,SI")])
2750
2751 (define_insn "*movxf_integer"
2752   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2753         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2754   "!optimize_size
2755    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2756    && (reload_in_progress || reload_completed
2757        || GET_CODE (operands[1]) != CONST_DOUBLE
2758        || memory_operand (operands[0], XFmode))" 
2759 {
2760   switch (which_alternative)
2761     {
2762     case 0:
2763       return output_387_reg_move (insn, operands);
2764
2765     case 1:
2766       /* There is no non-popping store to memory for XFmode.  So if
2767          we need one, follow the store with a load.  */
2768       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2769         return "fstp%z0\t%y0\;fld%z0\t%y0";
2770       else
2771         return "fstp%z0\t%y0";
2772
2773     case 2:
2774       return standard_80387_constant_opcode (operands[1]);
2775
2776     case 3: case 4:
2777       return "#";
2778     }
2779   abort();
2780 }
2781   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2782    (set_attr "mode" "XF,XF,XF,SI,SI")])
2783
2784 (define_split
2785   [(set (match_operand 0 "nonimmediate_operand" "")
2786         (match_operand 1 "general_operand" ""))]
2787   "reload_completed
2788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789    && GET_MODE (operands[0]) == XFmode
2790    && ! (ANY_FP_REG_P (operands[0]) || 
2791          (GET_CODE (operands[0]) == SUBREG
2792           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2793    && ! (ANY_FP_REG_P (operands[1]) || 
2794          (GET_CODE (operands[1]) == SUBREG
2795           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2796   [(const_int 0)]
2797   "ix86_split_long_move (operands); DONE;")
2798
2799 (define_split
2800   [(set (match_operand 0 "register_operand" "")
2801         (match_operand 1 "memory_operand" ""))]
2802   "reload_completed
2803    && GET_CODE (operands[1]) == MEM
2804    && (GET_MODE (operands[0]) == XFmode
2805        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2806    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2807    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2808   [(set (match_dup 0) (match_dup 1))]
2809 {
2810   rtx c = get_pool_constant (XEXP (operands[1], 0));
2811   rtx r = operands[0];
2812
2813   if (GET_CODE (r) == SUBREG)
2814     r = SUBREG_REG (r);
2815
2816   if (SSE_REG_P (r))
2817     {
2818       if (!standard_sse_constant_p (c))
2819         FAIL;
2820     }
2821   else if (FP_REG_P (r))
2822     {
2823       if (!standard_80387_constant_p (c))
2824         FAIL;
2825     }
2826   else if (MMX_REG_P (r))
2827     FAIL;
2828
2829   operands[1] = c;
2830 })
2831
2832 (define_insn "swapxf"
2833   [(set (match_operand:XF 0 "register_operand" "+f")
2834         (match_operand:XF 1 "register_operand" "+f"))
2835    (set (match_dup 1)
2836         (match_dup 0))]
2837   ""
2838 {
2839   if (STACK_TOP_P (operands[0]))
2840     return "fxch\t%1";
2841   else
2842     return "fxch\t%0";
2843 }
2844   [(set_attr "type" "fxch")
2845    (set_attr "mode" "XF")])
2846 \f
2847 ;; Zero extension instructions
2848
2849 (define_expand "zero_extendhisi2"
2850   [(set (match_operand:SI 0 "register_operand" "")
2851      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2852   ""
2853 {
2854   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2855     {
2856       operands[1] = force_reg (HImode, operands[1]);
2857       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2858       DONE;
2859     }
2860 })
2861
2862 (define_insn "zero_extendhisi2_and"
2863   [(set (match_operand:SI 0 "register_operand" "=r")
2864      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2865    (clobber (reg:CC FLAGS_REG))]
2866   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2867   "#"
2868   [(set_attr "type" "alu1")
2869    (set_attr "mode" "SI")])
2870
2871 (define_split
2872   [(set (match_operand:SI 0 "register_operand" "")
2873         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2874    (clobber (reg:CC FLAGS_REG))]
2875   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2876   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2877               (clobber (reg:CC FLAGS_REG))])]
2878   "")
2879
2880 (define_insn "*zero_extendhisi2_movzwl"
2881   [(set (match_operand:SI 0 "register_operand" "=r")
2882      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2883   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2884   "movz{wl|x}\t{%1, %0|%0, %1}"
2885   [(set_attr "type" "imovx")
2886    (set_attr "mode" "SI")])
2887
2888 (define_expand "zero_extendqihi2"
2889   [(parallel
2890     [(set (match_operand:HI 0 "register_operand" "")
2891        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2892      (clobber (reg:CC FLAGS_REG))])]
2893   ""
2894   "")
2895
2896 (define_insn "*zero_extendqihi2_and"
2897   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2898      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2899    (clobber (reg:CC FLAGS_REG))]
2900   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2901   "#"
2902   [(set_attr "type" "alu1")
2903    (set_attr "mode" "HI")])
2904
2905 (define_insn "*zero_extendqihi2_movzbw_and"
2906   [(set (match_operand:HI 0 "register_operand" "=r,r")
2907      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2908    (clobber (reg:CC FLAGS_REG))]
2909   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2910   "#"
2911   [(set_attr "type" "imovx,alu1")
2912    (set_attr "mode" "HI")])
2913
2914 (define_insn "*zero_extendqihi2_movzbw"
2915   [(set (match_operand:HI 0 "register_operand" "=r")
2916      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2917   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2918   "movz{bw|x}\t{%1, %0|%0, %1}"
2919   [(set_attr "type" "imovx")
2920    (set_attr "mode" "HI")])
2921
2922 ;; For the movzbw case strip only the clobber
2923 (define_split
2924   [(set (match_operand:HI 0 "register_operand" "")
2925         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2926    (clobber (reg:CC FLAGS_REG))]
2927   "reload_completed 
2928    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2929    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2930   [(set (match_operand:HI 0 "register_operand" "")
2931         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2932
2933 ;; When source and destination does not overlap, clear destination
2934 ;; first and then do the movb
2935 (define_split
2936   [(set (match_operand:HI 0 "register_operand" "")
2937         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2938    (clobber (reg:CC FLAGS_REG))]
2939   "reload_completed
2940    && ANY_QI_REG_P (operands[0])
2941    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2942    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2943   [(set (match_dup 0) (const_int 0))
2944    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2945   "operands[2] = gen_lowpart (QImode, operands[0]);")
2946
2947 ;; Rest is handled by single and.
2948 (define_split
2949   [(set (match_operand:HI 0 "register_operand" "")
2950         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2951    (clobber (reg:CC FLAGS_REG))]
2952   "reload_completed
2953    && true_regnum (operands[0]) == true_regnum (operands[1])"
2954   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2955               (clobber (reg:CC FLAGS_REG))])]
2956   "")
2957
2958 (define_expand "zero_extendqisi2"
2959   [(parallel
2960     [(set (match_operand:SI 0 "register_operand" "")
2961        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2962      (clobber (reg:CC FLAGS_REG))])]
2963   ""
2964   "")
2965
2966 (define_insn "*zero_extendqisi2_and"
2967   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2968      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2969    (clobber (reg:CC FLAGS_REG))]
2970   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2971   "#"
2972   [(set_attr "type" "alu1")
2973    (set_attr "mode" "SI")])
2974
2975 (define_insn "*zero_extendqisi2_movzbw_and"
2976   [(set (match_operand:SI 0 "register_operand" "=r,r")
2977      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2978    (clobber (reg:CC FLAGS_REG))]
2979   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2980   "#"
2981   [(set_attr "type" "imovx,alu1")
2982    (set_attr "mode" "SI")])
2983
2984 (define_insn "*zero_extendqisi2_movzbw"
2985   [(set (match_operand:SI 0 "register_operand" "=r")
2986      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2987   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2988   "movz{bl|x}\t{%1, %0|%0, %1}"
2989   [(set_attr "type" "imovx")
2990    (set_attr "mode" "SI")])
2991
2992 ;; For the movzbl case strip only the clobber
2993 (define_split
2994   [(set (match_operand:SI 0 "register_operand" "")
2995         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2996    (clobber (reg:CC FLAGS_REG))]
2997   "reload_completed 
2998    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2999    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3000   [(set (match_dup 0)
3001         (zero_extend:SI (match_dup 1)))])
3002
3003 ;; When source and destination does not overlap, clear destination
3004 ;; first and then do the movb
3005 (define_split
3006   [(set (match_operand:SI 0 "register_operand" "")
3007         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && ANY_QI_REG_P (operands[0])
3011    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3012    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3013    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3014   [(set (match_dup 0) (const_int 0))
3015    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3016   "operands[2] = gen_lowpart (QImode, operands[0]);")
3017
3018 ;; Rest is handled by single and.
3019 (define_split
3020   [(set (match_operand:SI 0 "register_operand" "")
3021         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "reload_completed
3024    && true_regnum (operands[0]) == true_regnum (operands[1])"
3025   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3026               (clobber (reg:CC FLAGS_REG))])]
3027   "")
3028
3029 ;; %%% Kill me once multi-word ops are sane.
3030 (define_expand "zero_extendsidi2"
3031   [(set (match_operand:DI 0 "register_operand" "=r")
3032      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3033   ""
3034   "if (!TARGET_64BIT)
3035      {
3036        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3037        DONE;
3038      }
3039   ")
3040
3041 (define_insn "zero_extendsidi2_32"
3042   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3043         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3044    (clobber (reg:CC FLAGS_REG))]
3045   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3046   "@
3047    #
3048    #
3049    #
3050    movd\t{%1, %0|%0, %1}
3051    movd\t{%1, %0|%0, %1}"
3052   [(set_attr "mode" "SI,SI,SI,DI,TI")
3053    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3054
3055 (define_insn "*zero_extendsidi2_32_1"
3056   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3057         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3058    (clobber (reg:CC FLAGS_REG))]
3059   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3060   "@
3061    #
3062    #
3063    #
3064    movd\t{%1, %0|%0, %1}
3065    movd\t{%1, %0|%0, %1}"
3066   [(set_attr "mode" "SI,SI,SI,DI,TI")
3067    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3068
3069 (define_insn "zero_extendsidi2_rex64"
3070   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3071      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3072   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3073   "@
3074    mov\t{%k1, %k0|%k0, %k1}
3075    #
3076    movd\t{%1, %0|%0, %1}
3077    movd\t{%1, %0|%0, %1}"
3078   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3079    (set_attr "mode" "SI,DI,DI,TI")])
3080
3081 (define_insn "*zero_extendsidi2_rex64_1"
3082   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3083      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3084   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3085   "@
3086    mov\t{%k1, %k0|%k0, %k1}
3087    #
3088    movd\t{%1, %0|%0, %1}
3089    movd\t{%1, %0|%0, %1}"
3090   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3091    (set_attr "mode" "SI,DI,SI,SI")])
3092
3093 (define_split
3094   [(set (match_operand:DI 0 "memory_operand" "")
3095      (zero_extend:DI (match_dup 0)))]
3096   "TARGET_64BIT"
3097   [(set (match_dup 4) (const_int 0))]
3098   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3099
3100 (define_split 
3101   [(set (match_operand:DI 0 "register_operand" "")
3102         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3103    (clobber (reg:CC FLAGS_REG))]
3104   "!TARGET_64BIT && reload_completed
3105    && true_regnum (operands[0]) == true_regnum (operands[1])"
3106   [(set (match_dup 4) (const_int 0))]
3107   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3108
3109 (define_split 
3110   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3111         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3112    (clobber (reg:CC FLAGS_REG))]
3113   "!TARGET_64BIT && reload_completed
3114    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3115   [(set (match_dup 3) (match_dup 1))
3116    (set (match_dup 4) (const_int 0))]
3117   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3118
3119 (define_insn "zero_extendhidi2"
3120   [(set (match_operand:DI 0 "register_operand" "=r,r")
3121      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3122   "TARGET_64BIT"
3123   "@
3124    movz{wl|x}\t{%1, %k0|%k0, %1}
3125    movz{wq|x}\t{%1, %0|%0, %1}"
3126   [(set_attr "type" "imovx")
3127    (set_attr "mode" "SI,DI")])
3128
3129 (define_insn "zero_extendqidi2"
3130   [(set (match_operand:DI 0 "register_operand" "=r,r")
3131      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3132   "TARGET_64BIT"
3133   "@
3134    movz{bl|x}\t{%1, %k0|%k0, %1}
3135    movz{bq|x}\t{%1, %0|%0, %1}"
3136   [(set_attr "type" "imovx")
3137    (set_attr "mode" "SI,DI")])
3138 \f
3139 ;; Sign extension instructions
3140
3141 (define_expand "extendsidi2"
3142   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3143                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3144               (clobber (reg:CC FLAGS_REG))
3145               (clobber (match_scratch:SI 2 ""))])]
3146   ""
3147 {
3148   if (TARGET_64BIT)
3149     {
3150       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3151       DONE;
3152     }
3153 })
3154
3155 (define_insn "*extendsidi2_1"
3156   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3157         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3158    (clobber (reg:CC FLAGS_REG))
3159    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3160   "!TARGET_64BIT"
3161   "#")
3162
3163 (define_insn "extendsidi2_rex64"
3164   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3165         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3166   "TARGET_64BIT"
3167   "@
3168    {cltq|cdqe}
3169    movs{lq|x}\t{%1,%0|%0, %1}"
3170   [(set_attr "type" "imovx")
3171    (set_attr "mode" "DI")
3172    (set_attr "prefix_0f" "0")
3173    (set_attr "modrm" "0,1")])
3174
3175 (define_insn "extendhidi2"
3176   [(set (match_operand:DI 0 "register_operand" "=r")
3177         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3178   "TARGET_64BIT"
3179   "movs{wq|x}\t{%1,%0|%0, %1}"
3180   [(set_attr "type" "imovx")
3181    (set_attr "mode" "DI")])
3182
3183 (define_insn "extendqidi2"
3184   [(set (match_operand:DI 0 "register_operand" "=r")
3185         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3186   "TARGET_64BIT"
3187   "movs{bq|x}\t{%1,%0|%0, %1}"
3188    [(set_attr "type" "imovx")
3189     (set_attr "mode" "DI")])
3190
3191 ;; Extend to memory case when source register does die.
3192 (define_split 
3193   [(set (match_operand:DI 0 "memory_operand" "")
3194         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3195    (clobber (reg:CC FLAGS_REG))
3196    (clobber (match_operand:SI 2 "register_operand" ""))]
3197   "(reload_completed
3198     && dead_or_set_p (insn, operands[1])
3199     && !reg_mentioned_p (operands[1], operands[0]))"
3200   [(set (match_dup 3) (match_dup 1))
3201    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3202               (clobber (reg:CC FLAGS_REG))])
3203    (set (match_dup 4) (match_dup 1))]
3204   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205
3206 ;; Extend to memory case when source register does not die.
3207 (define_split 
3208   [(set (match_operand:DI 0 "memory_operand" "")
3209         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3210    (clobber (reg:CC FLAGS_REG))
3211    (clobber (match_operand:SI 2 "register_operand" ""))]
3212   "reload_completed"
3213   [(const_int 0)]
3214 {
3215   split_di (&operands[0], 1, &operands[3], &operands[4]);
3216
3217   emit_move_insn (operands[3], operands[1]);
3218
3219   /* Generate a cltd if possible and doing so it profitable.  */
3220   if (true_regnum (operands[1]) == 0
3221       && true_regnum (operands[2]) == 1
3222       && (optimize_size || TARGET_USE_CLTD))
3223     {
3224       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3225     }
3226   else
3227     {
3228       emit_move_insn (operands[2], operands[1]);
3229       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3230     }
3231   emit_move_insn (operands[4], operands[2]);
3232   DONE;
3233 })
3234
3235 ;; Extend to register case.  Optimize case where source and destination
3236 ;; registers match and cases where we can use cltd.
3237 (define_split 
3238   [(set (match_operand:DI 0 "register_operand" "")
3239         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3240    (clobber (reg:CC FLAGS_REG))
3241    (clobber (match_scratch:SI 2 ""))]
3242   "reload_completed"
3243   [(const_int 0)]
3244 {
3245   split_di (&operands[0], 1, &operands[3], &operands[4]);
3246
3247   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3248     emit_move_insn (operands[3], operands[1]);
3249
3250   /* Generate a cltd if possible and doing so it profitable.  */
3251   if (true_regnum (operands[3]) == 0
3252       && (optimize_size || TARGET_USE_CLTD))
3253     {
3254       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3255       DONE;
3256     }
3257
3258   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3259     emit_move_insn (operands[4], operands[1]);
3260
3261   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3262   DONE;
3263 })
3264
3265 (define_insn "extendhisi2"
3266   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3267         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3268   ""
3269 {
3270   switch (get_attr_prefix_0f (insn))
3271     {
3272     case 0:
3273       return "{cwtl|cwde}";
3274     default:
3275       return "movs{wl|x}\t{%1,%0|%0, %1}";
3276     }
3277 }
3278   [(set_attr "type" "imovx")
3279    (set_attr "mode" "SI")
3280    (set (attr "prefix_0f")
3281      ;; movsx is short decodable while cwtl is vector decoded.
3282      (if_then_else (and (eq_attr "cpu" "!k6")
3283                         (eq_attr "alternative" "0"))
3284         (const_string "0")
3285         (const_string "1")))
3286    (set (attr "modrm")
3287      (if_then_else (eq_attr "prefix_0f" "0")
3288         (const_string "0")
3289         (const_string "1")))])
3290
3291 (define_insn "*extendhisi2_zext"
3292   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3293         (zero_extend:DI
3294           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3295   "TARGET_64BIT"
3296 {
3297   switch (get_attr_prefix_0f (insn))
3298     {
3299     case 0:
3300       return "{cwtl|cwde}";
3301     default:
3302       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3303     }
3304 }
3305   [(set_attr "type" "imovx")
3306    (set_attr "mode" "SI")
3307    (set (attr "prefix_0f")
3308      ;; movsx is short decodable while cwtl is vector decoded.
3309      (if_then_else (and (eq_attr "cpu" "!k6")
3310                         (eq_attr "alternative" "0"))
3311         (const_string "0")
3312         (const_string "1")))
3313    (set (attr "modrm")
3314      (if_then_else (eq_attr "prefix_0f" "0")
3315         (const_string "0")
3316         (const_string "1")))])
3317
3318 (define_insn "extendqihi2"
3319   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3320         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3321   ""
3322 {
3323   switch (get_attr_prefix_0f (insn))
3324     {
3325     case 0:
3326       return "{cbtw|cbw}";
3327     default:
3328       return "movs{bw|x}\t{%1,%0|%0, %1}";
3329     }
3330 }
3331   [(set_attr "type" "imovx")
3332    (set_attr "mode" "HI")
3333    (set (attr "prefix_0f")
3334      ;; movsx is short decodable while cwtl is vector decoded.
3335      (if_then_else (and (eq_attr "cpu" "!k6")
3336                         (eq_attr "alternative" "0"))
3337         (const_string "0")
3338         (const_string "1")))
3339    (set (attr "modrm")
3340      (if_then_else (eq_attr "prefix_0f" "0")
3341         (const_string "0")
3342         (const_string "1")))])
3343
3344 (define_insn "extendqisi2"
3345   [(set (match_operand:SI 0 "register_operand" "=r")
3346         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3347   ""
3348   "movs{bl|x}\t{%1,%0|%0, %1}"
3349    [(set_attr "type" "imovx")
3350     (set_attr "mode" "SI")])
3351
3352 (define_insn "*extendqisi2_zext"
3353   [(set (match_operand:DI 0 "register_operand" "=r")
3354         (zero_extend:DI
3355           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3356   "TARGET_64BIT"
3357   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3358    [(set_attr "type" "imovx")
3359     (set_attr "mode" "SI")])
3360 \f
3361 ;; Conversions between float and double.
3362
3363 ;; These are all no-ops in the model used for the 80387.  So just
3364 ;; emit moves.
3365
3366 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3367 (define_insn "*dummy_extendsfdf2"
3368   [(set (match_operand:DF 0 "push_operand" "=<")
3369         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3370   "0"
3371   "#")
3372
3373 (define_split
3374   [(set (match_operand:DF 0 "push_operand" "")
3375         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3376   "!TARGET_64BIT"
3377   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3378    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3379
3380 (define_split
3381   [(set (match_operand:DF 0 "push_operand" "")
3382         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3383   "TARGET_64BIT"
3384   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3385    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3386
3387 (define_insn "*dummy_extendsfxf2"
3388   [(set (match_operand:XF 0 "push_operand" "=<")
3389         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3390   "0"
3391   "#")
3392
3393 (define_split
3394   [(set (match_operand:XF 0 "push_operand" "")
3395         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3396   ""
3397   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3398    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3399   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3400
3401 (define_split
3402   [(set (match_operand:XF 0 "push_operand" "")
3403         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3404   "TARGET_64BIT"
3405   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3406    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3407   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3408
3409 (define_split
3410   [(set (match_operand:XF 0 "push_operand" "")
3411         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3412   ""
3413   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3414    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3415   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3416
3417 (define_split
3418   [(set (match_operand:XF 0 "push_operand" "")
3419         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3420   "TARGET_64BIT"
3421   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3422    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3423   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3424
3425 (define_expand "extendsfdf2"
3426   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3427         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3428   "TARGET_80387 || TARGET_SSE2"
3429 {
3430   /* ??? Needed for compress_float_constant since all fp constants
3431      are LEGITIMATE_CONSTANT_P.  */
3432   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3433     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3434   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3435     operands[1] = force_reg (SFmode, operands[1]);
3436 })
3437
3438 (define_insn "*extendsfdf2_1"
3439   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3440         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3441   "(TARGET_80387 || TARGET_SSE2)
3442    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3443 {
3444   switch (which_alternative)
3445     {
3446     case 0:
3447       return output_387_reg_move (insn, operands);
3448
3449     case 1:
3450       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3451         return "fstp%z0\t%y0";
3452       else
3453         return "fst%z0\t%y0";
3454
3455     case 2:
3456       return "cvtss2sd\t{%1, %0|%0, %1}";
3457
3458     default:
3459       abort ();
3460     }
3461 }
3462   [(set_attr "type" "fmov,fmov,ssecvt")
3463    (set_attr "mode" "SF,XF,DF")])
3464
3465 (define_insn "*extendsfdf2_1_sse_only"
3466   [(set (match_operand:DF 0 "register_operand" "=Y")
3467         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3468   "!TARGET_80387 && TARGET_SSE2
3469    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3470   "cvtss2sd\t{%1, %0|%0, %1}"
3471   [(set_attr "type" "ssecvt")
3472    (set_attr "mode" "DF")])
3473
3474 (define_expand "extendsfxf2"
3475   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3476         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3477   "TARGET_80387"
3478 {
3479   /* ??? Needed for compress_float_constant since all fp constants
3480      are LEGITIMATE_CONSTANT_P.  */
3481   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3482     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3483   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3484     operands[1] = force_reg (SFmode, operands[1]);
3485 })
3486
3487 (define_insn "*extendsfxf2_1"
3488   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3489         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3490   "TARGET_80387
3491    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3492 {
3493   switch (which_alternative)
3494     {
3495     case 0:
3496       return output_387_reg_move (insn, operands);
3497
3498     case 1:
3499       /* There is no non-popping store to memory for XFmode.  So if
3500          we need one, follow the store with a load.  */
3501       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3502         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3503       else
3504         return "fstp%z0\t%y0";
3505
3506     default:
3507       abort ();
3508     }
3509 }
3510   [(set_attr "type" "fmov")
3511    (set_attr "mode" "SF,XF")])
3512
3513 (define_expand "extenddfxf2"
3514   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3515         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3516   "TARGET_80387"
3517 {
3518   /* ??? Needed for compress_float_constant since all fp constants
3519      are LEGITIMATE_CONSTANT_P.  */
3520   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3521     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3523     operands[1] = force_reg (DFmode, operands[1]);
3524 })
3525
3526 (define_insn "*extenddfxf2_1"
3527   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3528         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3529   "TARGET_80387
3530    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3531 {
3532   switch (which_alternative)
3533     {
3534     case 0:
3535       return output_387_reg_move (insn, operands);
3536
3537     case 1:
3538       /* There is no non-popping store to memory for XFmode.  So if
3539          we need one, follow the store with a load.  */
3540       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3541         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3542       else
3543         return "fstp%z0\t%y0";
3544
3545     default:
3546       abort ();
3547     }
3548 }
3549   [(set_attr "type" "fmov")
3550    (set_attr "mode" "DF,XF")])
3551
3552 ;; %%% This seems bad bad news.
3553 ;; This cannot output into an f-reg because there is no way to be sure
3554 ;; of truncating in that case.  Otherwise this is just like a simple move
3555 ;; insn.  So we pretend we can output to a reg in order to get better
3556 ;; register preferencing, but we really use a stack slot.
3557
3558 (define_expand "truncdfsf2"
3559   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3560                    (float_truncate:SF
3561                     (match_operand:DF 1 "register_operand" "")))
3562               (clobber (match_dup 2))])]
3563   "TARGET_80387 || TARGET_SSE2"
3564   "
3565    if (!TARGET_80387)
3566      {
3567         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3568         DONE;
3569      }
3570    else if (flag_unsafe_math_optimizations)
3571      {
3572         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3573         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3574         if (reg != operands[0])
3575           emit_move_insn (operands[0], reg);
3576         DONE;
3577      }
3578    else
3579      operands[2] = assign_386_stack_local (SFmode, 0);
3580 ")
3581
3582 (define_insn "truncdfsf2_noop"
3583   [(set (match_operand:SF 0 "register_operand" "=f")
3584         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3585   "TARGET_80387 && flag_unsafe_math_optimizations"
3586 {
3587   return output_387_reg_move (insn, operands);
3588 }
3589   [(set_attr "type" "fmov")
3590    (set_attr "mode" "SF")])
3591
3592 (define_insn "*truncdfsf2_1"
3593   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3594         (float_truncate:SF
3595          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3596    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3597   "TARGET_80387 && !TARGET_SSE2"
3598 {
3599   switch (which_alternative)
3600     {
3601     case 0:
3602       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3603         return "fstp%z0\t%y0";
3604       else
3605         return "fst%z0\t%y0";
3606     default:
3607       abort ();
3608     }
3609 }
3610   [(set_attr "type" "fmov,multi,multi,multi")
3611    (set_attr "mode" "SF,SF,SF,SF")])
3612
3613 (define_insn "*truncdfsf2_1_sse"
3614   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3615         (float_truncate:SF
3616          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3617    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3618   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3619 {
3620   switch (which_alternative)
3621     {
3622     case 0:
3623       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624         return "fstp%z0\t%y0";
3625       else
3626         return "fst%z0\t%y0";
3627     case 4:
3628       return "#";
3629     default:
3630       abort ();
3631     }
3632 }
3633   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3634    (set_attr "mode" "SF,SF,SF,SF,DF")])
3635
3636 (define_insn "*truncdfsf2_1_sse_nooverlap"
3637   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3638         (float_truncate:SF
3639          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3640    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3641   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3642 {
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3647         return "fstp%z0\t%y0";
3648       else
3649         return "fst%z0\t%y0";
3650     case 4:
3651       return "#";
3652     default:
3653       abort ();
3654     }
3655 }
3656   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3657    (set_attr "mode" "SF,SF,SF,SF,DF")])
3658
3659 (define_insn "*truncdfsf2_2"
3660   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3661         (float_truncate:SF
3662          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3663   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3664    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3665 {
3666   switch (which_alternative)
3667     {
3668     case 0:
3669     case 1:
3670       return "cvtsd2ss\t{%1, %0|%0, %1}";
3671     case 2:
3672       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3673         return "fstp%z0\t%y0";
3674       else
3675         return "fst%z0\t%y0";
3676     default:
3677       abort ();
3678     }
3679 }
3680   [(set_attr "type" "ssecvt,ssecvt,fmov")
3681    (set_attr "athlon_decode" "vector,double,*")
3682    (set_attr "mode" "SF,SF,SF")])
3683
3684 (define_insn "*truncdfsf2_2_nooverlap"
3685   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3686         (float_truncate:SF
3687          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3688   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3689    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3690 {
3691   switch (which_alternative)
3692     {
3693     case 0:
3694       return "#";
3695     case 1:
3696       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697         return "fstp%z0\t%y0";
3698       else
3699         return "fst%z0\t%y0";
3700     default:
3701       abort ();
3702     }
3703 }
3704   [(set_attr "type" "ssecvt,fmov")
3705    (set_attr "mode" "DF,SF")])
3706
3707 (define_insn "*truncdfsf2_3"
3708   [(set (match_operand:SF 0 "memory_operand" "=m")
3709         (float_truncate:SF
3710          (match_operand:DF 1 "register_operand" "f")))]
3711   "TARGET_80387"
3712 {
3713   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3714     return "fstp%z0\t%y0";
3715   else
3716     return "fst%z0\t%y0";
3717 }
3718   [(set_attr "type" "fmov")
3719    (set_attr "mode" "SF")])
3720
3721 (define_insn "truncdfsf2_sse_only"
3722   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3723         (float_truncate:SF
3724          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3725   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3726   "cvtsd2ss\t{%1, %0|%0, %1}"
3727   [(set_attr "type" "ssecvt")
3728    (set_attr "athlon_decode" "vector,double")
3729    (set_attr "mode" "SF")])
3730
3731 (define_insn "*truncdfsf2_sse_only_nooverlap"
3732   [(set (match_operand:SF 0 "register_operand" "=&Y")
3733         (float_truncate:SF
3734          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3735   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3736   "#"
3737   [(set_attr "type" "ssecvt")
3738    (set_attr "mode" "DF")])
3739
3740 (define_split
3741   [(set (match_operand:SF 0 "memory_operand" "")
3742         (float_truncate:SF
3743          (match_operand:DF 1 "register_operand" "")))
3744    (clobber (match_operand:SF 2 "memory_operand" ""))]
3745   "TARGET_80387"
3746   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3747   "")
3748
3749 ; Avoid possible reformatting penalty on the destination by first
3750 ; zeroing it out
3751 (define_split
3752   [(set (match_operand:SF 0 "register_operand" "")
3753         (float_truncate:SF
3754          (match_operand:DF 1 "nonimmediate_operand" "")))
3755    (clobber (match_operand 2 "" ""))]
3756   "TARGET_80387 && reload_completed
3757    && SSE_REG_P (operands[0])
3758    && !STACK_REG_P (operands[1])"
3759   [(const_int 0)]
3760 {
3761   rtx src, dest;
3762   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3763     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3764   else
3765     {
3766       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3767       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3768       /* simplify_gen_subreg refuses to widen memory references.  */
3769       if (GET_CODE (src) == SUBREG)
3770         alter_subreg (&src);
3771       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3772         abort ();
3773       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3774       emit_insn (gen_cvtsd2ss (dest, dest, src));
3775     }
3776   DONE;
3777 })
3778
3779 (define_split
3780   [(set (match_operand:SF 0 "register_operand" "")
3781         (float_truncate:SF
3782          (match_operand:DF 1 "nonimmediate_operand" "")))]
3783   "TARGET_80387 && reload_completed
3784    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3785   [(const_int 0)]
3786 {
3787   rtx src, dest;
3788   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3789   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3790   /* simplify_gen_subreg refuses to widen memory references.  */
3791   if (GET_CODE (src) == SUBREG)
3792     alter_subreg (&src);
3793   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3794     abort ();
3795   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3796   emit_insn (gen_cvtsd2ss (dest, dest, src));
3797   DONE;
3798 })
3799
3800 (define_split
3801   [(set (match_operand:SF 0 "register_operand" "")
3802         (float_truncate:SF
3803          (match_operand:DF 1 "fp_register_operand" "")))
3804    (clobber (match_operand:SF 2 "memory_operand" ""))]
3805   "TARGET_80387 && reload_completed"
3806   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3807    (set (match_dup 0) (match_dup 2))]
3808   "")
3809
3810 (define_expand "truncxfsf2"
3811   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3812                    (float_truncate:SF
3813                     (match_operand:XF 1 "register_operand" "")))
3814               (clobber (match_dup 2))])]
3815   "TARGET_80387"
3816   "
3817   if (flag_unsafe_math_optimizations)
3818     {
3819       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3821       if (reg != operands[0])
3822         emit_move_insn (operands[0], reg);
3823       DONE;
3824     }
3825   else
3826     operands[2] = assign_386_stack_local (SFmode, 0);
3827   ")
3828
3829 (define_insn "truncxfsf2_noop"
3830   [(set (match_operand:SF 0 "register_operand" "=f")
3831         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3832   "TARGET_80387 && flag_unsafe_math_optimizations"
3833 {
3834   return output_387_reg_move (insn, operands);
3835 }
3836   [(set_attr "type" "fmov")
3837    (set_attr "mode" "SF")])
3838
3839 (define_insn "*truncxfsf2_1"
3840   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3841         (float_truncate:SF
3842          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844   "TARGET_80387"
3845 {
3846   switch (which_alternative)
3847     {
3848     case 0:
3849       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850         return "fstp%z0\t%y0";
3851       else
3852         return "fst%z0\t%y0";
3853     default:
3854       abort();
3855     }
3856 }
3857   [(set_attr "type" "fmov,multi,multi,multi")
3858    (set_attr "mode" "SF")])
3859
3860 (define_insn "*truncxfsf2_2"
3861   [(set (match_operand:SF 0 "memory_operand" "=m")
3862         (float_truncate:SF
3863          (match_operand:XF 1 "register_operand" "f")))]
3864   "TARGET_80387"
3865 {
3866   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867     return "fstp%z0\t%y0";
3868   else
3869     return "fst%z0\t%y0";
3870 }
3871   [(set_attr "type" "fmov")
3872    (set_attr "mode" "SF")])
3873
3874 (define_split
3875   [(set (match_operand:SF 0 "memory_operand" "")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "")))
3878    (clobber (match_operand:SF 2 "memory_operand" ""))]
3879   "TARGET_80387"
3880   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3881   "")
3882
3883 (define_split
3884   [(set (match_operand:SF 0 "register_operand" "")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "")))
3887    (clobber (match_operand:SF 2 "memory_operand" ""))]
3888   "TARGET_80387 && reload_completed"
3889   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3890    (set (match_dup 0) (match_dup 2))]
3891   "")
3892
3893 (define_expand "truncxfdf2"
3894   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3895                    (float_truncate:DF
3896                     (match_operand:XF 1 "register_operand" "")))
3897               (clobber (match_dup 2))])]
3898   "TARGET_80387"
3899   "
3900   if (flag_unsafe_math_optimizations)
3901     {
3902       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3903       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3904       if (reg != operands[0])
3905         emit_move_insn (operands[0], reg);
3906       DONE;
3907     }
3908   else
3909     operands[2] = assign_386_stack_local (DFmode, 0);
3910   ")
3911
3912 (define_insn "truncxfdf2_noop"
3913   [(set (match_operand:DF 0 "register_operand" "=f")
3914         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3915   "TARGET_80387 && flag_unsafe_math_optimizations"
3916 {
3917   return output_387_reg_move (insn, operands);
3918 }
3919   [(set_attr "type" "fmov")
3920    (set_attr "mode" "DF")])
3921
3922 (define_insn "*truncxfdf2_1"
3923   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3924         (float_truncate:DF
3925          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3926    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3927   "TARGET_80387"
3928 {
3929   switch (which_alternative)
3930     {
3931     case 0:
3932       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933         return "fstp%z0\t%y0";
3934       else
3935         return "fst%z0\t%y0";
3936     default:
3937       abort();
3938     }
3939   abort ();
3940 }
3941   [(set_attr "type" "fmov,multi,multi,multi")
3942    (set_attr "mode" "DF")])
3943
3944 (define_insn "*truncxfdf2_2"
3945   [(set (match_operand:DF 0 "memory_operand" "=m")
3946         (float_truncate:DF
3947           (match_operand:XF 1 "register_operand" "f")))]
3948   "TARGET_80387"
3949 {
3950   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3951     return "fstp%z0\t%y0";
3952   else
3953     return "fst%z0\t%y0";
3954 }
3955   [(set_attr "type" "fmov")
3956    (set_attr "mode" "DF")])
3957
3958 (define_split
3959   [(set (match_operand:DF 0 "memory_operand" "")
3960         (float_truncate:DF
3961          (match_operand:XF 1 "register_operand" "")))
3962    (clobber (match_operand:DF 2 "memory_operand" ""))]
3963   "TARGET_80387"
3964   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3965   "")
3966
3967 (define_split
3968   [(set (match_operand:DF 0 "register_operand" "")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "")))
3971    (clobber (match_operand:DF 2 "memory_operand" ""))]
3972   "TARGET_80387 && reload_completed"
3973   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3974    (set (match_dup 0) (match_dup 2))]
3975   "")
3976
3977 \f
3978 ;; %%% Break up all these bad boys.
3979
3980 ;; Signed conversion to DImode.
3981
3982 (define_expand "fix_truncxfdi2"
3983   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3984                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3985               (clobber (reg:CC FLAGS_REG))])]
3986   "TARGET_80387"
3987   "")
3988
3989 (define_expand "fix_truncdfdi2"
3990   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
3994 {
3995   if (TARGET_64BIT && TARGET_SSE2)
3996    {
3997      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3998      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
3999      if (out != operands[0])
4000         emit_move_insn (operands[0], out);
4001      DONE;
4002    }
4003 })
4004
4005 (define_expand "fix_truncsfdi2"
4006   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4007                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4008               (clobber (reg:CC FLAGS_REG))])] 
4009   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4010 {
4011   if (TARGET_SSE && TARGET_64BIT)
4012    {
4013      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4014      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4015      if (out != operands[0])
4016         emit_move_insn (operands[0], out);
4017      DONE;
4018    }
4019 })
4020
4021 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4022 ;; of the machinery.
4023 (define_insn_and_split "*fix_truncdi_1"
4024   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4025         (fix:DI (match_operand 1 "register_operand" "f,f")))
4026    (clobber (reg:CC FLAGS_REG))]
4027   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4028    && !reload_completed && !reload_in_progress
4029    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4030   "#"
4031   "&& 1"
4032   [(const_int 0)]
4033 {
4034   ix86_optimize_mode_switching = 1;
4035   operands[2] = assign_386_stack_local (HImode, 1);
4036   operands[3] = assign_386_stack_local (HImode, 2);
4037   if (memory_operand (operands[0], VOIDmode))
4038     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4039                                        operands[2], operands[3]));
4040   else
4041     {
4042       operands[4] = assign_386_stack_local (DImode, 0);
4043       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4044                                            operands[2], operands[3],
4045                                            operands[4]));
4046     }
4047   DONE;
4048 }
4049   [(set_attr "type" "fistp")
4050    (set_attr "i387_cw" "trunc")
4051    (set_attr "mode" "DI")])
4052
4053 (define_insn "fix_truncdi_nomemory"
4054   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4055         (fix:DI (match_operand 1 "register_operand" "f,f")))
4056    (use (match_operand:HI 2 "memory_operand" "m,m"))
4057    (use (match_operand:HI 3 "memory_operand" "m,m"))
4058    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4059    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4060   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4061    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4062   "#"
4063   [(set_attr "type" "fistp")
4064    (set_attr "i387_cw" "trunc")
4065    (set_attr "mode" "DI")])
4066
4067 (define_insn "fix_truncdi_memory"
4068   [(set (match_operand:DI 0 "memory_operand" "=m")
4069         (fix:DI (match_operand 1 "register_operand" "f")))
4070    (use (match_operand:HI 2 "memory_operand" "m"))
4071    (use (match_operand:HI 3 "memory_operand" "m"))
4072    (clobber (match_scratch:DF 4 "=&1f"))]
4073   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4074    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4075   "* return output_fix_trunc (insn, operands);"
4076   [(set_attr "type" "fistp")
4077    (set_attr "i387_cw" "trunc")
4078    (set_attr "mode" "DI")])
4079
4080 (define_split 
4081   [(set (match_operand:DI 0 "register_operand" "")
4082         (fix:DI (match_operand 1 "register_operand" "")))
4083    (use (match_operand:HI 2 "memory_operand" ""))
4084    (use (match_operand:HI 3 "memory_operand" ""))
4085    (clobber (match_operand:DI 4 "memory_operand" ""))
4086    (clobber (match_scratch 5 ""))]
4087   "reload_completed"
4088   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4089               (use (match_dup 2))
4090               (use (match_dup 3))
4091               (clobber (match_dup 5))])
4092    (set (match_dup 0) (match_dup 4))]
4093   "")
4094
4095 (define_split 
4096   [(set (match_operand:DI 0 "memory_operand" "")
4097         (fix:DI (match_operand 1 "register_operand" "")))
4098    (use (match_operand:HI 2 "memory_operand" ""))
4099    (use (match_operand:HI 3 "memory_operand" ""))
4100    (clobber (match_operand:DI 4 "memory_operand" ""))
4101    (clobber (match_scratch 5 ""))]
4102   "reload_completed"
4103   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4104               (use (match_dup 2))
4105               (use (match_dup 3))
4106               (clobber (match_dup 5))])]
4107   "")
4108
4109 ;; When SSE available, it is always faster to use it!
4110 (define_insn "fix_truncsfdi_sse"
4111   [(set (match_operand:DI 0 "register_operand" "=r,r")
4112         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4113   "TARGET_64BIT && TARGET_SSE"
4114   "cvttss2si{q}\t{%1, %0|%0, %1}"
4115   [(set_attr "type" "sseicvt")
4116    (set_attr "mode" "SF")
4117    (set_attr "athlon_decode" "double,vector")])
4118
4119 ;; Avoid vector decoded form of the instruction.
4120 (define_peephole2
4121   [(match_scratch:SF 2 "x")
4122    (set (match_operand:DI 0 "register_operand" "")
4123         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4124   "TARGET_K8 && !optimize_size"
4125   [(set (match_dup 2) (match_dup 1))
4126    (set (match_dup 0) (fix:DI (match_dup 2)))]
4127   "")
4128
4129 (define_insn "fix_truncdfdi_sse"
4130   [(set (match_operand:DI 0 "register_operand" "=r,r")
4131         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4132   "TARGET_64BIT && TARGET_SSE2"
4133   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4134   [(set_attr "type" "sseicvt,sseicvt")
4135    (set_attr "mode" "DF")
4136    (set_attr "athlon_decode" "double,vector")])
4137
4138 ;; Avoid vector decoded form of the instruction.
4139 (define_peephole2
4140   [(match_scratch:DF 2 "Y")
4141    (set (match_operand:DI 0 "register_operand" "")
4142         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4143   "TARGET_K8 && !optimize_size"
4144   [(set (match_dup 2) (match_dup 1))
4145    (set (match_dup 0) (fix:DI (match_dup 2)))]
4146   "")
4147
4148 ;; Signed conversion to SImode.
4149
4150 (define_expand "fix_truncxfsi2"
4151   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4152                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4153               (clobber (reg:CC FLAGS_REG))])]
4154   "TARGET_80387"
4155   "")
4156
4157 (define_expand "fix_truncdfsi2"
4158   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387 || TARGET_SSE2"
4162 {
4163   if (TARGET_SSE2)
4164    {
4165      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4166      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4167      if (out != operands[0])
4168         emit_move_insn (operands[0], out);
4169      DONE;
4170    }
4171 })
4172
4173 (define_expand "fix_truncsfsi2"
4174   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4175                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4176               (clobber (reg:CC FLAGS_REG))])] 
4177   "TARGET_80387 || TARGET_SSE"
4178 {
4179   if (TARGET_SSE)
4180    {
4181      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4182      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4183      if (out != operands[0])
4184         emit_move_insn (operands[0], out);
4185      DONE;
4186    }
4187 })
4188
4189 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4190 ;; of the machinery.
4191 (define_insn_and_split "*fix_truncsi_1"
4192   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4193         (fix:SI (match_operand 1 "register_operand" "f,f")))
4194    (clobber (reg:CC FLAGS_REG))]
4195   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4196    && !reload_completed && !reload_in_progress
4197    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4198   "#"
4199   "&& 1"
4200   [(const_int 0)]
4201 {
4202   ix86_optimize_mode_switching = 1;
4203   operands[2] = assign_386_stack_local (HImode, 1);
4204   operands[3] = assign_386_stack_local (HImode, 2);
4205   if (memory_operand (operands[0], VOIDmode))
4206     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4207                                        operands[2], operands[3]));
4208   else
4209     {
4210       operands[4] = assign_386_stack_local (SImode, 0);
4211       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4212                                            operands[2], operands[3],
4213                                            operands[4]));
4214     }
4215   DONE;
4216 }
4217   [(set_attr "type" "fistp")
4218    (set_attr "i387_cw" "trunc")
4219    (set_attr "mode" "SI")])
4220
4221 (define_insn "fix_truncsi_nomemory"
4222   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4223         (fix:SI (match_operand 1 "register_operand" "f,f")))
4224    (use (match_operand:HI 2 "memory_operand" "m,m"))
4225    (use (match_operand:HI 3 "memory_operand" "m,m"))
4226    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4227   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4229   "#"
4230   [(set_attr "type" "fistp")
4231    (set_attr "i387_cw" "trunc")
4232    (set_attr "mode" "SI")])
4233
4234 (define_insn "fix_truncsi_memory"
4235   [(set (match_operand:SI 0 "memory_operand" "=m")
4236         (fix:SI (match_operand 1 "register_operand" "f")))
4237    (use (match_operand:HI 2 "memory_operand" "m"))
4238    (use (match_operand:HI 3 "memory_operand" "m"))]
4239   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4240    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4241   "* return output_fix_trunc (insn, operands);"
4242   [(set_attr "type" "fistp")
4243    (set_attr "i387_cw" "trunc")
4244    (set_attr "mode" "SI")])
4245
4246 ;; When SSE available, it is always faster to use it!
4247 (define_insn "fix_truncsfsi_sse"
4248   [(set (match_operand:SI 0 "register_operand" "=r,r")
4249         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4250   "TARGET_SSE"
4251   "cvttss2si\t{%1, %0|%0, %1}"
4252   [(set_attr "type" "sseicvt")
4253    (set_attr "mode" "DF")
4254    (set_attr "athlon_decode" "double,vector")])
4255
4256 ;; Avoid vector decoded form of the instruction.
4257 (define_peephole2
4258   [(match_scratch:SF 2 "x")
4259    (set (match_operand:SI 0 "register_operand" "")
4260         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4261   "TARGET_K8 && !optimize_size"
4262   [(set (match_dup 2) (match_dup 1))
4263    (set (match_dup 0) (fix:SI (match_dup 2)))]
4264   "")
4265
4266 (define_insn "fix_truncdfsi_sse"
4267   [(set (match_operand:SI 0 "register_operand" "=r,r")
4268         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4269   "TARGET_SSE2"
4270   "cvttsd2si\t{%1, %0|%0, %1}"
4271   [(set_attr "type" "sseicvt")
4272    (set_attr "mode" "DF")
4273    (set_attr "athlon_decode" "double,vector")])
4274
4275 ;; Avoid vector decoded form of the instruction.
4276 (define_peephole2
4277   [(match_scratch:DF 2 "Y")
4278    (set (match_operand:SI 0 "register_operand" "")
4279         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4280   "TARGET_K8 && !optimize_size"
4281   [(set (match_dup 2) (match_dup 1))
4282    (set (match_dup 0) (fix:SI (match_dup 2)))]
4283   "")
4284
4285 (define_split 
4286   [(set (match_operand:SI 0 "register_operand" "")
4287         (fix:SI (match_operand 1 "register_operand" "")))
4288    (use (match_operand:HI 2 "memory_operand" ""))
4289    (use (match_operand:HI 3 "memory_operand" ""))
4290    (clobber (match_operand:SI 4 "memory_operand" ""))]
4291   "reload_completed"
4292   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4293               (use (match_dup 2))
4294               (use (match_dup 3))])
4295    (set (match_dup 0) (match_dup 4))]
4296   "")
4297
4298 (define_split 
4299   [(set (match_operand:SI 0 "memory_operand" "")
4300         (fix:SI (match_operand 1 "register_operand" "")))
4301    (use (match_operand:HI 2 "memory_operand" ""))
4302    (use (match_operand:HI 3 "memory_operand" ""))
4303    (clobber (match_operand:SI 4 "memory_operand" ""))]
4304   "reload_completed"
4305   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4306               (use (match_dup 2))
4307               (use (match_dup 3))])]
4308   "")
4309
4310 ;; Signed conversion to HImode.
4311
4312 (define_expand "fix_truncxfhi2"
4313   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4314                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4315               (clobber (reg:CC FLAGS_REG))])] 
4316   "TARGET_80387"
4317   "")
4318
4319 (define_expand "fix_truncdfhi2"
4320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4322               (clobber (reg:CC FLAGS_REG))])]
4323   "TARGET_80387 && !TARGET_SSE2"
4324   "")
4325
4326 (define_expand "fix_truncsfhi2"
4327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4329                (clobber (reg:CC FLAGS_REG))])]
4330   "TARGET_80387 && !TARGET_SSE"
4331   "")
4332
4333 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4334 ;; of the machinery.
4335 (define_insn_and_split "*fix_trunchi_1"
4336   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4337         (fix:HI (match_operand 1 "register_operand" "f,f")))
4338    (clobber (reg:CC FLAGS_REG))]
4339   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !reload_completed && !reload_in_progress
4341    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342   "#"
4343   "&& 1"
4344   [(const_int 0)]
4345 {
4346   ix86_optimize_mode_switching = 1;
4347   operands[2] = assign_386_stack_local (HImode, 1);
4348   operands[3] = assign_386_stack_local (HImode, 2);
4349   if (memory_operand (operands[0], VOIDmode))
4350     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4351                                        operands[2], operands[3]));
4352   else
4353     {
4354       operands[4] = assign_386_stack_local (HImode, 0);
4355       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4356                                            operands[2], operands[3],
4357                                            operands[4]));
4358     }
4359   DONE;
4360 }
4361   [(set_attr "type" "fistp")
4362    (set_attr "i387_cw" "trunc")
4363    (set_attr "mode" "HI")])
4364
4365 (define_insn "fix_trunchi_nomemory"
4366   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4367         (fix:HI (match_operand 1 "register_operand" "f,f")))
4368    (use (match_operand:HI 2 "memory_operand" "m,m"))
4369    (use (match_operand:HI 3 "memory_operand" "m,m"))
4370    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4371   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373   "#"
4374   [(set_attr "type" "fistp")
4375    (set_attr "i387_cw" "trunc")
4376    (set_attr "mode" "HI")])
4377
4378 (define_insn "fix_trunchi_memory"
4379   [(set (match_operand:HI 0 "memory_operand" "=m")
4380         (fix:HI (match_operand 1 "register_operand" "f")))
4381    (use (match_operand:HI 2 "memory_operand" "m"))
4382    (use (match_operand:HI 3 "memory_operand" "m"))]
4383   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4385   "* return output_fix_trunc (insn, operands);"
4386   [(set_attr "type" "fistp")
4387    (set_attr "i387_cw" "trunc")
4388    (set_attr "mode" "HI")])
4389
4390 (define_split 
4391   [(set (match_operand:HI 0 "memory_operand" "")
4392         (fix:HI (match_operand 1 "register_operand" "")))
4393    (use (match_operand:HI 2 "memory_operand" ""))
4394    (use (match_operand:HI 3 "memory_operand" ""))
4395    (clobber (match_operand:HI 4 "memory_operand" ""))]
4396   "reload_completed"
4397   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4398               (use (match_dup 2))
4399               (use (match_dup 3))])]
4400   "")
4401
4402 (define_split 
4403   [(set (match_operand:HI 0 "register_operand" "")
4404         (fix:HI (match_operand 1 "register_operand" "")))
4405    (use (match_operand:HI 2 "memory_operand" ""))
4406    (use (match_operand:HI 3 "memory_operand" ""))
4407    (clobber (match_operand:HI 4 "memory_operand" ""))]
4408   "reload_completed"
4409   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4410               (use (match_dup 2))
4411               (use (match_dup 3))
4412               (clobber (match_dup 4))])
4413    (set (match_dup 0) (match_dup 4))]
4414   "")
4415
4416 (define_insn "x86_fnstcw_1"
4417   [(set (match_operand:HI 0 "memory_operand" "=m")
4418         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4419   "TARGET_80387"
4420   "fnstcw\t%0"
4421   [(set_attr "length" "2")
4422    (set_attr "mode" "HI")
4423    (set_attr "unit" "i387")])
4424
4425 (define_insn "x86_fldcw_1"
4426   [(set (reg:HI FPSR_REG)
4427         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4428   "TARGET_80387"
4429   "fldcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")
4433    (set_attr "athlon_decode" "vector")])
4434 \f
4435 ;; Conversion between fixed point and floating point.
4436
4437 ;; Even though we only accept memory inputs, the backend _really_
4438 ;; wants to be able to do this between registers.
4439
4440 (define_expand "floathisf2"
4441   [(set (match_operand:SF 0 "register_operand" "")
4442         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4443   "TARGET_80387 || TARGET_SSE_MATH"
4444 {
4445   if (TARGET_SSE_MATH)
4446     {
4447       emit_insn (gen_floatsisf2 (operands[0],
4448                                  convert_to_mode (SImode, operands[1], 0)));
4449       DONE;
4450     }
4451 })
4452
4453 (define_insn "*floathisf2_i387"
4454   [(set (match_operand:SF 0 "register_operand" "=f,f")
4455         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4456   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4457   "@
4458    fild%z1\t%1
4459    #"
4460   [(set_attr "type" "fmov,multi")
4461    (set_attr "mode" "SF")
4462    (set_attr "fp_int_src" "true")])
4463
4464 (define_expand "floatsisf2"
4465   [(set (match_operand:SF 0 "register_operand" "")
4466         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4467   "TARGET_80387 || TARGET_SSE_MATH"
4468   "")
4469
4470 (define_insn "*floatsisf2_mixed"
4471   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4472         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4473   "TARGET_MIX_SSE_I387"
4474   "@
4475    fild%z1\t%1
4476    #
4477    cvtsi2ss\t{%1, %0|%0, %1}
4478    cvtsi2ss\t{%1, %0|%0, %1}"
4479   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4480    (set_attr "mode" "SF")
4481    (set_attr "athlon_decode" "*,*,vector,double")
4482    (set_attr "fp_int_src" "true")])
4483
4484 (define_insn "*floatsisf2_sse"
4485   [(set (match_operand:SF 0 "register_operand" "=x,x")
4486         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4487   "TARGET_SSE_MATH"
4488   "cvtsi2ss\t{%1, %0|%0, %1}"
4489   [(set_attr "type" "sseicvt")
4490    (set_attr "mode" "SF")
4491    (set_attr "athlon_decode" "vector,double")
4492    (set_attr "fp_int_src" "true")])
4493
4494 ; Avoid possible reformatting penalty on the destination by first
4495 ; zeroing it out
4496 (define_split
4497   [(set (match_operand:SF 0 "register_operand" "")
4498         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4499   "reload_completed
4500    && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4501    && SSE_REG_P (operands[0])"
4502   [(const_int 0)]
4503 {
4504   rtx dest;
4505   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4506   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4507   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4508   DONE;
4509 })
4510
4511 (define_insn "*floatsisf2_i387"
4512   [(set (match_operand:SF 0 "register_operand" "=f,f")
4513         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4514   "TARGET_80387"
4515   "@
4516    fild%z1\t%1
4517    #"
4518   [(set_attr "type" "fmov,multi")
4519    (set_attr "mode" "SF")
4520    (set_attr "fp_int_src" "true")])
4521
4522 (define_expand "floatdisf2"
4523   [(set (match_operand:SF 0 "register_operand" "")
4524         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4525   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4526   "")
4527
4528 (define_insn "*floatdisf2_mixed"
4529   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4530         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4531   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4532   "@
4533    fild%z1\t%1
4534    #
4535    cvtsi2ss{q}\t{%1, %0|%0, %1}
4536    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4537   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4538    (set_attr "mode" "SF")
4539    (set_attr "athlon_decode" "*,*,vector,double")
4540    (set_attr "fp_int_src" "true")])
4541
4542 (define_insn "*floatdisf2_sse"
4543   [(set (match_operand:SF 0 "register_operand" "=x,x")
4544         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4545   "TARGET_64BIT && TARGET_SSE_MATH"
4546   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4547   [(set_attr "type" "sseicvt")
4548    (set_attr "mode" "SF")
4549    (set_attr "athlon_decode" "vector,double")
4550    (set_attr "fp_int_src" "true")])
4551
4552 ; Avoid possible reformatting penalty on the destination by first
4553 ; zeroing it out
4554 (define_split
4555   [(set (match_operand:SF 0 "register_operand" "")
4556         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4557   "reload_completed
4558    && TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4559    && SSE_REG_P (operands[0])"
4560   [(const_int 0)]
4561 {
4562   rtx dest;
4563   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4564   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4565   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4566   DONE;
4567 })
4568
4569 (define_insn "*floatdisf2_i387"
4570   [(set (match_operand:SF 0 "register_operand" "=f,f")
4571         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4572   "TARGET_80387"
4573   "@
4574    fild%z1\t%1
4575    #"
4576   [(set_attr "type" "fmov,multi")
4577    (set_attr "mode" "SF")
4578    (set_attr "fp_int_src" "true")])
4579
4580 (define_expand "floathidf2"
4581   [(set (match_operand:DF 0 "register_operand" "")
4582         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4583   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4584 {
4585   if (TARGET_SSE2 && TARGET_SSE_MATH)
4586     {
4587       emit_insn (gen_floatsidf2 (operands[0],
4588                                  convert_to_mode (SImode, operands[1], 0)));
4589       DONE;
4590     }
4591 })
4592
4593 (define_insn "*floathidf2_i387"
4594   [(set (match_operand:DF 0 "register_operand" "=f,f")
4595         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4596   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4597   "@
4598    fild%z1\t%1
4599    #"
4600   [(set_attr "type" "fmov,multi")
4601    (set_attr "mode" "DF")
4602    (set_attr "fp_int_src" "true")])
4603
4604 (define_expand "floatsidf2"
4605   [(set (match_operand:DF 0 "register_operand" "")
4606         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4607   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4608   "")
4609
4610 (define_insn "*floatsidf2_mixed"
4611   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4612         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4613   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4614   "@
4615    fild%z1\t%1
4616    #
4617    cvtsi2sd\t{%1, %0|%0, %1}
4618    cvtsi2sd\t{%1, %0|%0, %1}"
4619   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4620    (set_attr "mode" "DF")
4621    (set_attr "athlon_decode" "*,*,double,direct")
4622    (set_attr "fp_int_src" "true")])
4623
4624 (define_insn "*floatsidf2_sse"
4625   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4626         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4627   "TARGET_SSE2 && TARGET_SSE_MATH"
4628   "cvtsi2sd\t{%1, %0|%0, %1}"
4629   [(set_attr "type" "sseicvt")
4630    (set_attr "mode" "DF")
4631    (set_attr "athlon_decode" "double,direct")
4632    (set_attr "fp_int_src" "true")])
4633
4634 (define_insn "*floatsidf2_i387"
4635   [(set (match_operand:DF 0 "register_operand" "=f,f")
4636         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4637   "TARGET_80387"
4638   "@
4639    fild%z1\t%1
4640    #"
4641   [(set_attr "type" "fmov,multi")
4642    (set_attr "mode" "DF")
4643    (set_attr "fp_int_src" "true")])
4644
4645 (define_expand "floatdidf2"
4646   [(set (match_operand:DF 0 "register_operand" "")
4647         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4648   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4649   "")
4650
4651 (define_insn "*floatdidf2_mixed"
4652   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4653         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4654   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4655   "@
4656    fild%z1\t%1
4657    #
4658    cvtsi2sd{q}\t{%1, %0|%0, %1}
4659    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4660   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4661    (set_attr "mode" "DF")
4662    (set_attr "athlon_decode" "*,*,double,direct")
4663    (set_attr "fp_int_src" "true")])
4664
4665 (define_insn "*floatdidf2_sse"
4666   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4667         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4668   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4669   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4670   [(set_attr "type" "sseicvt")
4671    (set_attr "mode" "DF")
4672    (set_attr "athlon_decode" "double,direct")
4673    (set_attr "fp_int_src" "true")])
4674
4675 (define_insn "*floatdidf2_i387"
4676   [(set (match_operand:DF 0 "register_operand" "=f,f")
4677         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4678   "TARGET_80387"
4679   "@
4680    fild%z1\t%1
4681    #"
4682   [(set_attr "type" "fmov,multi")
4683    (set_attr "mode" "DF")
4684    (set_attr "fp_int_src" "true")])
4685
4686 (define_insn "floathixf2"
4687   [(set (match_operand:XF 0 "register_operand" "=f,f")
4688         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4689   "TARGET_80387"
4690   "@
4691    fild%z1\t%1
4692    #"
4693   [(set_attr "type" "fmov,multi")
4694    (set_attr "mode" "XF")
4695    (set_attr "fp_int_src" "true")])
4696
4697 (define_insn "floatsixf2"
4698   [(set (match_operand:XF 0 "register_operand" "=f,f")
4699         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4700   "TARGET_80387"
4701   "@
4702    fild%z1\t%1
4703    #"
4704   [(set_attr "type" "fmov,multi")
4705    (set_attr "mode" "XF")
4706    (set_attr "fp_int_src" "true")])
4707
4708 (define_insn "floatdixf2"
4709   [(set (match_operand:XF 0 "register_operand" "=f,f")
4710         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4711   "TARGET_80387"
4712   "@
4713    fild%z1\t%1
4714    #"
4715   [(set_attr "type" "fmov,multi")
4716    (set_attr "mode" "XF")
4717    (set_attr "fp_int_src" "true")])
4718
4719 ;; %%% Kill these when reload knows how to do it.
4720 (define_split
4721   [(set (match_operand 0 "fp_register_operand" "")
4722         (float (match_operand 1 "register_operand" "")))]
4723   "reload_completed
4724    && TARGET_80387
4725    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4726   [(const_int 0)]
4727 {
4728   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4729   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4730   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4731   ix86_free_from_memory (GET_MODE (operands[1]));
4732   DONE;
4733 })
4734
4735 (define_expand "floatunssisf2"
4736   [(use (match_operand:SF 0 "register_operand" ""))
4737    (use (match_operand:SI 1 "register_operand" ""))]
4738   "!TARGET_64BIT && TARGET_SSE_MATH"
4739   "x86_emit_floatuns (operands); DONE;")
4740
4741 (define_expand "floatunsdisf2"
4742   [(use (match_operand:SF 0 "register_operand" ""))
4743    (use (match_operand:DI 1 "register_operand" ""))]
4744   "TARGET_64BIT && TARGET_SSE_MATH"
4745   "x86_emit_floatuns (operands); DONE;")
4746
4747 (define_expand "floatunsdidf2"
4748   [(use (match_operand:DF 0 "register_operand" ""))
4749    (use (match_operand:DI 1 "register_operand" ""))]
4750   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4751   "x86_emit_floatuns (operands); DONE;")
4752 \f
4753 ;; SSE extract/set expanders
4754
4755 (define_expand "vec_setv2df"
4756   [(match_operand:V2DF 0 "register_operand" "")
4757    (match_operand:DF 1 "register_operand" "")
4758    (match_operand 2 "const_int_operand" "")]
4759   "TARGET_SSE2"
4760 {
4761   switch (INTVAL (operands[2]))
4762     {
4763     case 0:
4764       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4765                                  simplify_gen_subreg (V2DFmode, operands[1],
4766                                                       DFmode, 0)));
4767       break;
4768     case 1:
4769       {
4770         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4771
4772         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4773       }
4774       break;
4775     default:
4776       abort ();
4777     }
4778   DONE;
4779 })
4780
4781 (define_expand "vec_extractv2df"
4782   [(match_operand:DF 0 "register_operand" "")
4783    (match_operand:V2DF 1 "register_operand" "")
4784    (match_operand 2 "const_int_operand" "")]
4785   "TARGET_SSE2"
4786 {
4787   switch (INTVAL (operands[2]))
4788     {
4789     case 0:
4790       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4791       break;
4792     case 1:
4793       {
4794         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4795
4796         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4797       }
4798       break;
4799     default:
4800       abort ();
4801     }
4802   DONE;
4803 })
4804
4805 (define_expand "vec_initv2df"
4806   [(match_operand:V2DF 0 "register_operand" "")
4807    (match_operand 1 "" "")]
4808   "TARGET_SSE2"
4809 {
4810   ix86_expand_vector_init (operands[0], operands[1]);
4811   DONE;
4812 })
4813
4814 (define_expand "vec_setv4sf"
4815   [(match_operand:V4SF 0 "register_operand" "")
4816    (match_operand:SF 1 "register_operand" "")
4817    (match_operand 2 "const_int_operand" "")]
4818   "TARGET_SSE"
4819 {
4820   switch (INTVAL (operands[2]))
4821     {
4822     case 0:
4823       emit_insn (gen_sse_movss (operands[0], operands[0],
4824                                 simplify_gen_subreg (V4SFmode, operands[1],
4825                                                      SFmode, 0)));
4826       break;
4827     case 1:
4828       {
4829         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4830         rtx tmp = gen_reg_rtx (V4SFmode);
4831  
4832         emit_move_insn (tmp, operands[0]);
4833         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4834         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4835         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4837       }
4838       break;
4839     case 2:
4840       {
4841         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4842         rtx tmp = gen_reg_rtx (V4SFmode);
4843
4844         emit_move_insn (tmp, operands[0]);
4845         emit_insn (gen_sse_movss (tmp, tmp, op1));
4846         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4847                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4848       }
4849       break;
4850     case 3:
4851       {
4852         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4853         rtx tmp = gen_reg_rtx (V4SFmode);
4854
4855         emit_move_insn (tmp, operands[0]);
4856         emit_insn (gen_sse_movss (tmp, tmp, op1));
4857         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4858                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4859       }
4860       break;
4861     default:
4862       abort ();
4863     }
4864   DONE;
4865 })
4866
4867 (define_expand "vec_extractv4sf"
4868   [(match_operand:SF 0 "register_operand" "")
4869    (match_operand:V4SF 1 "register_operand" "")
4870    (match_operand 2 "const_int_operand" "")]
4871   "TARGET_SSE"
4872 {
4873   switch (INTVAL (operands[2]))
4874     {
4875     case 0:
4876       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4877       break;
4878     case 1:
4879       {
4880         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4881         rtx tmp = gen_reg_rtx (V4SFmode);
4882  
4883         emit_move_insn (tmp, operands[1]);
4884         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4885                                    const1_rtx));
4886       }
4887       break;
4888     case 2:
4889       {
4890         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4891         rtx tmp = gen_reg_rtx (V4SFmode);
4892  
4893         emit_move_insn (tmp, operands[1]);
4894         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4895       }
4896       break;
4897     case 3:
4898       {
4899         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4900         rtx tmp = gen_reg_rtx (V4SFmode);
4901  
4902         emit_move_insn (tmp, operands[1]);
4903         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4904                                    GEN_INT (3)));
4905       }
4906       break;
4907     default:
4908       abort ();
4909     }
4910   DONE;
4911 })
4912
4913 (define_expand "vec_initv4sf"
4914   [(match_operand:V4SF 0 "register_operand" "")
4915    (match_operand 1 "" "")]
4916   "TARGET_SSE"
4917 {
4918   ix86_expand_vector_init (operands[0], operands[1]);
4919   DONE;
4920 })
4921 \f
4922 ;; Add instructions
4923
4924 ;; %%% splits for addsidi3
4925 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4926 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4927 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4928
4929 (define_expand "adddi3"
4930   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4931         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4932                  (match_operand:DI 2 "x86_64_general_operand" "")))
4933    (clobber (reg:CC FLAGS_REG))]
4934   ""
4935   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4936
4937 (define_insn "*adddi3_1"
4938   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4939         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4940                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4941    (clobber (reg:CC FLAGS_REG))]
4942   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4943   "#")
4944
4945 (define_split
4946   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4947         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4948                  (match_operand:DI 2 "general_operand" "")))
4949    (clobber (reg:CC FLAGS_REG))]
4950   "!TARGET_64BIT && reload_completed"
4951   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4952                                           UNSPEC_ADD_CARRY))
4953               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4954    (parallel [(set (match_dup 3)
4955                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4956                                      (match_dup 4))
4957                             (match_dup 5)))
4958               (clobber (reg:CC FLAGS_REG))])]
4959   "split_di (operands+0, 1, operands+0, operands+3);
4960    split_di (operands+1, 1, operands+1, operands+4);
4961    split_di (operands+2, 1, operands+2, operands+5);")
4962
4963 (define_insn "adddi3_carry_rex64"
4964   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4965           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4966                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4967                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4968    (clobber (reg:CC FLAGS_REG))]
4969   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4970   "adc{q}\t{%2, %0|%0, %2}"
4971   [(set_attr "type" "alu")
4972    (set_attr "pent_pair" "pu")
4973    (set_attr "mode" "DI")])
4974
4975 (define_insn "*adddi3_cc_rex64"
4976   [(set (reg:CC FLAGS_REG)
4977         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4978                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4979                    UNSPEC_ADD_CARRY))
4980    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4981         (plus:DI (match_dup 1) (match_dup 2)))]
4982   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4983   "add{q}\t{%2, %0|%0, %2}"
4984   [(set_attr "type" "alu")
4985    (set_attr "mode" "DI")])
4986
4987 (define_insn "addqi3_carry"
4988   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4989           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4990                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4991                    (match_operand:QI 2 "general_operand" "qi,qm")))
4992    (clobber (reg:CC FLAGS_REG))]
4993   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4994   "adc{b}\t{%2, %0|%0, %2}"
4995   [(set_attr "type" "alu")
4996    (set_attr "pent_pair" "pu")
4997    (set_attr "mode" "QI")])
4998
4999 (define_insn "addhi3_carry"
5000   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5001           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5002                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5003                    (match_operand:HI 2 "general_operand" "ri,rm")))
5004    (clobber (reg:CC FLAGS_REG))]
5005   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5006   "adc{w}\t{%2, %0|%0, %2}"
5007   [(set_attr "type" "alu")
5008    (set_attr "pent_pair" "pu")
5009    (set_attr "mode" "HI")])
5010
5011 (define_insn "addsi3_carry"
5012   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5013           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5014                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5015                    (match_operand:SI 2 "general_operand" "ri,rm")))
5016    (clobber (reg:CC FLAGS_REG))]
5017   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5018   "adc{l}\t{%2, %0|%0, %2}"
5019   [(set_attr "type" "alu")
5020    (set_attr "pent_pair" "pu")
5021    (set_attr "mode" "SI")])
5022
5023 (define_insn "*addsi3_carry_zext"
5024   [(set (match_operand:DI 0 "register_operand" "=r")
5025           (zero_extend:DI 
5026             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5027                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5028                      (match_operand:SI 2 "general_operand" "rim"))))
5029    (clobber (reg:CC FLAGS_REG))]
5030   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5031   "adc{l}\t{%2, %k0|%k0, %2}"
5032   [(set_attr "type" "alu")
5033    (set_attr "pent_pair" "pu")
5034    (set_attr "mode" "SI")])
5035
5036 (define_insn "*addsi3_cc"
5037   [(set (reg:CC FLAGS_REG)
5038         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5039                     (match_operand:SI 2 "general_operand" "ri,rm")]
5040                    UNSPEC_ADD_CARRY))
5041    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5042         (plus:SI (match_dup 1) (match_dup 2)))]
5043   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5044   "add{l}\t{%2, %0|%0, %2}"
5045   [(set_attr "type" "alu")
5046    (set_attr "mode" "SI")])
5047
5048 (define_insn "addqi3_cc"
5049   [(set (reg:CC FLAGS_REG)
5050         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5051                     (match_operand:QI 2 "general_operand" "qi,qm")]
5052                    UNSPEC_ADD_CARRY))
5053    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5054         (plus:QI (match_dup 1) (match_dup 2)))]
5055   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5056   "add{b}\t{%2, %0|%0, %2}"
5057   [(set_attr "type" "alu")
5058    (set_attr "mode" "QI")])
5059
5060 (define_expand "addsi3"
5061   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5062                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5063                             (match_operand:SI 2 "general_operand" "")))
5064               (clobber (reg:CC FLAGS_REG))])]
5065   ""
5066   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5067
5068 (define_insn "*lea_1"
5069   [(set (match_operand:SI 0 "register_operand" "=r")
5070         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5071   "!TARGET_64BIT"
5072   "lea{l}\t{%a1, %0|%0, %a1}"
5073   [(set_attr "type" "lea")
5074    (set_attr "mode" "SI")])
5075
5076 (define_insn "*lea_1_rex64"
5077   [(set (match_operand:SI 0 "register_operand" "=r")
5078         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5079   "TARGET_64BIT"
5080   "lea{l}\t{%a1, %0|%0, %a1}"
5081   [(set_attr "type" "lea")
5082    (set_attr "mode" "SI")])
5083
5084 (define_insn "*lea_1_zext"
5085   [(set (match_operand:DI 0 "register_operand" "=r")
5086         (zero_extend:DI
5087          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5088   "TARGET_64BIT"
5089   "lea{l}\t{%a1, %k0|%k0, %a1}"
5090   [(set_attr "type" "lea")
5091    (set_attr "mode" "SI")])
5092
5093 (define_insn "*lea_2_rex64"
5094   [(set (match_operand:DI 0 "register_operand" "=r")
5095         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5096   "TARGET_64BIT"
5097   "lea{q}\t{%a1, %0|%0, %a1}"
5098   [(set_attr "type" "lea")
5099    (set_attr "mode" "DI")])
5100
5101 ;; The lea patterns for non-Pmodes needs to be matched by several
5102 ;; insns converted to real lea by splitters.
5103
5104 (define_insn_and_split "*lea_general_1"
5105   [(set (match_operand 0 "register_operand" "=r")
5106         (plus (plus (match_operand 1 "index_register_operand" "l")
5107                     (match_operand 2 "register_operand" "r"))
5108               (match_operand 3 "immediate_operand" "i")))]
5109   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5110     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5111    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5112    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5113    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5114    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5115        || GET_MODE (operands[3]) == VOIDmode)"
5116   "#"
5117   "&& reload_completed"
5118   [(const_int 0)]
5119 {
5120   rtx pat;
5121   operands[0] = gen_lowpart (SImode, operands[0]);
5122   operands[1] = gen_lowpart (Pmode, operands[1]);
5123   operands[2] = gen_lowpart (Pmode, operands[2]);
5124   operands[3] = gen_lowpart (Pmode, operands[3]);
5125   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5126                       operands[3]);
5127   if (Pmode != SImode)
5128     pat = gen_rtx_SUBREG (SImode, pat, 0);
5129   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5130   DONE;
5131 }
5132   [(set_attr "type" "lea")
5133    (set_attr "mode" "SI")])
5134
5135 (define_insn_and_split "*lea_general_1_zext"
5136   [(set (match_operand:DI 0 "register_operand" "=r")
5137         (zero_extend:DI
5138           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5139                             (match_operand:SI 2 "register_operand" "r"))
5140                    (match_operand:SI 3 "immediate_operand" "i"))))]
5141   "TARGET_64BIT"
5142   "#"
5143   "&& reload_completed"
5144   [(set (match_dup 0)
5145         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5146                                                      (match_dup 2))
5147                                             (match_dup 3)) 0)))]
5148 {
5149   operands[1] = gen_lowpart (Pmode, operands[1]);
5150   operands[2] = gen_lowpart (Pmode, operands[2]);
5151   operands[3] = gen_lowpart (Pmode, operands[3]);
5152 }
5153   [(set_attr "type" "lea")
5154    (set_attr "mode" "SI")])
5155
5156 (define_insn_and_split "*lea_general_2"
5157   [(set (match_operand 0 "register_operand" "=r")
5158         (plus (mult (match_operand 1 "index_register_operand" "l")
5159                     (match_operand 2 "const248_operand" "i"))
5160               (match_operand 3 "nonmemory_operand" "ri")))]
5161   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5162     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5163    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5164    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5165    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5166        || GET_MODE (operands[3]) == VOIDmode)"
5167   "#"
5168   "&& reload_completed"
5169   [(const_int 0)]
5170 {
5171   rtx pat;
5172   operands[0] = gen_lowpart (SImode, operands[0]);
5173   operands[1] = gen_lowpart (Pmode, operands[1]);
5174   operands[3] = gen_lowpart (Pmode, operands[3]);
5175   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5176                       operands[3]);
5177   if (Pmode != SImode)
5178     pat = gen_rtx_SUBREG (SImode, pat, 0);
5179   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5180   DONE;
5181 }
5182   [(set_attr "type" "lea")
5183    (set_attr "mode" "SI")])
5184
5185 (define_insn_and_split "*lea_general_2_zext"
5186   [(set (match_operand:DI 0 "register_operand" "=r")
5187         (zero_extend:DI
5188           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5189                             (match_operand:SI 2 "const248_operand" "n"))
5190                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5191   "TARGET_64BIT"
5192   "#"
5193   "&& reload_completed"
5194   [(set (match_dup 0)
5195         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5196                                                      (match_dup 2))
5197                                             (match_dup 3)) 0)))]
5198 {
5199   operands[1] = gen_lowpart (Pmode, operands[1]);
5200   operands[3] = gen_lowpart (Pmode, operands[3]);
5201 }
5202   [(set_attr "type" "lea")
5203    (set_attr "mode" "SI")])
5204
5205 (define_insn_and_split "*lea_general_3"
5206   [(set (match_operand 0 "register_operand" "=r")
5207         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5208                           (match_operand 2 "const248_operand" "i"))
5209                     (match_operand 3 "register_operand" "r"))
5210               (match_operand 4 "immediate_operand" "i")))]
5211   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5212     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5213    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5214    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5215    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5216   "#"
5217   "&& reload_completed"
5218   [(const_int 0)]
5219 {
5220   rtx pat;
5221   operands[0] = gen_lowpart (SImode, operands[0]);
5222   operands[1] = gen_lowpart (Pmode, operands[1]);
5223   operands[3] = gen_lowpart (Pmode, operands[3]);
5224   operands[4] = gen_lowpart (Pmode, operands[4]);
5225   pat = gen_rtx_PLUS (Pmode,
5226                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5227                                                          operands[2]),
5228                                     operands[3]),
5229                       operands[4]);
5230   if (Pmode != SImode)
5231     pat = gen_rtx_SUBREG (SImode, pat, 0);
5232   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5233   DONE;
5234 }
5235   [(set_attr "type" "lea")
5236    (set_attr "mode" "SI")])
5237
5238 (define_insn_and_split "*lea_general_3_zext"
5239   [(set (match_operand:DI 0 "register_operand" "=r")
5240         (zero_extend:DI
5241           (plus:SI (plus:SI (mult:SI
5242                               (match_operand:SI 1 "index_register_operand" "l")
5243                               (match_operand:SI 2 "const248_operand" "n"))
5244                             (match_operand:SI 3 "register_operand" "r"))
5245                    (match_operand:SI 4 "immediate_operand" "i"))))]
5246   "TARGET_64BIT"
5247   "#"
5248   "&& reload_completed"
5249   [(set (match_dup 0)
5250         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5251                                                               (match_dup 2))
5252                                                      (match_dup 3))
5253                                             (match_dup 4)) 0)))]
5254 {
5255   operands[1] = gen_lowpart (Pmode, operands[1]);
5256   operands[3] = gen_lowpart (Pmode, operands[3]);
5257   operands[4] = gen_lowpart (Pmode, operands[4]);
5258 }
5259   [(set_attr "type" "lea")
5260    (set_attr "mode" "SI")])
5261
5262 (define_insn "*adddi_1_rex64"
5263   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5264         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5265                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5266    (clobber (reg:CC FLAGS_REG))]
5267   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5268 {
5269   switch (get_attr_type (insn))
5270     {
5271     case TYPE_LEA:
5272       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5273       return "lea{q}\t{%a2, %0|%0, %a2}";
5274
5275     case TYPE_INCDEC:
5276       if (! rtx_equal_p (operands[0], operands[1]))
5277         abort ();
5278       if (operands[2] == const1_rtx)
5279         return "inc{q}\t%0";
5280       else if (operands[2] == constm1_rtx)
5281         return "dec{q}\t%0";
5282       else
5283         abort ();
5284
5285     default:
5286       if (! rtx_equal_p (operands[0], operands[1]))
5287         abort ();
5288
5289       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5290          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5291       if (GET_CODE (operands[2]) == CONST_INT
5292           /* Avoid overflows.  */
5293           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5294           && (INTVAL (operands[2]) == 128
5295               || (INTVAL (operands[2]) < 0
5296                   && INTVAL (operands[2]) != -128)))
5297         {
5298           operands[2] = GEN_INT (-INTVAL (operands[2]));
5299           return "sub{q}\t{%2, %0|%0, %2}";
5300         }
5301       return "add{q}\t{%2, %0|%0, %2}";
5302     }
5303 }
5304   [(set (attr "type")
5305      (cond [(eq_attr "alternative" "2")
5306               (const_string "lea")
5307             ; Current assemblers are broken and do not allow @GOTOFF in
5308             ; ought but a memory context.
5309             (match_operand:DI 2 "pic_symbolic_operand" "")
5310               (const_string "lea")
5311             (match_operand:DI 2 "incdec_operand" "")
5312               (const_string "incdec")
5313            ]
5314            (const_string "alu")))
5315    (set_attr "mode" "DI")])
5316
5317 ;; Convert lea to the lea pattern to avoid flags dependency.
5318 (define_split
5319   [(set (match_operand:DI 0 "register_operand" "")
5320         (plus:DI (match_operand:DI 1 "register_operand" "")
5321                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5322    (clobber (reg:CC FLAGS_REG))]
5323   "TARGET_64BIT && reload_completed
5324    && true_regnum (operands[0]) != true_regnum (operands[1])"
5325   [(set (match_dup 0)
5326         (plus:DI (match_dup 1)
5327                  (match_dup 2)))]
5328   "")
5329
5330 (define_insn "*adddi_2_rex64"
5331   [(set (reg FLAGS_REG)
5332         (compare
5333           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5334                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5335           (const_int 0)))                       
5336    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5337         (plus:DI (match_dup 1) (match_dup 2)))]
5338   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5339    && ix86_binary_operator_ok (PLUS, DImode, operands)
5340    /* Current assemblers are broken and do not allow @GOTOFF in
5341       ought but a memory context.  */
5342    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5343 {
5344   switch (get_attr_type (insn))
5345     {
5346     case TYPE_INCDEC:
5347       if (! rtx_equal_p (operands[0], operands[1]))
5348         abort ();
5349       if (operands[2] == const1_rtx)
5350         return "inc{q}\t%0";
5351       else if (operands[2] == constm1_rtx)
5352         return "dec{q}\t%0";
5353       else
5354         abort ();
5355
5356     default:
5357       if (! rtx_equal_p (operands[0], operands[1]))
5358         abort ();
5359       /* ???? We ought to handle there the 32bit case too
5360          - do we need new constraint?  */
5361       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5363       if (GET_CODE (operands[2]) == CONST_INT
5364           /* Avoid overflows.  */
5365           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366           && (INTVAL (operands[2]) == 128
5367               || (INTVAL (operands[2]) < 0
5368                   && INTVAL (operands[2]) != -128)))
5369         {
5370           operands[2] = GEN_INT (-INTVAL (operands[2]));
5371           return "sub{q}\t{%2, %0|%0, %2}";
5372         }
5373       return "add{q}\t{%2, %0|%0, %2}";
5374     }
5375 }
5376   [(set (attr "type")
5377      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378         (const_string "incdec")
5379         (const_string "alu")))
5380    (set_attr "mode" "DI")])
5381
5382 (define_insn "*adddi_3_rex64"
5383   [(set (reg FLAGS_REG)
5384         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5385                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5386    (clobber (match_scratch:DI 0 "=r"))]
5387   "TARGET_64BIT
5388    && ix86_match_ccmode (insn, CCZmode)
5389    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5390    /* Current assemblers are broken and do not allow @GOTOFF in
5391       ought but a memory context.  */
5392    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5393 {
5394   switch (get_attr_type (insn))
5395     {
5396     case TYPE_INCDEC:
5397       if (! rtx_equal_p (operands[0], operands[1]))
5398         abort ();
5399       if (operands[2] == const1_rtx)
5400         return "inc{q}\t%0";
5401       else if (operands[2] == constm1_rtx)
5402         return "dec{q}\t%0";
5403       else
5404         abort ();
5405
5406     default:
5407       if (! rtx_equal_p (operands[0], operands[1]))
5408         abort ();
5409       /* ???? We ought to handle there the 32bit case too
5410          - do we need new constraint?  */
5411       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5412          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5413       if (GET_CODE (operands[2]) == CONST_INT
5414           /* Avoid overflows.  */
5415           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5416           && (INTVAL (operands[2]) == 128
5417               || (INTVAL (operands[2]) < 0
5418                   && INTVAL (operands[2]) != -128)))
5419         {
5420           operands[2] = GEN_INT (-INTVAL (operands[2]));
5421           return "sub{q}\t{%2, %0|%0, %2}";
5422         }
5423       return "add{q}\t{%2, %0|%0, %2}";
5424     }
5425 }
5426   [(set (attr "type")
5427      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5428         (const_string "incdec")
5429         (const_string "alu")))
5430    (set_attr "mode" "DI")])
5431
5432 ; For comparisons against 1, -1 and 128, we may generate better code
5433 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5434 ; is matched then.  We can't accept general immediate, because for
5435 ; case of overflows,  the result is messed up.
5436 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5437 ; when negated.
5438 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5439 ; only for comparisons not depending on it.
5440 (define_insn "*adddi_4_rex64"
5441   [(set (reg FLAGS_REG)
5442         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5443                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5444    (clobber (match_scratch:DI 0 "=rm"))]
5445   "TARGET_64BIT
5446    &&  ix86_match_ccmode (insn, CCGCmode)"
5447 {
5448   switch (get_attr_type (insn))
5449     {
5450     case TYPE_INCDEC:
5451       if (operands[2] == constm1_rtx)
5452         return "inc{q}\t%0";
5453       else if (operands[2] == const1_rtx)
5454         return "dec{q}\t%0";
5455       else
5456         abort();
5457
5458     default:
5459       if (! rtx_equal_p (operands[0], operands[1]))
5460         abort ();
5461       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5462          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5463       if ((INTVAL (operands[2]) == -128
5464            || (INTVAL (operands[2]) > 0
5465                && INTVAL (operands[2]) != 128))
5466           /* Avoid overflows.  */
5467           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5468         return "sub{q}\t{%2, %0|%0, %2}";
5469       operands[2] = GEN_INT (-INTVAL (operands[2]));
5470       return "add{q}\t{%2, %0|%0, %2}";
5471     }
5472 }
5473   [(set (attr "type")
5474      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5475         (const_string "incdec")
5476         (const_string "alu")))
5477    (set_attr "mode" "DI")])
5478
5479 (define_insn "*adddi_5_rex64"
5480   [(set (reg FLAGS_REG)
5481         (compare
5482           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5483                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5484           (const_int 0)))                       
5485    (clobber (match_scratch:DI 0 "=r"))]
5486   "TARGET_64BIT
5487    && ix86_match_ccmode (insn, CCGOCmode)
5488    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5489    /* Current assemblers are broken and do not allow @GOTOFF in
5490       ought but a memory context.  */
5491    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5492 {
5493   switch (get_attr_type (insn))
5494     {
5495     case TYPE_INCDEC:
5496       if (! rtx_equal_p (operands[0], operands[1]))
5497         abort ();
5498       if (operands[2] == const1_rtx)
5499         return "inc{q}\t%0";
5500       else if (operands[2] == constm1_rtx)
5501         return "dec{q}\t%0";
5502       else
5503         abort();
5504
5505     default:
5506       if (! rtx_equal_p (operands[0], operands[1]))
5507         abort ();
5508       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5509          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5510       if (GET_CODE (operands[2]) == CONST_INT
5511           /* Avoid overflows.  */
5512           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5513           && (INTVAL (operands[2]) == 128
5514               || (INTVAL (operands[2]) < 0
5515                   && INTVAL (operands[2]) != -128)))
5516         {
5517           operands[2] = GEN_INT (-INTVAL (operands[2]));
5518           return "sub{q}\t{%2, %0|%0, %2}";
5519         }
5520       return "add{q}\t{%2, %0|%0, %2}";
5521     }
5522 }
5523   [(set (attr "type")
5524      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5525         (const_string "incdec")
5526         (const_string "alu")))
5527    (set_attr "mode" "DI")])
5528
5529
5530 (define_insn "*addsi_1"
5531   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5532         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5533                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5534    (clobber (reg:CC FLAGS_REG))]
5535   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5536 {
5537   switch (get_attr_type (insn))
5538     {
5539     case TYPE_LEA:
5540       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5541       return "lea{l}\t{%a2, %0|%0, %a2}";
5542
5543     case TYPE_INCDEC:
5544       if (! rtx_equal_p (operands[0], operands[1]))
5545         abort ();
5546       if (operands[2] == const1_rtx)
5547         return "inc{l}\t%0";
5548       else if (operands[2] == constm1_rtx)
5549         return "dec{l}\t%0";
5550       else
5551         abort();
5552
5553     default:
5554       if (! rtx_equal_p (operands[0], operands[1]))
5555         abort ();
5556
5557       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5558          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5559       if (GET_CODE (operands[2]) == CONST_INT
5560           && (INTVAL (operands[2]) == 128
5561               || (INTVAL (operands[2]) < 0
5562                   && INTVAL (operands[2]) != -128)))
5563         {
5564           operands[2] = GEN_INT (-INTVAL (operands[2]));
5565           return "sub{l}\t{%2, %0|%0, %2}";
5566         }
5567       return "add{l}\t{%2, %0|%0, %2}";
5568     }
5569 }
5570   [(set (attr "type")
5571      (cond [(eq_attr "alternative" "2")
5572               (const_string "lea")
5573             ; Current assemblers are broken and do not allow @GOTOFF in
5574             ; ought but a memory context.
5575             (match_operand:SI 2 "pic_symbolic_operand" "")
5576               (const_string "lea")
5577             (match_operand:SI 2 "incdec_operand" "")
5578               (const_string "incdec")
5579            ]
5580            (const_string "alu")))
5581    (set_attr "mode" "SI")])
5582
5583 ;; Convert lea to the lea pattern to avoid flags dependency.
5584 (define_split
5585   [(set (match_operand 0 "register_operand" "")
5586         (plus (match_operand 1 "register_operand" "")
5587               (match_operand 2 "nonmemory_operand" "")))
5588    (clobber (reg:CC FLAGS_REG))]
5589   "reload_completed
5590    && true_regnum (operands[0]) != true_regnum (operands[1])"
5591   [(const_int 0)]
5592 {
5593   rtx pat;
5594   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5595      may confuse gen_lowpart.  */
5596   if (GET_MODE (operands[0]) != Pmode)
5597     {
5598       operands[1] = gen_lowpart (Pmode, operands[1]);
5599       operands[2] = gen_lowpart (Pmode, operands[2]);
5600     }
5601   operands[0] = gen_lowpart (SImode, operands[0]);
5602   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5603   if (Pmode != SImode)
5604     pat = gen_rtx_SUBREG (SImode, pat, 0);
5605   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5606   DONE;
5607 })
5608
5609 ;; It may seem that nonimmediate operand is proper one for operand 1.
5610 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5611 ;; we take care in ix86_binary_operator_ok to not allow two memory
5612 ;; operands so proper swapping will be done in reload.  This allow
5613 ;; patterns constructed from addsi_1 to match.
5614 (define_insn "addsi_1_zext"
5615   [(set (match_operand:DI 0 "register_operand" "=r,r")
5616         (zero_extend:DI
5617           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5618                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5619    (clobber (reg:CC FLAGS_REG))]
5620   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5621 {
5622   switch (get_attr_type (insn))
5623     {
5624     case TYPE_LEA:
5625       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5626       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5627
5628     case TYPE_INCDEC:
5629       if (operands[2] == const1_rtx)
5630         return "inc{l}\t%k0";
5631       else if (operands[2] == constm1_rtx)
5632         return "dec{l}\t%k0";
5633       else
5634         abort();
5635
5636     default:
5637       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5639       if (GET_CODE (operands[2]) == CONST_INT
5640           && (INTVAL (operands[2]) == 128
5641               || (INTVAL (operands[2]) < 0
5642                   && INTVAL (operands[2]) != -128)))
5643         {
5644           operands[2] = GEN_INT (-INTVAL (operands[2]));
5645           return "sub{l}\t{%2, %k0|%k0, %2}";
5646         }
5647       return "add{l}\t{%2, %k0|%k0, %2}";
5648     }
5649 }
5650   [(set (attr "type")
5651      (cond [(eq_attr "alternative" "1")
5652               (const_string "lea")
5653             ; Current assemblers are broken and do not allow @GOTOFF in
5654             ; ought but a memory context.
5655             (match_operand:SI 2 "pic_symbolic_operand" "")
5656               (const_string "lea")
5657             (match_operand:SI 2 "incdec_operand" "")
5658               (const_string "incdec")
5659            ]
5660            (const_string "alu")))
5661    (set_attr "mode" "SI")])
5662
5663 ;; Convert lea to the lea pattern to avoid flags dependency.
5664 (define_split
5665   [(set (match_operand:DI 0 "register_operand" "")
5666         (zero_extend:DI
5667           (plus:SI (match_operand:SI 1 "register_operand" "")
5668                    (match_operand:SI 2 "nonmemory_operand" ""))))
5669    (clobber (reg:CC FLAGS_REG))]
5670   "TARGET_64BIT && reload_completed
5671    && true_regnum (operands[0]) != true_regnum (operands[1])"
5672   [(set (match_dup 0)
5673         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5674 {
5675   operands[1] = gen_lowpart (Pmode, operands[1]);
5676   operands[2] = gen_lowpart (Pmode, operands[2]);
5677 })
5678
5679 (define_insn "*addsi_2"
5680   [(set (reg FLAGS_REG)
5681         (compare
5682           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5683                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5684           (const_int 0)))                       
5685    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5686         (plus:SI (match_dup 1) (match_dup 2)))]
5687   "ix86_match_ccmode (insn, CCGOCmode)
5688    && ix86_binary_operator_ok (PLUS, SImode, operands)
5689    /* Current assemblers are broken and do not allow @GOTOFF in
5690       ought but a memory context.  */
5691    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5692 {
5693   switch (get_attr_type (insn))
5694     {
5695     case TYPE_INCDEC:
5696       if (! rtx_equal_p (operands[0], operands[1]))
5697         abort ();
5698       if (operands[2] == const1_rtx)
5699         return "inc{l}\t%0";
5700       else if (operands[2] == constm1_rtx)
5701         return "dec{l}\t%0";
5702       else
5703         abort();
5704
5705     default:
5706       if (! rtx_equal_p (operands[0], operands[1]))
5707         abort ();
5708       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5709          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5710       if (GET_CODE (operands[2]) == CONST_INT
5711           && (INTVAL (operands[2]) == 128
5712               || (INTVAL (operands[2]) < 0
5713                   && INTVAL (operands[2]) != -128)))
5714         {
5715           operands[2] = GEN_INT (-INTVAL (operands[2]));
5716           return "sub{l}\t{%2, %0|%0, %2}";
5717         }
5718       return "add{l}\t{%2, %0|%0, %2}";
5719     }
5720 }
5721   [(set (attr "type")
5722      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5723         (const_string "incdec")
5724         (const_string "alu")))
5725    (set_attr "mode" "SI")])
5726
5727 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5728 (define_insn "*addsi_2_zext"
5729   [(set (reg FLAGS_REG)
5730         (compare
5731           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5732                    (match_operand:SI 2 "general_operand" "rmni"))
5733           (const_int 0)))                       
5734    (set (match_operand:DI 0 "register_operand" "=r")
5735         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5736   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5737    && ix86_binary_operator_ok (PLUS, SImode, operands)
5738    /* Current assemblers are broken and do not allow @GOTOFF in
5739       ought but a memory context.  */
5740    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5741 {
5742   switch (get_attr_type (insn))
5743     {
5744     case TYPE_INCDEC:
5745       if (operands[2] == const1_rtx)
5746         return "inc{l}\t%k0";
5747       else if (operands[2] == constm1_rtx)
5748         return "dec{l}\t%k0";
5749       else
5750         abort();
5751
5752     default:
5753       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5754          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5755       if (GET_CODE (operands[2]) == CONST_INT
5756           && (INTVAL (operands[2]) == 128
5757               || (INTVAL (operands[2]) < 0
5758                   && INTVAL (operands[2]) != -128)))
5759         {
5760           operands[2] = GEN_INT (-INTVAL (operands[2]));
5761           return "sub{l}\t{%2, %k0|%k0, %2}";
5762         }
5763       return "add{l}\t{%2, %k0|%k0, %2}";
5764     }
5765 }
5766   [(set (attr "type")
5767      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5768         (const_string "incdec")
5769         (const_string "alu")))
5770    (set_attr "mode" "SI")])
5771
5772 (define_insn "*addsi_3"
5773   [(set (reg FLAGS_REG)
5774         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5775                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5776    (clobber (match_scratch:SI 0 "=r"))]
5777   "ix86_match_ccmode (insn, CCZmode)
5778    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5779    /* Current assemblers are broken and do not allow @GOTOFF in
5780       ought but a memory context.  */
5781    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5782 {
5783   switch (get_attr_type (insn))
5784     {
5785     case TYPE_INCDEC:
5786       if (! rtx_equal_p (operands[0], operands[1]))
5787         abort ();
5788       if (operands[2] == const1_rtx)
5789         return "inc{l}\t%0";
5790       else if (operands[2] == constm1_rtx)
5791         return "dec{l}\t%0";
5792       else
5793         abort();
5794
5795     default:
5796       if (! rtx_equal_p (operands[0], operands[1]))
5797         abort ();
5798       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5800       if (GET_CODE (operands[2]) == CONST_INT
5801           && (INTVAL (operands[2]) == 128
5802               || (INTVAL (operands[2]) < 0
5803                   && INTVAL (operands[2]) != -128)))
5804         {
5805           operands[2] = GEN_INT (-INTVAL (operands[2]));
5806           return "sub{l}\t{%2, %0|%0, %2}";
5807         }
5808       return "add{l}\t{%2, %0|%0, %2}";
5809     }
5810 }
5811   [(set (attr "type")
5812      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813         (const_string "incdec")
5814         (const_string "alu")))
5815    (set_attr "mode" "SI")])
5816
5817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5818 (define_insn "*addsi_3_zext"
5819   [(set (reg FLAGS_REG)
5820         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5821                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5822    (set (match_operand:DI 0 "register_operand" "=r")
5823         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5824   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5825    && ix86_binary_operator_ok (PLUS, SImode, operands)
5826    /* Current assemblers are broken and do not allow @GOTOFF in
5827       ought but a memory context.  */
5828    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5829 {
5830   switch (get_attr_type (insn))
5831     {
5832     case TYPE_INCDEC:
5833       if (operands[2] == const1_rtx)
5834         return "inc{l}\t%k0";
5835       else if (operands[2] == constm1_rtx)
5836         return "dec{l}\t%k0";
5837       else
5838         abort();
5839
5840     default:
5841       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5843       if (GET_CODE (operands[2]) == CONST_INT
5844           && (INTVAL (operands[2]) == 128
5845               || (INTVAL (operands[2]) < 0
5846                   && INTVAL (operands[2]) != -128)))
5847         {
5848           operands[2] = GEN_INT (-INTVAL (operands[2]));
5849           return "sub{l}\t{%2, %k0|%k0, %2}";
5850         }
5851       return "add{l}\t{%2, %k0|%k0, %2}";
5852     }
5853 }
5854   [(set (attr "type")
5855      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5856         (const_string "incdec")
5857         (const_string "alu")))
5858    (set_attr "mode" "SI")])
5859
5860 ; For comparisons against 1, -1 and 128, we may generate better code
5861 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5862 ; is matched then.  We can't accept general immediate, because for
5863 ; case of overflows,  the result is messed up.
5864 ; This pattern also don't hold of 0x80000000, since the value overflows
5865 ; when negated.
5866 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5867 ; only for comparisons not depending on it.
5868 (define_insn "*addsi_4"
5869   [(set (reg FLAGS_REG)
5870         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5871                  (match_operand:SI 2 "const_int_operand" "n")))
5872    (clobber (match_scratch:SI 0 "=rm"))]
5873   "ix86_match_ccmode (insn, CCGCmode)
5874    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5875 {
5876   switch (get_attr_type (insn))
5877     {
5878     case TYPE_INCDEC:
5879       if (operands[2] == constm1_rtx)
5880         return "inc{l}\t%0";
5881       else if (operands[2] == const1_rtx)
5882         return "dec{l}\t%0";
5883       else
5884         abort();
5885
5886     default:
5887       if (! rtx_equal_p (operands[0], operands[1]))
5888         abort ();
5889       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5890          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5891       if ((INTVAL (operands[2]) == -128
5892            || (INTVAL (operands[2]) > 0
5893                && INTVAL (operands[2]) != 128)))
5894         return "sub{l}\t{%2, %0|%0, %2}";
5895       operands[2] = GEN_INT (-INTVAL (operands[2]));
5896       return "add{l}\t{%2, %0|%0, %2}";
5897     }
5898 }
5899   [(set (attr "type")
5900      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901         (const_string "incdec")
5902         (const_string "alu")))
5903    (set_attr "mode" "SI")])
5904
5905 (define_insn "*addsi_5"
5906   [(set (reg FLAGS_REG)
5907         (compare
5908           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5909                    (match_operand:SI 2 "general_operand" "rmni"))
5910           (const_int 0)))                       
5911    (clobber (match_scratch:SI 0 "=r"))]
5912   "ix86_match_ccmode (insn, CCGOCmode)
5913    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5914    /* Current assemblers are broken and do not allow @GOTOFF in
5915       ought but a memory context.  */
5916    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5917 {
5918   switch (get_attr_type (insn))
5919     {
5920     case TYPE_INCDEC:
5921       if (! rtx_equal_p (operands[0], operands[1]))
5922         abort ();
5923       if (operands[2] == const1_rtx)
5924         return "inc{l}\t%0";
5925       else if (operands[2] == constm1_rtx)
5926         return "dec{l}\t%0";
5927       else
5928         abort();
5929
5930     default:
5931       if (! rtx_equal_p (operands[0], operands[1]))
5932         abort ();
5933       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5934          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5935       if (GET_CODE (operands[2]) == CONST_INT
5936           && (INTVAL (operands[2]) == 128
5937               || (INTVAL (operands[2]) < 0
5938                   && INTVAL (operands[2]) != -128)))
5939         {
5940           operands[2] = GEN_INT (-INTVAL (operands[2]));
5941           return "sub{l}\t{%2, %0|%0, %2}";
5942         }
5943       return "add{l}\t{%2, %0|%0, %2}";
5944     }
5945 }
5946   [(set (attr "type")
5947      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5948         (const_string "incdec")
5949         (const_string "alu")))
5950    (set_attr "mode" "SI")])
5951
5952 (define_expand "addhi3"
5953   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5954                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5955                             (match_operand:HI 2 "general_operand" "")))
5956               (clobber (reg:CC FLAGS_REG))])]
5957   "TARGET_HIMODE_MATH"
5958   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5959
5960 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5961 ;; type optimizations enabled by define-splits.  This is not important
5962 ;; for PII, and in fact harmful because of partial register stalls.
5963
5964 (define_insn "*addhi_1_lea"
5965   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5966         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5967                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5968    (clobber (reg:CC FLAGS_REG))]
5969   "!TARGET_PARTIAL_REG_STALL
5970    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5971 {
5972   switch (get_attr_type (insn))
5973     {
5974     case TYPE_LEA:
5975       return "#";
5976     case TYPE_INCDEC:
5977       if (operands[2] == const1_rtx)
5978         return "inc{w}\t%0";
5979       else if (operands[2] == constm1_rtx)
5980         return "dec{w}\t%0";
5981       abort();
5982
5983     default:
5984       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5985          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5986       if (GET_CODE (operands[2]) == CONST_INT
5987           && (INTVAL (operands[2]) == 128
5988               || (INTVAL (operands[2]) < 0
5989                   && INTVAL (operands[2]) != -128)))
5990         {
5991           operands[2] = GEN_INT (-INTVAL (operands[2]));
5992           return "sub{w}\t{%2, %0|%0, %2}";
5993         }
5994       return "add{w}\t{%2, %0|%0, %2}";
5995     }
5996 }
5997   [(set (attr "type")
5998      (if_then_else (eq_attr "alternative" "2")
5999         (const_string "lea")
6000         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6001            (const_string "incdec")
6002            (const_string "alu"))))
6003    (set_attr "mode" "HI,HI,SI")])
6004
6005 (define_insn "*addhi_1"
6006   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6007         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6008                  (match_operand:HI 2 "general_operand" "ri,rm")))
6009    (clobber (reg:CC FLAGS_REG))]
6010   "TARGET_PARTIAL_REG_STALL
6011    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6012 {
6013   switch (get_attr_type (insn))
6014     {
6015     case TYPE_INCDEC:
6016       if (operands[2] == const1_rtx)
6017         return "inc{w}\t%0";
6018       else if (operands[2] == constm1_rtx)
6019         return "dec{w}\t%0";
6020       abort();
6021
6022     default:
6023       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6024          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6025       if (GET_CODE (operands[2]) == CONST_INT
6026           && (INTVAL (operands[2]) == 128
6027               || (INTVAL (operands[2]) < 0
6028                   && INTVAL (operands[2]) != -128)))
6029         {
6030           operands[2] = GEN_INT (-INTVAL (operands[2]));
6031           return "sub{w}\t{%2, %0|%0, %2}";
6032         }
6033       return "add{w}\t{%2, %0|%0, %2}";
6034     }
6035 }
6036   [(set (attr "type")
6037      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6038         (const_string "incdec")
6039         (const_string "alu")))
6040    (set_attr "mode" "HI")])
6041
6042 (define_insn "*addhi_2"
6043   [(set (reg FLAGS_REG)
6044         (compare
6045           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6046                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6047           (const_int 0)))                       
6048    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6049         (plus:HI (match_dup 1) (match_dup 2)))]
6050   "ix86_match_ccmode (insn, CCGOCmode)
6051    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6052 {
6053   switch (get_attr_type (insn))
6054     {
6055     case TYPE_INCDEC:
6056       if (operands[2] == const1_rtx)
6057         return "inc{w}\t%0";
6058       else if (operands[2] == constm1_rtx)
6059         return "dec{w}\t%0";
6060       abort();
6061
6062     default:
6063       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6065       if (GET_CODE (operands[2]) == CONST_INT
6066           && (INTVAL (operands[2]) == 128
6067               || (INTVAL (operands[2]) < 0
6068                   && INTVAL (operands[2]) != -128)))
6069         {
6070           operands[2] = GEN_INT (-INTVAL (operands[2]));
6071           return "sub{w}\t{%2, %0|%0, %2}";
6072         }
6073       return "add{w}\t{%2, %0|%0, %2}";
6074     }
6075 }
6076   [(set (attr "type")
6077      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078         (const_string "incdec")
6079         (const_string "alu")))
6080    (set_attr "mode" "HI")])
6081
6082 (define_insn "*addhi_3"
6083   [(set (reg FLAGS_REG)
6084         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6085                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6086    (clobber (match_scratch:HI 0 "=r"))]
6087   "ix86_match_ccmode (insn, CCZmode)
6088    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6089 {
6090   switch (get_attr_type (insn))
6091     {
6092     case TYPE_INCDEC:
6093       if (operands[2] == const1_rtx)
6094         return "inc{w}\t%0";
6095       else if (operands[2] == constm1_rtx)
6096         return "dec{w}\t%0";
6097       abort();
6098
6099     default:
6100       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6102       if (GET_CODE (operands[2]) == CONST_INT
6103           && (INTVAL (operands[2]) == 128
6104               || (INTVAL (operands[2]) < 0
6105                   && INTVAL (operands[2]) != -128)))
6106         {
6107           operands[2] = GEN_INT (-INTVAL (operands[2]));
6108           return "sub{w}\t{%2, %0|%0, %2}";
6109         }
6110       return "add{w}\t{%2, %0|%0, %2}";
6111     }
6112 }
6113   [(set (attr "type")
6114      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6115         (const_string "incdec")
6116         (const_string "alu")))
6117    (set_attr "mode" "HI")])
6118
6119 ; See comments above addsi_3_imm for details.
6120 (define_insn "*addhi_4"
6121   [(set (reg FLAGS_REG)
6122         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6123                  (match_operand:HI 2 "const_int_operand" "n")))
6124    (clobber (match_scratch:HI 0 "=rm"))]
6125   "ix86_match_ccmode (insn, CCGCmode)
6126    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6127 {
6128   switch (get_attr_type (insn))
6129     {
6130     case TYPE_INCDEC:
6131       if (operands[2] == constm1_rtx)
6132         return "inc{w}\t%0";
6133       else if (operands[2] == const1_rtx)
6134         return "dec{w}\t%0";
6135       else
6136         abort();
6137
6138     default:
6139       if (! rtx_equal_p (operands[0], operands[1]))
6140         abort ();
6141       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6143       if ((INTVAL (operands[2]) == -128
6144            || (INTVAL (operands[2]) > 0
6145                && INTVAL (operands[2]) != 128)))
6146         return "sub{w}\t{%2, %0|%0, %2}";
6147       operands[2] = GEN_INT (-INTVAL (operands[2]));
6148       return "add{w}\t{%2, %0|%0, %2}";
6149     }
6150 }
6151   [(set (attr "type")
6152      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153         (const_string "incdec")
6154         (const_string "alu")))
6155    (set_attr "mode" "SI")])
6156
6157
6158 (define_insn "*addhi_5"
6159   [(set (reg FLAGS_REG)
6160         (compare
6161           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6162                    (match_operand:HI 2 "general_operand" "rmni"))
6163           (const_int 0)))                       
6164    (clobber (match_scratch:HI 0 "=r"))]
6165   "ix86_match_ccmode (insn, CCGOCmode)
6166    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6167 {
6168   switch (get_attr_type (insn))
6169     {
6170     case TYPE_INCDEC:
6171       if (operands[2] == const1_rtx)
6172         return "inc{w}\t%0";
6173       else if (operands[2] == constm1_rtx)
6174         return "dec{w}\t%0";
6175       abort();
6176
6177     default:
6178       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6179          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6180       if (GET_CODE (operands[2]) == CONST_INT
6181           && (INTVAL (operands[2]) == 128
6182               || (INTVAL (operands[2]) < 0
6183                   && INTVAL (operands[2]) != -128)))
6184         {
6185           operands[2] = GEN_INT (-INTVAL (operands[2]));
6186           return "sub{w}\t{%2, %0|%0, %2}";
6187         }
6188       return "add{w}\t{%2, %0|%0, %2}";
6189     }
6190 }
6191   [(set (attr "type")
6192      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6193         (const_string "incdec")
6194         (const_string "alu")))
6195    (set_attr "mode" "HI")])
6196
6197 (define_expand "addqi3"
6198   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6199                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6200                             (match_operand:QI 2 "general_operand" "")))
6201               (clobber (reg:CC FLAGS_REG))])]
6202   "TARGET_QIMODE_MATH"
6203   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6204
6205 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6206 (define_insn "*addqi_1_lea"
6207   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6208         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6209                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6210    (clobber (reg:CC FLAGS_REG))]
6211   "!TARGET_PARTIAL_REG_STALL
6212    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6213 {
6214   int widen = (which_alternative == 2);
6215   switch (get_attr_type (insn))
6216     {
6217     case TYPE_LEA:
6218       return "#";
6219     case TYPE_INCDEC:
6220       if (operands[2] == const1_rtx)
6221         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6222       else if (operands[2] == constm1_rtx)
6223         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6224       abort();
6225
6226     default:
6227       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6228          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6229       if (GET_CODE (operands[2]) == CONST_INT
6230           && (INTVAL (operands[2]) == 128
6231               || (INTVAL (operands[2]) < 0
6232                   && INTVAL (operands[2]) != -128)))
6233         {
6234           operands[2] = GEN_INT (-INTVAL (operands[2]));
6235           if (widen)
6236             return "sub{l}\t{%2, %k0|%k0, %2}";
6237           else
6238             return "sub{b}\t{%2, %0|%0, %2}";
6239         }
6240       if (widen)
6241         return "add{l}\t{%k2, %k0|%k0, %k2}";
6242       else
6243         return "add{b}\t{%2, %0|%0, %2}";
6244     }
6245 }
6246   [(set (attr "type")
6247      (if_then_else (eq_attr "alternative" "3")
6248         (const_string "lea")
6249         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250            (const_string "incdec")
6251            (const_string "alu"))))
6252    (set_attr "mode" "QI,QI,SI,SI")])
6253
6254 (define_insn "*addqi_1"
6255   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6256         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6257                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6258    (clobber (reg:CC FLAGS_REG))]
6259   "TARGET_PARTIAL_REG_STALL
6260    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6261 {
6262   int widen = (which_alternative == 2);
6263   switch (get_attr_type (insn))
6264     {
6265     case TYPE_INCDEC:
6266       if (operands[2] == const1_rtx)
6267         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6268       else if (operands[2] == constm1_rtx)
6269         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6270       abort();
6271
6272     default:
6273       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6274          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6275       if (GET_CODE (operands[2]) == CONST_INT
6276           && (INTVAL (operands[2]) == 128
6277               || (INTVAL (operands[2]) < 0
6278                   && INTVAL (operands[2]) != -128)))
6279         {
6280           operands[2] = GEN_INT (-INTVAL (operands[2]));
6281           if (widen)
6282             return "sub{l}\t{%2, %k0|%k0, %2}";
6283           else
6284             return "sub{b}\t{%2, %0|%0, %2}";
6285         }
6286       if (widen)
6287         return "add{l}\t{%k2, %k0|%k0, %k2}";
6288       else
6289         return "add{b}\t{%2, %0|%0, %2}";
6290     }
6291 }
6292   [(set (attr "type")
6293      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294         (const_string "incdec")
6295         (const_string "alu")))
6296    (set_attr "mode" "QI,QI,SI")])
6297
6298 (define_insn "*addqi_1_slp"
6299   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6300         (plus:QI (match_dup 0)
6301                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6302    (clobber (reg:CC FLAGS_REG))]
6303   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6304    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6305 {
6306   switch (get_attr_type (insn))
6307     {
6308     case TYPE_INCDEC:
6309       if (operands[1] == const1_rtx)
6310         return "inc{b}\t%0";
6311       else if (operands[1] == constm1_rtx)
6312         return "dec{b}\t%0";
6313       abort();
6314
6315     default:
6316       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6317       if (GET_CODE (operands[1]) == CONST_INT
6318           && INTVAL (operands[1]) < 0)
6319         {
6320           operands[1] = GEN_INT (-INTVAL (operands[1]));
6321           return "sub{b}\t{%1, %0|%0, %1}";
6322         }
6323       return "add{b}\t{%1, %0|%0, %1}";
6324     }
6325 }
6326   [(set (attr "type")
6327      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6328         (const_string "incdec")
6329         (const_string "alu1")))
6330    (set_attr "mode" "QI")])
6331
6332 (define_insn "*addqi_2"
6333   [(set (reg FLAGS_REG)
6334         (compare
6335           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6336                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6337           (const_int 0)))
6338    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6339         (plus:QI (match_dup 1) (match_dup 2)))]
6340   "ix86_match_ccmode (insn, CCGOCmode)
6341    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6342 {
6343   switch (get_attr_type (insn))
6344     {
6345     case TYPE_INCDEC:
6346       if (operands[2] == const1_rtx)
6347         return "inc{b}\t%0";
6348       else if (operands[2] == constm1_rtx
6349                || (GET_CODE (operands[2]) == CONST_INT
6350                    && INTVAL (operands[2]) == 255))
6351         return "dec{b}\t%0";
6352       abort();
6353
6354     default:
6355       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6356       if (GET_CODE (operands[2]) == CONST_INT
6357           && INTVAL (operands[2]) < 0)
6358         {
6359           operands[2] = GEN_INT (-INTVAL (operands[2]));
6360           return "sub{b}\t{%2, %0|%0, %2}";
6361         }
6362       return "add{b}\t{%2, %0|%0, %2}";
6363     }
6364 }
6365   [(set (attr "type")
6366      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6367         (const_string "incdec")
6368         (const_string "alu")))
6369    (set_attr "mode" "QI")])
6370
6371 (define_insn "*addqi_3"
6372   [(set (reg FLAGS_REG)
6373         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6374                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6375    (clobber (match_scratch:QI 0 "=q"))]
6376   "ix86_match_ccmode (insn, CCZmode)
6377    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6378 {
6379   switch (get_attr_type (insn))
6380     {
6381     case TYPE_INCDEC:
6382       if (operands[2] == const1_rtx)
6383         return "inc{b}\t%0";
6384       else if (operands[2] == constm1_rtx
6385                || (GET_CODE (operands[2]) == CONST_INT
6386                    && INTVAL (operands[2]) == 255))
6387         return "dec{b}\t%0";
6388       abort();
6389
6390     default:
6391       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6392       if (GET_CODE (operands[2]) == CONST_INT
6393           && INTVAL (operands[2]) < 0)
6394         {
6395           operands[2] = GEN_INT (-INTVAL (operands[2]));
6396           return "sub{b}\t{%2, %0|%0, %2}";
6397         }
6398       return "add{b}\t{%2, %0|%0, %2}";
6399     }
6400 }
6401   [(set (attr "type")
6402      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6403         (const_string "incdec")
6404         (const_string "alu")))
6405    (set_attr "mode" "QI")])
6406
6407 ; See comments above addsi_3_imm for details.
6408 (define_insn "*addqi_4"
6409   [(set (reg FLAGS_REG)
6410         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6411                  (match_operand:QI 2 "const_int_operand" "n")))
6412    (clobber (match_scratch:QI 0 "=qm"))]
6413   "ix86_match_ccmode (insn, CCGCmode)
6414    && (INTVAL (operands[2]) & 0xff) != 0x80"
6415 {
6416   switch (get_attr_type (insn))
6417     {
6418     case TYPE_INCDEC:
6419       if (operands[2] == constm1_rtx
6420           || (GET_CODE (operands[2]) == CONST_INT
6421               && INTVAL (operands[2]) == 255))
6422         return "inc{b}\t%0";
6423       else if (operands[2] == const1_rtx)
6424         return "dec{b}\t%0";
6425       else
6426         abort();
6427
6428     default:
6429       if (! rtx_equal_p (operands[0], operands[1]))
6430         abort ();
6431       if (INTVAL (operands[2]) < 0)
6432         {
6433           operands[2] = GEN_INT (-INTVAL (operands[2]));
6434           return "add{b}\t{%2, %0|%0, %2}";
6435         }
6436       return "sub{b}\t{%2, %0|%0, %2}";
6437     }
6438 }
6439   [(set (attr "type")
6440      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6441         (const_string "incdec")
6442         (const_string "alu")))
6443    (set_attr "mode" "QI")])
6444
6445
6446 (define_insn "*addqi_5"
6447   [(set (reg FLAGS_REG)
6448         (compare
6449           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6450                    (match_operand:QI 2 "general_operand" "qmni"))
6451           (const_int 0)))
6452    (clobber (match_scratch:QI 0 "=q"))]
6453   "ix86_match_ccmode (insn, CCGOCmode)
6454    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6455 {
6456   switch (get_attr_type (insn))
6457     {
6458     case TYPE_INCDEC:
6459       if (operands[2] == const1_rtx)
6460         return "inc{b}\t%0";
6461       else if (operands[2] == constm1_rtx
6462                || (GET_CODE (operands[2]) == CONST_INT
6463                    && INTVAL (operands[2]) == 255))
6464         return "dec{b}\t%0";
6465       abort();
6466
6467     default:
6468       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6469       if (GET_CODE (operands[2]) == CONST_INT
6470           && INTVAL (operands[2]) < 0)
6471         {
6472           operands[2] = GEN_INT (-INTVAL (operands[2]));
6473           return "sub{b}\t{%2, %0|%0, %2}";
6474         }
6475       return "add{b}\t{%2, %0|%0, %2}";
6476     }
6477 }
6478   [(set (attr "type")
6479      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6480         (const_string "incdec")
6481         (const_string "alu")))
6482    (set_attr "mode" "QI")])
6483
6484
6485 (define_insn "addqi_ext_1"
6486   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6487                          (const_int 8)
6488                          (const_int 8))
6489         (plus:SI
6490           (zero_extract:SI
6491             (match_operand 1 "ext_register_operand" "0")
6492             (const_int 8)
6493             (const_int 8))
6494           (match_operand:QI 2 "general_operand" "Qmn")))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "!TARGET_64BIT"
6497 {
6498   switch (get_attr_type (insn))
6499     {
6500     case TYPE_INCDEC:
6501       if (operands[2] == const1_rtx)
6502         return "inc{b}\t%h0";
6503       else if (operands[2] == constm1_rtx
6504                || (GET_CODE (operands[2]) == CONST_INT
6505                    && INTVAL (operands[2]) == 255))
6506         return "dec{b}\t%h0";
6507       abort();
6508
6509     default:
6510       return "add{b}\t{%2, %h0|%h0, %2}";
6511     }
6512 }
6513   [(set (attr "type")
6514      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6515         (const_string "incdec")
6516         (const_string "alu")))
6517    (set_attr "mode" "QI")])
6518
6519 (define_insn "*addqi_ext_1_rex64"
6520   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6521                          (const_int 8)
6522                          (const_int 8))
6523         (plus:SI
6524           (zero_extract:SI
6525             (match_operand 1 "ext_register_operand" "0")
6526             (const_int 8)
6527             (const_int 8))
6528           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "TARGET_64BIT"
6531 {
6532   switch (get_attr_type (insn))
6533     {
6534     case TYPE_INCDEC:
6535       if (operands[2] == const1_rtx)
6536         return "inc{b}\t%h0";
6537       else if (operands[2] == constm1_rtx
6538                || (GET_CODE (operands[2]) == CONST_INT
6539                    && INTVAL (operands[2]) == 255))
6540         return "dec{b}\t%h0";
6541       abort();
6542
6543     default:
6544       return "add{b}\t{%2, %h0|%h0, %2}";
6545     }
6546 }
6547   [(set (attr "type")
6548      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6549         (const_string "incdec")
6550         (const_string "alu")))
6551    (set_attr "mode" "QI")])
6552
6553 (define_insn "*addqi_ext_2"
6554   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6555                          (const_int 8)
6556                          (const_int 8))
6557         (plus:SI
6558           (zero_extract:SI
6559             (match_operand 1 "ext_register_operand" "%0")
6560             (const_int 8)
6561             (const_int 8))
6562           (zero_extract:SI
6563             (match_operand 2 "ext_register_operand" "Q")
6564             (const_int 8)
6565             (const_int 8))))
6566    (clobber (reg:CC FLAGS_REG))]
6567   ""
6568   "add{b}\t{%h2, %h0|%h0, %h2}"
6569   [(set_attr "type" "alu")
6570    (set_attr "mode" "QI")])
6571
6572 ;; The patterns that match these are at the end of this file.
6573
6574 (define_expand "addxf3"
6575   [(set (match_operand:XF 0 "register_operand" "")
6576         (plus:XF (match_operand:XF 1 "register_operand" "")
6577                  (match_operand:XF 2 "register_operand" "")))]
6578   "TARGET_80387"
6579   "")
6580
6581 (define_expand "adddf3"
6582   [(set (match_operand:DF 0 "register_operand" "")
6583         (plus:DF (match_operand:DF 1 "register_operand" "")
6584                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6585   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6586   "")
6587
6588 (define_expand "addsf3"
6589   [(set (match_operand:SF 0 "register_operand" "")
6590         (plus:SF (match_operand:SF 1 "register_operand" "")
6591                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6592   "TARGET_80387 || TARGET_SSE_MATH"
6593   "")
6594 \f
6595 ;; Subtract instructions
6596
6597 ;; %%% splits for subsidi3
6598
6599 (define_expand "subdi3"
6600   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6601                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6602                              (match_operand:DI 2 "x86_64_general_operand" "")))
6603               (clobber (reg:CC FLAGS_REG))])]
6604   ""
6605   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6606
6607 (define_insn "*subdi3_1"
6608   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6609         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6610                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6613   "#")
6614
6615 (define_split
6616   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6617         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6618                   (match_operand:DI 2 "general_operand" "")))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "!TARGET_64BIT && reload_completed"
6621   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6622               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6623    (parallel [(set (match_dup 3)
6624                    (minus:SI (match_dup 4)
6625                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6626                                       (match_dup 5))))
6627               (clobber (reg:CC FLAGS_REG))])]
6628   "split_di (operands+0, 1, operands+0, operands+3);
6629    split_di (operands+1, 1, operands+1, operands+4);
6630    split_di (operands+2, 1, operands+2, operands+5);")
6631
6632 (define_insn "subdi3_carry_rex64"
6633   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6634           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6635             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6636                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6637    (clobber (reg:CC FLAGS_REG))]
6638   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6639   "sbb{q}\t{%2, %0|%0, %2}"
6640   [(set_attr "type" "alu")
6641    (set_attr "pent_pair" "pu")
6642    (set_attr "mode" "DI")])
6643
6644 (define_insn "*subdi_1_rex64"
6645   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6646         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6647                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6650   "sub{q}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "DI")])
6653
6654 (define_insn "*subdi_2_rex64"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6658                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6659           (const_int 0)))
6660    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6661         (minus:DI (match_dup 1) (match_dup 2)))]
6662   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6663    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6664   "sub{q}\t{%2, %0|%0, %2}"
6665   [(set_attr "type" "alu")
6666    (set_attr "mode" "DI")])
6667
6668 (define_insn "*subdi_3_rex63"
6669   [(set (reg FLAGS_REG)
6670         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6671                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6672    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6673         (minus:DI (match_dup 1) (match_dup 2)))]
6674   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6675    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6676   "sub{q}\t{%2, %0|%0, %2}"
6677   [(set_attr "type" "alu")
6678    (set_attr "mode" "DI")])
6679
6680 (define_insn "subqi3_carry"
6681   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6682           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6683             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6684                (match_operand:QI 2 "general_operand" "qi,qm"))))
6685    (clobber (reg:CC FLAGS_REG))]
6686   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6687   "sbb{b}\t{%2, %0|%0, %2}"
6688   [(set_attr "type" "alu")
6689    (set_attr "pent_pair" "pu")
6690    (set_attr "mode" "QI")])
6691
6692 (define_insn "subhi3_carry"
6693   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6694           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6695             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6696                (match_operand:HI 2 "general_operand" "ri,rm"))))
6697    (clobber (reg:CC FLAGS_REG))]
6698   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6699   "sbb{w}\t{%2, %0|%0, %2}"
6700   [(set_attr "type" "alu")
6701    (set_attr "pent_pair" "pu")
6702    (set_attr "mode" "HI")])
6703
6704 (define_insn "subsi3_carry"
6705   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6706           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6707             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6708                (match_operand:SI 2 "general_operand" "ri,rm"))))
6709    (clobber (reg:CC FLAGS_REG))]
6710   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6711   "sbb{l}\t{%2, %0|%0, %2}"
6712   [(set_attr "type" "alu")
6713    (set_attr "pent_pair" "pu")
6714    (set_attr "mode" "SI")])
6715
6716 (define_insn "subsi3_carry_zext"
6717   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6718           (zero_extend:DI
6719             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6720               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6721                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6722    (clobber (reg:CC FLAGS_REG))]
6723   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6724   "sbb{l}\t{%2, %k0|%k0, %2}"
6725   [(set_attr "type" "alu")
6726    (set_attr "pent_pair" "pu")
6727    (set_attr "mode" "SI")])
6728
6729 (define_expand "subsi3"
6730   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6731                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6732                              (match_operand:SI 2 "general_operand" "")))
6733               (clobber (reg:CC FLAGS_REG))])]
6734   ""
6735   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6736
6737 (define_insn "*subsi_1"
6738   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6739         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6740                   (match_operand:SI 2 "general_operand" "ri,rm")))
6741    (clobber (reg:CC FLAGS_REG))]
6742   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6743   "sub{l}\t{%2, %0|%0, %2}"
6744   [(set_attr "type" "alu")
6745    (set_attr "mode" "SI")])
6746
6747 (define_insn "*subsi_1_zext"
6748   [(set (match_operand:DI 0 "register_operand" "=r")
6749         (zero_extend:DI
6750           (minus:SI (match_operand:SI 1 "register_operand" "0")
6751                     (match_operand:SI 2 "general_operand" "rim"))))
6752    (clobber (reg:CC FLAGS_REG))]
6753   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6754   "sub{l}\t{%2, %k0|%k0, %2}"
6755   [(set_attr "type" "alu")
6756    (set_attr "mode" "SI")])
6757
6758 (define_insn "*subsi_2"
6759   [(set (reg FLAGS_REG)
6760         (compare
6761           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6762                     (match_operand:SI 2 "general_operand" "ri,rm"))
6763           (const_int 0)))
6764    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6765         (minus:SI (match_dup 1) (match_dup 2)))]
6766   "ix86_match_ccmode (insn, CCGOCmode)
6767    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6768   "sub{l}\t{%2, %0|%0, %2}"
6769   [(set_attr "type" "alu")
6770    (set_attr "mode" "SI")])
6771
6772 (define_insn "*subsi_2_zext"
6773   [(set (reg FLAGS_REG)
6774         (compare
6775           (minus:SI (match_operand:SI 1 "register_operand" "0")
6776                     (match_operand:SI 2 "general_operand" "rim"))
6777           (const_int 0)))
6778    (set (match_operand:DI 0 "register_operand" "=r")
6779         (zero_extend:DI
6780           (minus:SI (match_dup 1)
6781                     (match_dup 2))))]
6782   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6783    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784   "sub{l}\t{%2, %k0|%k0, %2}"
6785   [(set_attr "type" "alu")
6786    (set_attr "mode" "SI")])
6787
6788 (define_insn "*subsi_3"
6789   [(set (reg FLAGS_REG)
6790         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6791                  (match_operand:SI 2 "general_operand" "ri,rm")))
6792    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6793         (minus:SI (match_dup 1) (match_dup 2)))]
6794   "ix86_match_ccmode (insn, CCmode)
6795    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6796   "sub{l}\t{%2, %0|%0, %2}"
6797   [(set_attr "type" "alu")
6798    (set_attr "mode" "SI")])
6799
6800 (define_insn "*subsi_3_zext"
6801   [(set (reg FLAGS_REG)
6802         (compare (match_operand:SI 1 "register_operand" "0")
6803                  (match_operand:SI 2 "general_operand" "rim")))
6804    (set (match_operand:DI 0 "register_operand" "=r")
6805         (zero_extend:DI
6806           (minus:SI (match_dup 1)
6807                     (match_dup 2))))]
6808   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6809    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6810   "sub{q}\t{%2, %0|%0, %2}"
6811   [(set_attr "type" "alu")
6812    (set_attr "mode" "DI")])
6813
6814 (define_expand "subhi3"
6815   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6816                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6817                              (match_operand:HI 2 "general_operand" "")))
6818               (clobber (reg:CC FLAGS_REG))])]
6819   "TARGET_HIMODE_MATH"
6820   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6821
6822 (define_insn "*subhi_1"
6823   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6824         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6825                   (match_operand:HI 2 "general_operand" "ri,rm")))
6826    (clobber (reg:CC FLAGS_REG))]
6827   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6828   "sub{w}\t{%2, %0|%0, %2}"
6829   [(set_attr "type" "alu")
6830    (set_attr "mode" "HI")])
6831
6832 (define_insn "*subhi_2"
6833   [(set (reg FLAGS_REG)
6834         (compare
6835           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6836                     (match_operand:HI 2 "general_operand" "ri,rm"))
6837           (const_int 0)))
6838    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6839         (minus:HI (match_dup 1) (match_dup 2)))]
6840   "ix86_match_ccmode (insn, CCGOCmode)
6841    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6842   "sub{w}\t{%2, %0|%0, %2}"
6843   [(set_attr "type" "alu")
6844    (set_attr "mode" "HI")])
6845
6846 (define_insn "*subhi_3"
6847   [(set (reg FLAGS_REG)
6848         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6849                  (match_operand:HI 2 "general_operand" "ri,rm")))
6850    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6851         (minus:HI (match_dup 1) (match_dup 2)))]
6852   "ix86_match_ccmode (insn, CCmode)
6853    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6854   "sub{w}\t{%2, %0|%0, %2}"
6855   [(set_attr "type" "alu")
6856    (set_attr "mode" "HI")])
6857
6858 (define_expand "subqi3"
6859   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6860                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6861                              (match_operand:QI 2 "general_operand" "")))
6862               (clobber (reg:CC FLAGS_REG))])]
6863   "TARGET_QIMODE_MATH"
6864   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6865
6866 (define_insn "*subqi_1"
6867   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6868         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6869                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6870    (clobber (reg:CC FLAGS_REG))]
6871   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6872   "sub{b}\t{%2, %0|%0, %2}"
6873   [(set_attr "type" "alu")
6874    (set_attr "mode" "QI")])
6875
6876 (define_insn "*subqi_1_slp"
6877   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6878         (minus:QI (match_dup 0)
6879                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6880    (clobber (reg:CC FLAGS_REG))]
6881   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6882    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6883   "sub{b}\t{%1, %0|%0, %1}"
6884   [(set_attr "type" "alu1")
6885    (set_attr "mode" "QI")])
6886
6887 (define_insn "*subqi_2"
6888   [(set (reg FLAGS_REG)
6889         (compare
6890           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6891                     (match_operand:QI 2 "general_operand" "qi,qm"))
6892           (const_int 0)))
6893    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6894         (minus:HI (match_dup 1) (match_dup 2)))]
6895   "ix86_match_ccmode (insn, CCGOCmode)
6896    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6897   "sub{b}\t{%2, %0|%0, %2}"
6898   [(set_attr "type" "alu")
6899    (set_attr "mode" "QI")])
6900
6901 (define_insn "*subqi_3"
6902   [(set (reg FLAGS_REG)
6903         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6904                  (match_operand:QI 2 "general_operand" "qi,qm")))
6905    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6906         (minus:HI (match_dup 1) (match_dup 2)))]
6907   "ix86_match_ccmode (insn, CCmode)
6908    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6909   "sub{b}\t{%2, %0|%0, %2}"
6910   [(set_attr "type" "alu")
6911    (set_attr "mode" "QI")])
6912
6913 ;; The patterns that match these are at the end of this file.
6914
6915 (define_expand "subxf3"
6916   [(set (match_operand:XF 0 "register_operand" "")
6917         (minus:XF (match_operand:XF 1 "register_operand" "")
6918                   (match_operand:XF 2 "register_operand" "")))]
6919   "TARGET_80387"
6920   "")
6921
6922 (define_expand "subdf3"
6923   [(set (match_operand:DF 0 "register_operand" "")
6924         (minus:DF (match_operand:DF 1 "register_operand" "")
6925                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6926   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6927   "")
6928
6929 (define_expand "subsf3"
6930   [(set (match_operand:SF 0 "register_operand" "")
6931         (minus:SF (match_operand:SF 1 "register_operand" "")
6932                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6933   "TARGET_80387 || TARGET_SSE_MATH"
6934   "")
6935 \f
6936 ;; Multiply instructions
6937
6938 (define_expand "muldi3"
6939   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6940                    (mult:DI (match_operand:DI 1 "register_operand" "")
6941                             (match_operand:DI 2 "x86_64_general_operand" "")))
6942               (clobber (reg:CC FLAGS_REG))])]
6943   "TARGET_64BIT"
6944   "")
6945
6946 (define_insn "*muldi3_1_rex64"
6947   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6948         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6949                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6950    (clobber (reg:CC FLAGS_REG))]
6951   "TARGET_64BIT
6952    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6953   "@
6954    imul{q}\t{%2, %1, %0|%0, %1, %2}
6955    imul{q}\t{%2, %1, %0|%0, %1, %2}
6956    imul{q}\t{%2, %0|%0, %2}"
6957   [(set_attr "type" "imul")
6958    (set_attr "prefix_0f" "0,0,1")
6959    (set (attr "athlon_decode")
6960         (cond [(eq_attr "cpu" "athlon")
6961                   (const_string "vector")
6962                (eq_attr "alternative" "1")
6963                   (const_string "vector")
6964                (and (eq_attr "alternative" "2")
6965                     (match_operand 1 "memory_operand" ""))
6966                   (const_string "vector")]
6967               (const_string "direct")))
6968    (set_attr "mode" "DI")])
6969
6970 (define_expand "mulsi3"
6971   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6972                    (mult:SI (match_operand:SI 1 "register_operand" "")
6973                             (match_operand:SI 2 "general_operand" "")))
6974               (clobber (reg:CC FLAGS_REG))])]
6975   ""
6976   "")
6977
6978 (define_insn "*mulsi3_1"
6979   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6980         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6981                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6982    (clobber (reg:CC FLAGS_REG))]
6983   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6984   "@
6985    imul{l}\t{%2, %1, %0|%0, %1, %2}
6986    imul{l}\t{%2, %1, %0|%0, %1, %2}
6987    imul{l}\t{%2, %0|%0, %2}"
6988   [(set_attr "type" "imul")
6989    (set_attr "prefix_0f" "0,0,1")
6990    (set (attr "athlon_decode")
6991         (cond [(eq_attr "cpu" "athlon")
6992                   (const_string "vector")
6993                (eq_attr "alternative" "1")
6994                   (const_string "vector")
6995                (and (eq_attr "alternative" "2")
6996                     (match_operand 1 "memory_operand" ""))
6997                   (const_string "vector")]
6998               (const_string "direct")))
6999    (set_attr "mode" "SI")])
7000
7001 (define_insn "*mulsi3_1_zext"
7002   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7003         (zero_extend:DI
7004           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7005                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7006    (clobber (reg:CC FLAGS_REG))]
7007   "TARGET_64BIT
7008    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7009   "@
7010    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7011    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7012    imul{l}\t{%2, %k0|%k0, %2}"
7013   [(set_attr "type" "imul")
7014    (set_attr "prefix_0f" "0,0,1")
7015    (set (attr "athlon_decode")
7016         (cond [(eq_attr "cpu" "athlon")
7017                   (const_string "vector")
7018                (eq_attr "alternative" "1")
7019                   (const_string "vector")
7020                (and (eq_attr "alternative" "2")
7021                     (match_operand 1 "memory_operand" ""))
7022                   (const_string "vector")]
7023               (const_string "direct")))
7024    (set_attr "mode" "SI")])
7025
7026 (define_expand "mulhi3"
7027   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7028                    (mult:HI (match_operand:HI 1 "register_operand" "")
7029                             (match_operand:HI 2 "general_operand" "")))
7030               (clobber (reg:CC FLAGS_REG))])]
7031   "TARGET_HIMODE_MATH"
7032   "")
7033
7034 (define_insn "*mulhi3_1"
7035   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7036         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7037                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7038    (clobber (reg:CC FLAGS_REG))]
7039   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7040   "@
7041    imul{w}\t{%2, %1, %0|%0, %1, %2}
7042    imul{w}\t{%2, %1, %0|%0, %1, %2}
7043    imul{w}\t{%2, %0|%0, %2}"
7044   [(set_attr "type" "imul")
7045    (set_attr "prefix_0f" "0,0,1")
7046    (set (attr "athlon_decode")
7047         (cond [(eq_attr "cpu" "athlon")
7048                   (const_string "vector")
7049                (eq_attr "alternative" "1,2")
7050                   (const_string "vector")]
7051               (const_string "direct")))
7052    (set_attr "mode" "HI")])
7053
7054 (define_expand "mulqi3"
7055   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7056                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7057                             (match_operand:QI 2 "register_operand" "")))
7058               (clobber (reg:CC FLAGS_REG))])]
7059   "TARGET_QIMODE_MATH"
7060   "")
7061
7062 (define_insn "*mulqi3_1"
7063   [(set (match_operand:QI 0 "register_operand" "=a")
7064         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7065                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7066    (clobber (reg:CC FLAGS_REG))]
7067   "TARGET_QIMODE_MATH
7068    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7069   "mul{b}\t%2"
7070   [(set_attr "type" "imul")
7071    (set_attr "length_immediate" "0")
7072    (set (attr "athlon_decode")
7073      (if_then_else (eq_attr "cpu" "athlon")
7074         (const_string "vector")
7075         (const_string "direct")))
7076    (set_attr "mode" "QI")])
7077
7078 (define_expand "umulqihi3"
7079   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7080                    (mult:HI (zero_extend:HI
7081                               (match_operand:QI 1 "nonimmediate_operand" ""))
7082                             (zero_extend:HI
7083                               (match_operand:QI 2 "register_operand" ""))))
7084               (clobber (reg:CC FLAGS_REG))])]
7085   "TARGET_QIMODE_MATH"
7086   "")
7087
7088 (define_insn "*umulqihi3_1"
7089   [(set (match_operand:HI 0 "register_operand" "=a")
7090         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7091                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7092    (clobber (reg:CC FLAGS_REG))]
7093   "TARGET_QIMODE_MATH
7094    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7095   "mul{b}\t%2"
7096   [(set_attr "type" "imul")
7097    (set_attr "length_immediate" "0")
7098    (set (attr "athlon_decode")
7099      (if_then_else (eq_attr "cpu" "athlon")
7100         (const_string "vector")
7101         (const_string "direct")))
7102    (set_attr "mode" "QI")])
7103
7104 (define_expand "mulqihi3"
7105   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7106                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7107                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7108               (clobber (reg:CC FLAGS_REG))])]
7109   "TARGET_QIMODE_MATH"
7110   "")
7111
7112 (define_insn "*mulqihi3_insn"
7113   [(set (match_operand:HI 0 "register_operand" "=a")
7114         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7115                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7116    (clobber (reg:CC FLAGS_REG))]
7117   "TARGET_QIMODE_MATH
7118    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7119   "imul{b}\t%2"
7120   [(set_attr "type" "imul")
7121    (set_attr "length_immediate" "0")
7122    (set (attr "athlon_decode")
7123      (if_then_else (eq_attr "cpu" "athlon")
7124         (const_string "vector")
7125         (const_string "direct")))
7126    (set_attr "mode" "QI")])
7127
7128 (define_expand "umulditi3"
7129   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7130                    (mult:TI (zero_extend:TI
7131                               (match_operand:DI 1 "nonimmediate_operand" ""))
7132                             (zero_extend:TI
7133                               (match_operand:DI 2 "register_operand" ""))))
7134               (clobber (reg:CC FLAGS_REG))])]
7135   "TARGET_64BIT"
7136   "")
7137
7138 (define_insn "*umulditi3_insn"
7139   [(set (match_operand:TI 0 "register_operand" "=A")
7140         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7141                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7142    (clobber (reg:CC FLAGS_REG))]
7143   "TARGET_64BIT
7144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145   "mul{q}\t%2"
7146   [(set_attr "type" "imul")
7147    (set_attr "length_immediate" "0")
7148    (set (attr "athlon_decode")
7149      (if_then_else (eq_attr "cpu" "athlon")
7150         (const_string "vector")
7151         (const_string "double")))
7152    (set_attr "mode" "DI")])
7153
7154 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7155 (define_expand "umulsidi3"
7156   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7157                    (mult:DI (zero_extend:DI
7158                               (match_operand:SI 1 "nonimmediate_operand" ""))
7159                             (zero_extend:DI
7160                               (match_operand:SI 2 "register_operand" ""))))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   "!TARGET_64BIT"
7163   "")
7164
7165 (define_insn "*umulsidi3_insn"
7166   [(set (match_operand:DI 0 "register_operand" "=A")
7167         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7168                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7169    (clobber (reg:CC FLAGS_REG))]
7170   "!TARGET_64BIT
7171    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172   "mul{l}\t%2"
7173   [(set_attr "type" "imul")
7174    (set_attr "length_immediate" "0")
7175    (set (attr "athlon_decode")
7176      (if_then_else (eq_attr "cpu" "athlon")
7177         (const_string "vector")
7178         (const_string "double")))
7179    (set_attr "mode" "SI")])
7180
7181 (define_expand "mulditi3"
7182   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7183                    (mult:TI (sign_extend:TI
7184                               (match_operand:DI 1 "nonimmediate_operand" ""))
7185                             (sign_extend:TI
7186                               (match_operand:DI 2 "register_operand" ""))))
7187               (clobber (reg:CC FLAGS_REG))])]
7188   "TARGET_64BIT"
7189   "")
7190
7191 (define_insn "*mulditi3_insn"
7192   [(set (match_operand:TI 0 "register_operand" "=A")
7193         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7194                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7195    (clobber (reg:CC FLAGS_REG))]
7196   "TARGET_64BIT
7197    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7198   "imul{q}\t%2"
7199   [(set_attr "type" "imul")
7200    (set_attr "length_immediate" "0")
7201    (set (attr "athlon_decode")
7202      (if_then_else (eq_attr "cpu" "athlon")
7203         (const_string "vector")
7204         (const_string "double")))
7205    (set_attr "mode" "DI")])
7206
7207 (define_expand "mulsidi3"
7208   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7209                    (mult:DI (sign_extend:DI
7210                               (match_operand:SI 1 "nonimmediate_operand" ""))
7211                             (sign_extend:DI
7212                               (match_operand:SI 2 "register_operand" ""))))
7213               (clobber (reg:CC FLAGS_REG))])]
7214   "!TARGET_64BIT"
7215   "")
7216
7217 (define_insn "*mulsidi3_insn"
7218   [(set (match_operand:DI 0 "register_operand" "=A")
7219         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7220                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7221    (clobber (reg:CC FLAGS_REG))]
7222   "!TARGET_64BIT
7223    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7224   "imul{l}\t%2"
7225   [(set_attr "type" "imul")
7226    (set_attr "length_immediate" "0")
7227    (set (attr "athlon_decode")
7228      (if_then_else (eq_attr "cpu" "athlon")
7229         (const_string "vector")
7230         (const_string "double")))
7231    (set_attr "mode" "SI")])
7232
7233 (define_expand "umuldi3_highpart"
7234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7235                    (truncate:DI
7236                      (lshiftrt:TI
7237                        (mult:TI (zero_extend:TI
7238                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7239                                 (zero_extend:TI
7240                                   (match_operand:DI 2 "register_operand" "")))
7241                        (const_int 64))))
7242               (clobber (match_scratch:DI 3 ""))
7243               (clobber (reg:CC FLAGS_REG))])]
7244   "TARGET_64BIT"
7245   "")
7246
7247 (define_insn "*umuldi3_highpart_rex64"
7248   [(set (match_operand:DI 0 "register_operand" "=d")
7249         (truncate:DI
7250           (lshiftrt:TI
7251             (mult:TI (zero_extend:TI
7252                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7253                      (zero_extend:TI
7254                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7255             (const_int 64))))
7256    (clobber (match_scratch:DI 3 "=1"))
7257    (clobber (reg:CC FLAGS_REG))]
7258   "TARGET_64BIT
7259    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7260   "mul{q}\t%2"
7261   [(set_attr "type" "imul")
7262    (set_attr "length_immediate" "0")
7263    (set (attr "athlon_decode")
7264      (if_then_else (eq_attr "cpu" "athlon")
7265         (const_string "vector")
7266         (const_string "double")))
7267    (set_attr "mode" "DI")])
7268
7269 (define_expand "umulsi3_highpart"
7270   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7271                    (truncate:SI
7272                      (lshiftrt:DI
7273                        (mult:DI (zero_extend:DI
7274                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7275                                 (zero_extend:DI
7276                                   (match_operand:SI 2 "register_operand" "")))
7277                        (const_int 32))))
7278               (clobber (match_scratch:SI 3 ""))
7279               (clobber (reg:CC FLAGS_REG))])]
7280   ""
7281   "")
7282
7283 (define_insn "*umulsi3_highpart_insn"
7284   [(set (match_operand:SI 0 "register_operand" "=d")
7285         (truncate:SI
7286           (lshiftrt:DI
7287             (mult:DI (zero_extend:DI
7288                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7289                      (zero_extend:DI
7290                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7291             (const_int 32))))
7292    (clobber (match_scratch:SI 3 "=1"))
7293    (clobber (reg:CC FLAGS_REG))]
7294   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7295   "mul{l}\t%2"
7296   [(set_attr "type" "imul")
7297    (set_attr "length_immediate" "0")
7298    (set (attr "athlon_decode")
7299      (if_then_else (eq_attr "cpu" "athlon")
7300         (const_string "vector")
7301         (const_string "double")))
7302    (set_attr "mode" "SI")])
7303
7304 (define_insn "*umulsi3_highpart_zext"
7305   [(set (match_operand:DI 0 "register_operand" "=d")
7306         (zero_extend:DI (truncate:SI
7307           (lshiftrt:DI
7308             (mult:DI (zero_extend:DI
7309                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7310                      (zero_extend:DI
7311                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7312             (const_int 32)))))
7313    (clobber (match_scratch:SI 3 "=1"))
7314    (clobber (reg:CC FLAGS_REG))]
7315   "TARGET_64BIT
7316    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7317   "mul{l}\t%2"
7318   [(set_attr "type" "imul")
7319    (set_attr "length_immediate" "0")
7320    (set (attr "athlon_decode")
7321      (if_then_else (eq_attr "cpu" "athlon")
7322         (const_string "vector")
7323         (const_string "double")))
7324    (set_attr "mode" "SI")])
7325
7326 (define_expand "smuldi3_highpart"
7327   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7328                    (truncate:DI
7329                      (lshiftrt:TI
7330                        (mult:TI (sign_extend:TI
7331                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7332                                 (sign_extend:TI
7333                                   (match_operand:DI 2 "register_operand" "")))
7334                        (const_int 64))))
7335               (clobber (match_scratch:DI 3 ""))
7336               (clobber (reg:CC FLAGS_REG))])]
7337   "TARGET_64BIT"
7338   "")
7339
7340 (define_insn "*smuldi3_highpart_rex64"
7341   [(set (match_operand:DI 0 "register_operand" "=d")
7342         (truncate:DI
7343           (lshiftrt:TI
7344             (mult:TI (sign_extend:TI
7345                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7346                      (sign_extend:TI
7347                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7348             (const_int 64))))
7349    (clobber (match_scratch:DI 3 "=1"))
7350    (clobber (reg:CC FLAGS_REG))]
7351   "TARGET_64BIT
7352    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7353   "imul{q}\t%2"
7354   [(set_attr "type" "imul")
7355    (set (attr "athlon_decode")
7356      (if_then_else (eq_attr "cpu" "athlon")
7357         (const_string "vector")
7358         (const_string "double")))
7359    (set_attr "mode" "DI")])
7360
7361 (define_expand "smulsi3_highpart"
7362   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7363                    (truncate:SI
7364                      (lshiftrt:DI
7365                        (mult:DI (sign_extend:DI
7366                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7367                                 (sign_extend:DI
7368                                   (match_operand:SI 2 "register_operand" "")))
7369                        (const_int 32))))
7370               (clobber (match_scratch:SI 3 ""))
7371               (clobber (reg:CC FLAGS_REG))])]
7372   ""
7373   "")
7374
7375 (define_insn "*smulsi3_highpart_insn"
7376   [(set (match_operand:SI 0 "register_operand" "=d")
7377         (truncate:SI
7378           (lshiftrt:DI
7379             (mult:DI (sign_extend:DI
7380                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7381                      (sign_extend:DI
7382                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7383             (const_int 32))))
7384    (clobber (match_scratch:SI 3 "=1"))
7385    (clobber (reg:CC FLAGS_REG))]
7386   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7387   "imul{l}\t%2"
7388   [(set_attr "type" "imul")
7389    (set (attr "athlon_decode")
7390      (if_then_else (eq_attr "cpu" "athlon")
7391         (const_string "vector")
7392         (const_string "double")))
7393    (set_attr "mode" "SI")])
7394
7395 (define_insn "*smulsi3_highpart_zext"
7396   [(set (match_operand:DI 0 "register_operand" "=d")
7397         (zero_extend:DI (truncate:SI
7398           (lshiftrt:DI
7399             (mult:DI (sign_extend:DI
7400                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7401                      (sign_extend:DI
7402                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7403             (const_int 32)))))
7404    (clobber (match_scratch:SI 3 "=1"))
7405    (clobber (reg:CC FLAGS_REG))]
7406   "TARGET_64BIT
7407    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7408   "imul{l}\t%2"
7409   [(set_attr "type" "imul")
7410    (set (attr "athlon_decode")
7411      (if_then_else (eq_attr "cpu" "athlon")
7412         (const_string "vector")
7413         (const_string "double")))
7414    (set_attr "mode" "SI")])
7415
7416 ;; The patterns that match these are at the end of this file.
7417
7418 (define_expand "mulxf3"
7419   [(set (match_operand:XF 0 "register_operand" "")
7420         (mult:XF (match_operand:XF 1 "register_operand" "")
7421                  (match_operand:XF 2 "register_operand" "")))]
7422   "TARGET_80387"
7423   "")
7424
7425 (define_expand "muldf3"
7426   [(set (match_operand:DF 0 "register_operand" "")
7427         (mult:DF (match_operand:DF 1 "register_operand" "")
7428                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7429   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7430   "")
7431
7432 (define_expand "mulsf3"
7433   [(set (match_operand:SF 0 "register_operand" "")
7434         (mult:SF (match_operand:SF 1 "register_operand" "")
7435                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7436   "TARGET_80387 || TARGET_SSE_MATH"
7437   "")
7438 \f
7439 ;; Divide instructions
7440
7441 (define_insn "divqi3"
7442   [(set (match_operand:QI 0 "register_operand" "=a")
7443         (div:QI (match_operand:HI 1 "register_operand" "0")
7444                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7445    (clobber (reg:CC FLAGS_REG))]
7446   "TARGET_QIMODE_MATH"
7447   "idiv{b}\t%2"
7448   [(set_attr "type" "idiv")
7449    (set_attr "mode" "QI")])
7450
7451 (define_insn "udivqi3"
7452   [(set (match_operand:QI 0 "register_operand" "=a")
7453         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7454                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7455    (clobber (reg:CC FLAGS_REG))]
7456   "TARGET_QIMODE_MATH"
7457   "div{b}\t%2"
7458   [(set_attr "type" "idiv")
7459    (set_attr "mode" "QI")])
7460
7461 ;; The patterns that match these are at the end of this file.
7462
7463 (define_expand "divxf3"
7464   [(set (match_operand:XF 0 "register_operand" "")
7465         (div:XF (match_operand:XF 1 "register_operand" "")
7466                 (match_operand:XF 2 "register_operand" "")))]
7467   "TARGET_80387"
7468   "")
7469
7470 (define_expand "divdf3"
7471   [(set (match_operand:DF 0 "register_operand" "")
7472         (div:DF (match_operand:DF 1 "register_operand" "")
7473                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7474    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7475    "")
7476  
7477 (define_expand "divsf3"
7478   [(set (match_operand:SF 0 "register_operand" "")
7479         (div:SF (match_operand:SF 1 "register_operand" "")
7480                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7481   "TARGET_80387 || TARGET_SSE_MATH"
7482   "")
7483 \f
7484 ;; Remainder instructions.
7485
7486 (define_expand "divmoddi4"
7487   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488                    (div:DI (match_operand:DI 1 "register_operand" "")
7489                            (match_operand:DI 2 "nonimmediate_operand" "")))
7490               (set (match_operand:DI 3 "register_operand" "")
7491                    (mod:DI (match_dup 1) (match_dup 2)))
7492               (clobber (reg:CC FLAGS_REG))])]
7493   "TARGET_64BIT"
7494   "")
7495
7496 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7497 ;; Penalize eax case slightly because it results in worse scheduling
7498 ;; of code.
7499 (define_insn "*divmoddi4_nocltd_rex64"
7500   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7501         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7502                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7503    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7504         (mod:DI (match_dup 2) (match_dup 3)))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7507   "#"
7508   [(set_attr "type" "multi")])
7509
7510 (define_insn "*divmoddi4_cltd_rex64"
7511   [(set (match_operand:DI 0 "register_operand" "=a")
7512         (div:DI (match_operand:DI 2 "register_operand" "a")
7513                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7514    (set (match_operand:DI 1 "register_operand" "=&d")
7515         (mod:DI (match_dup 2) (match_dup 3)))
7516    (clobber (reg:CC FLAGS_REG))]
7517   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7518   "#"
7519   [(set_attr "type" "multi")])
7520
7521 (define_insn "*divmoddi_noext_rex64"
7522   [(set (match_operand:DI 0 "register_operand" "=a")
7523         (div:DI (match_operand:DI 1 "register_operand" "0")
7524                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7525    (set (match_operand:DI 3 "register_operand" "=d")
7526         (mod:DI (match_dup 1) (match_dup 2)))
7527    (use (match_operand:DI 4 "register_operand" "3"))
7528    (clobber (reg:CC FLAGS_REG))]
7529   "TARGET_64BIT"
7530   "idiv{q}\t%2"
7531   [(set_attr "type" "idiv")
7532    (set_attr "mode" "DI")])
7533
7534 (define_split
7535   [(set (match_operand:DI 0 "register_operand" "")
7536         (div:DI (match_operand:DI 1 "register_operand" "")
7537                 (match_operand:DI 2 "nonimmediate_operand" "")))
7538    (set (match_operand:DI 3 "register_operand" "")
7539         (mod:DI (match_dup 1) (match_dup 2)))
7540    (clobber (reg:CC FLAGS_REG))]
7541   "TARGET_64BIT && reload_completed"
7542   [(parallel [(set (match_dup 3)
7543                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7544               (clobber (reg:CC FLAGS_REG))])
7545    (parallel [(set (match_dup 0)
7546                    (div:DI (reg:DI 0) (match_dup 2)))
7547               (set (match_dup 3)
7548                    (mod:DI (reg:DI 0) (match_dup 2)))
7549               (use (match_dup 3))
7550               (clobber (reg:CC FLAGS_REG))])]
7551 {
7552   /* Avoid use of cltd in favor of a mov+shift.  */
7553   if (!TARGET_USE_CLTD && !optimize_size)
7554     {
7555       if (true_regnum (operands[1]))
7556         emit_move_insn (operands[0], operands[1]);
7557       else
7558         emit_move_insn (operands[3], operands[1]);
7559       operands[4] = operands[3];
7560     }
7561   else
7562     {
7563       if (true_regnum (operands[1]))
7564         abort();
7565       operands[4] = operands[1];
7566     }
7567 })
7568
7569
7570 (define_expand "divmodsi4"
7571   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7572                    (div:SI (match_operand:SI 1 "register_operand" "")
7573                            (match_operand:SI 2 "nonimmediate_operand" "")))
7574               (set (match_operand:SI 3 "register_operand" "")
7575                    (mod:SI (match_dup 1) (match_dup 2)))
7576               (clobber (reg:CC FLAGS_REG))])]
7577   ""
7578   "")
7579
7580 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7581 ;; Penalize eax case slightly because it results in worse scheduling
7582 ;; of code.
7583 (define_insn "*divmodsi4_nocltd"
7584   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7585         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7586                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7587    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7588         (mod:SI (match_dup 2) (match_dup 3)))
7589    (clobber (reg:CC FLAGS_REG))]
7590   "!optimize_size && !TARGET_USE_CLTD"
7591   "#"
7592   [(set_attr "type" "multi")])
7593
7594 (define_insn "*divmodsi4_cltd"
7595   [(set (match_operand:SI 0 "register_operand" "=a")
7596         (div:SI (match_operand:SI 2 "register_operand" "a")
7597                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7598    (set (match_operand:SI 1 "register_operand" "=&d")
7599         (mod:SI (match_dup 2) (match_dup 3)))
7600    (clobber (reg:CC FLAGS_REG))]
7601   "optimize_size || TARGET_USE_CLTD"
7602   "#"
7603   [(set_attr "type" "multi")])
7604
7605 (define_insn "*divmodsi_noext"
7606   [(set (match_operand:SI 0 "register_operand" "=a")
7607         (div:SI (match_operand:SI 1 "register_operand" "0")
7608                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7609    (set (match_operand:SI 3 "register_operand" "=d")
7610         (mod:SI (match_dup 1) (match_dup 2)))
7611    (use (match_operand:SI 4 "register_operand" "3"))
7612    (clobber (reg:CC FLAGS_REG))]
7613   ""
7614   "idiv{l}\t%2"
7615   [(set_attr "type" "idiv")
7616    (set_attr "mode" "SI")])
7617
7618 (define_split
7619   [(set (match_operand:SI 0 "register_operand" "")
7620         (div:SI (match_operand:SI 1 "register_operand" "")
7621                 (match_operand:SI 2 "nonimmediate_operand" "")))
7622    (set (match_operand:SI 3 "register_operand" "")
7623         (mod:SI (match_dup 1) (match_dup 2)))
7624    (clobber (reg:CC FLAGS_REG))]
7625   "reload_completed"
7626   [(parallel [(set (match_dup 3)
7627                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7628               (clobber (reg:CC FLAGS_REG))])
7629    (parallel [(set (match_dup 0)
7630                    (div:SI (reg:SI 0) (match_dup 2)))
7631               (set (match_dup 3)
7632                    (mod:SI (reg:SI 0) (match_dup 2)))
7633               (use (match_dup 3))
7634               (clobber (reg:CC FLAGS_REG))])]
7635 {
7636   /* Avoid use of cltd in favor of a mov+shift.  */
7637   if (!TARGET_USE_CLTD && !optimize_size)
7638     {
7639       if (true_regnum (operands[1]))
7640         emit_move_insn (operands[0], operands[1]);
7641       else
7642         emit_move_insn (operands[3], operands[1]);
7643       operands[4] = operands[3];
7644     }
7645   else
7646     {
7647       if (true_regnum (operands[1]))
7648         abort();
7649       operands[4] = operands[1];
7650     }
7651 })
7652 ;; %%% Split me.
7653 (define_insn "divmodhi4"
7654   [(set (match_operand:HI 0 "register_operand" "=a")
7655         (div:HI (match_operand:HI 1 "register_operand" "0")
7656                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7657    (set (match_operand:HI 3 "register_operand" "=&d")
7658         (mod:HI (match_dup 1) (match_dup 2)))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "TARGET_HIMODE_MATH"
7661   "cwtd\;idiv{w}\t%2"
7662   [(set_attr "type" "multi")
7663    (set_attr "length_immediate" "0")
7664    (set_attr "mode" "SI")])
7665
7666 (define_insn "udivmoddi4"
7667   [(set (match_operand:DI 0 "register_operand" "=a")
7668         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7669                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7670    (set (match_operand:DI 3 "register_operand" "=&d")
7671         (umod:DI (match_dup 1) (match_dup 2)))
7672    (clobber (reg:CC FLAGS_REG))]
7673   "TARGET_64BIT"
7674   "xor{q}\t%3, %3\;div{q}\t%2"
7675   [(set_attr "type" "multi")
7676    (set_attr "length_immediate" "0")
7677    (set_attr "mode" "DI")])
7678
7679 (define_insn "*udivmoddi4_noext"
7680   [(set (match_operand:DI 0 "register_operand" "=a")
7681         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7682                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7683    (set (match_operand:DI 3 "register_operand" "=d")
7684         (umod:DI (match_dup 1) (match_dup 2)))
7685    (use (match_dup 3))
7686    (clobber (reg:CC FLAGS_REG))]
7687   "TARGET_64BIT"
7688   "div{q}\t%2"
7689   [(set_attr "type" "idiv")
7690    (set_attr "mode" "DI")])
7691
7692 (define_split
7693   [(set (match_operand:DI 0 "register_operand" "")
7694         (udiv:DI (match_operand:DI 1 "register_operand" "")
7695                  (match_operand:DI 2 "nonimmediate_operand" "")))
7696    (set (match_operand:DI 3 "register_operand" "")
7697         (umod:DI (match_dup 1) (match_dup 2)))
7698    (clobber (reg:CC FLAGS_REG))]
7699   "TARGET_64BIT && reload_completed"
7700   [(set (match_dup 3) (const_int 0))
7701    (parallel [(set (match_dup 0)
7702                    (udiv:DI (match_dup 1) (match_dup 2)))
7703               (set (match_dup 3)
7704                    (umod:DI (match_dup 1) (match_dup 2)))
7705               (use (match_dup 3))
7706               (clobber (reg:CC FLAGS_REG))])]
7707   "")
7708
7709 (define_insn "udivmodsi4"
7710   [(set (match_operand:SI 0 "register_operand" "=a")
7711         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7712                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7713    (set (match_operand:SI 3 "register_operand" "=&d")
7714         (umod:SI (match_dup 1) (match_dup 2)))
7715    (clobber (reg:CC FLAGS_REG))]
7716   ""
7717   "xor{l}\t%3, %3\;div{l}\t%2"
7718   [(set_attr "type" "multi")
7719    (set_attr "length_immediate" "0")
7720    (set_attr "mode" "SI")])
7721
7722 (define_insn "*udivmodsi4_noext"
7723   [(set (match_operand:SI 0 "register_operand" "=a")
7724         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7725                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7726    (set (match_operand:SI 3 "register_operand" "=d")
7727         (umod:SI (match_dup 1) (match_dup 2)))
7728    (use (match_dup 3))
7729    (clobber (reg:CC FLAGS_REG))]
7730   ""
7731   "div{l}\t%2"
7732   [(set_attr "type" "idiv")
7733    (set_attr "mode" "SI")])
7734
7735 (define_split
7736   [(set (match_operand:SI 0 "register_operand" "")
7737         (udiv:SI (match_operand:SI 1 "register_operand" "")
7738                  (match_operand:SI 2 "nonimmediate_operand" "")))
7739    (set (match_operand:SI 3 "register_operand" "")
7740         (umod:SI (match_dup 1) (match_dup 2)))
7741    (clobber (reg:CC FLAGS_REG))]
7742   "reload_completed"
7743   [(set (match_dup 3) (const_int 0))
7744    (parallel [(set (match_dup 0)
7745                    (udiv:SI (match_dup 1) (match_dup 2)))
7746               (set (match_dup 3)
7747                    (umod:SI (match_dup 1) (match_dup 2)))
7748               (use (match_dup 3))
7749               (clobber (reg:CC FLAGS_REG))])]
7750   "")
7751
7752 (define_expand "udivmodhi4"
7753   [(set (match_dup 4) (const_int 0))
7754    (parallel [(set (match_operand:HI 0 "register_operand" "")
7755                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7756                             (match_operand:HI 2 "nonimmediate_operand" "")))
7757               (set (match_operand:HI 3 "register_operand" "")
7758                    (umod:HI (match_dup 1) (match_dup 2)))
7759               (use (match_dup 4))
7760               (clobber (reg:CC FLAGS_REG))])]
7761   "TARGET_HIMODE_MATH"
7762   "operands[4] = gen_reg_rtx (HImode);")
7763
7764 (define_insn "*udivmodhi_noext"
7765   [(set (match_operand:HI 0 "register_operand" "=a")
7766         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7767                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7768    (set (match_operand:HI 3 "register_operand" "=d")
7769         (umod:HI (match_dup 1) (match_dup 2)))
7770    (use (match_operand:HI 4 "register_operand" "3"))
7771    (clobber (reg:CC FLAGS_REG))]
7772   ""
7773   "div{w}\t%2"
7774   [(set_attr "type" "idiv")
7775    (set_attr "mode" "HI")])
7776
7777 ;; We cannot use div/idiv for double division, because it causes
7778 ;; "division by zero" on the overflow and that's not what we expect
7779 ;; from truncate.  Because true (non truncating) double division is
7780 ;; never generated, we can't create this insn anyway.
7781 ;
7782 ;(define_insn ""
7783 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7784 ;       (truncate:SI
7785 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7786 ;                  (zero_extend:DI
7787 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7788 ;   (set (match_operand:SI 3 "register_operand" "=d")
7789 ;       (truncate:SI
7790 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7791 ;   (clobber (reg:CC FLAGS_REG))]
7792 ;  ""
7793 ;  "div{l}\t{%2, %0|%0, %2}"
7794 ;  [(set_attr "type" "idiv")])
7795 \f
7796 ;;- Logical AND instructions
7797
7798 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7799 ;; Note that this excludes ah.
7800
7801 (define_insn "*testdi_1_rex64"
7802   [(set (reg FLAGS_REG)
7803         (compare
7804           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7805                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7806           (const_int 0)))]
7807   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7808    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7809   "@
7810    test{l}\t{%k1, %k0|%k0, %k1}
7811    test{l}\t{%k1, %k0|%k0, %k1}
7812    test{q}\t{%1, %0|%0, %1}
7813    test{q}\t{%1, %0|%0, %1}
7814    test{q}\t{%1, %0|%0, %1}"
7815   [(set_attr "type" "test")
7816    (set_attr "modrm" "0,1,0,1,1")
7817    (set_attr "mode" "SI,SI,DI,DI,DI")
7818    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7819
7820 (define_insn "testsi_1"
7821   [(set (reg FLAGS_REG)
7822         (compare
7823           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7824                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7825           (const_int 0)))]
7826   "ix86_match_ccmode (insn, CCNOmode)
7827    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7828   "test{l}\t{%1, %0|%0, %1}"
7829   [(set_attr "type" "test")
7830    (set_attr "modrm" "0,1,1")
7831    (set_attr "mode" "SI")
7832    (set_attr "pent_pair" "uv,np,uv")])
7833
7834 (define_expand "testsi_ccno_1"
7835   [(set (reg:CCNO FLAGS_REG)
7836         (compare:CCNO
7837           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7838                   (match_operand:SI 1 "nonmemory_operand" ""))
7839           (const_int 0)))]
7840   ""
7841   "")
7842
7843 (define_insn "*testhi_1"
7844   [(set (reg FLAGS_REG)
7845         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7846                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7847                  (const_int 0)))]
7848   "ix86_match_ccmode (insn, CCNOmode)
7849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7850   "test{w}\t{%1, %0|%0, %1}"
7851   [(set_attr "type" "test")
7852    (set_attr "modrm" "0,1,1")
7853    (set_attr "mode" "HI")
7854    (set_attr "pent_pair" "uv,np,uv")])
7855
7856 (define_expand "testqi_ccz_1"
7857   [(set (reg:CCZ FLAGS_REG)
7858         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7859                              (match_operand:QI 1 "nonmemory_operand" ""))
7860                  (const_int 0)))]
7861   ""
7862   "")
7863
7864 (define_insn "*testqi_1_maybe_si"
7865   [(set (reg FLAGS_REG)
7866         (compare
7867           (and:QI
7868             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7869             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7870           (const_int 0)))]
7871    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7872     && ix86_match_ccmode (insn,
7873                          GET_CODE (operands[1]) == CONST_INT
7874                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7875 {
7876   if (which_alternative == 3)
7877     {
7878       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7879         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7880       return "test{l}\t{%1, %k0|%k0, %1}";
7881     }
7882   return "test{b}\t{%1, %0|%0, %1}";
7883 }
7884   [(set_attr "type" "test")
7885    (set_attr "modrm" "0,1,1,1")
7886    (set_attr "mode" "QI,QI,QI,SI")
7887    (set_attr "pent_pair" "uv,np,uv,np")])
7888
7889 (define_insn "*testqi_1"
7890   [(set (reg FLAGS_REG)
7891         (compare
7892           (and:QI
7893             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7894             (match_operand:QI 1 "general_operand" "n,n,qn"))
7895           (const_int 0)))]
7896   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7897    && ix86_match_ccmode (insn, CCNOmode)"
7898   "test{b}\t{%1, %0|%0, %1}"
7899   [(set_attr "type" "test")
7900    (set_attr "modrm" "0,1,1")
7901    (set_attr "mode" "QI")
7902    (set_attr "pent_pair" "uv,np,uv")])
7903
7904 (define_expand "testqi_ext_ccno_0"
7905   [(set (reg:CCNO FLAGS_REG)
7906         (compare:CCNO
7907           (and:SI
7908             (zero_extract:SI
7909               (match_operand 0 "ext_register_operand" "")
7910               (const_int 8)
7911               (const_int 8))
7912             (match_operand 1 "const_int_operand" ""))
7913           (const_int 0)))]
7914   ""
7915   "")
7916
7917 (define_insn "*testqi_ext_0"
7918   [(set (reg FLAGS_REG)
7919         (compare
7920           (and:SI
7921             (zero_extract:SI
7922               (match_operand 0 "ext_register_operand" "Q")
7923               (const_int 8)
7924               (const_int 8))
7925             (match_operand 1 "const_int_operand" "n"))
7926           (const_int 0)))]
7927   "ix86_match_ccmode (insn, CCNOmode)"
7928   "test{b}\t{%1, %h0|%h0, %1}"
7929   [(set_attr "type" "test")
7930    (set_attr "mode" "QI")
7931    (set_attr "length_immediate" "1")
7932    (set_attr "pent_pair" "np")])
7933
7934 (define_insn "*testqi_ext_1"
7935   [(set (reg FLAGS_REG)
7936         (compare
7937           (and:SI
7938             (zero_extract:SI
7939               (match_operand 0 "ext_register_operand" "Q")
7940               (const_int 8)
7941               (const_int 8))
7942             (zero_extend:SI
7943               (match_operand:QI 1 "general_operand" "Qm")))
7944           (const_int 0)))]
7945   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7946    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7947   "test{b}\t{%1, %h0|%h0, %1}"
7948   [(set_attr "type" "test")
7949    (set_attr "mode" "QI")])
7950
7951 (define_insn "*testqi_ext_1_rex64"
7952   [(set (reg FLAGS_REG)
7953         (compare
7954           (and:SI
7955             (zero_extract:SI
7956               (match_operand 0 "ext_register_operand" "Q")
7957               (const_int 8)
7958               (const_int 8))
7959             (zero_extend:SI
7960               (match_operand:QI 1 "register_operand" "Q")))
7961           (const_int 0)))]
7962   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7963   "test{b}\t{%1, %h0|%h0, %1}"
7964   [(set_attr "type" "test")
7965    (set_attr "mode" "QI")])
7966
7967 (define_insn "*testqi_ext_2"
7968   [(set (reg FLAGS_REG)
7969         (compare
7970           (and:SI
7971             (zero_extract:SI
7972               (match_operand 0 "ext_register_operand" "Q")
7973               (const_int 8)
7974               (const_int 8))
7975             (zero_extract:SI
7976               (match_operand 1 "ext_register_operand" "Q")
7977               (const_int 8)
7978               (const_int 8)))
7979           (const_int 0)))]
7980   "ix86_match_ccmode (insn, CCNOmode)"
7981   "test{b}\t{%h1, %h0|%h0, %h1}"
7982   [(set_attr "type" "test")
7983    (set_attr "mode" "QI")])
7984
7985 ;; Combine likes to form bit extractions for some tests.  Humor it.
7986 (define_insn "*testqi_ext_3"
7987   [(set (reg FLAGS_REG)
7988         (compare (zero_extract:SI
7989                    (match_operand 0 "nonimmediate_operand" "rm")
7990                    (match_operand:SI 1 "const_int_operand" "")
7991                    (match_operand:SI 2 "const_int_operand" ""))
7992                  (const_int 0)))]
7993   "ix86_match_ccmode (insn, CCNOmode)
7994    && (GET_MODE (operands[0]) == SImode
7995        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7996        || GET_MODE (operands[0]) == HImode
7997        || GET_MODE (operands[0]) == QImode)"
7998   "#")
7999
8000 (define_insn "*testqi_ext_3_rex64"
8001   [(set (reg FLAGS_REG)
8002         (compare (zero_extract:DI
8003                    (match_operand 0 "nonimmediate_operand" "rm")
8004                    (match_operand:DI 1 "const_int_operand" "")
8005                    (match_operand:DI 2 "const_int_operand" ""))
8006                  (const_int 0)))]
8007   "TARGET_64BIT
8008    && ix86_match_ccmode (insn, CCNOmode)
8009    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8010    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8011    /* Ensure that resulting mask is zero or sign extended operand.  */
8012    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8013        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8014            && INTVAL (operands[1]) > 32))
8015    && (GET_MODE (operands[0]) == SImode
8016        || GET_MODE (operands[0]) == DImode
8017        || GET_MODE (operands[0]) == HImode
8018        || GET_MODE (operands[0]) == QImode)"
8019   "#")
8020
8021 (define_split
8022   [(set (match_operand 0 "flags_reg_operand" "")
8023         (match_operator 1 "compare_operator"
8024           [(zero_extract
8025              (match_operand 2 "nonimmediate_operand" "")
8026              (match_operand 3 "const_int_operand" "")
8027              (match_operand 4 "const_int_operand" ""))
8028            (const_int 0)]))]
8029   "ix86_match_ccmode (insn, CCNOmode)"
8030   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8031 {
8032   rtx val = operands[2];
8033   HOST_WIDE_INT len = INTVAL (operands[3]);
8034   HOST_WIDE_INT pos = INTVAL (operands[4]);
8035   HOST_WIDE_INT mask;
8036   enum machine_mode mode, submode;
8037
8038   mode = GET_MODE (val);
8039   if (GET_CODE (val) == MEM)
8040     {
8041       /* ??? Combine likes to put non-volatile mem extractions in QImode
8042          no matter the size of the test.  So find a mode that works.  */
8043       if (! MEM_VOLATILE_P (val))
8044         {
8045           mode = smallest_mode_for_size (pos + len, MODE_INT);
8046           val = adjust_address (val, mode, 0);
8047         }
8048     }
8049   else if (GET_CODE (val) == SUBREG
8050            && (submode = GET_MODE (SUBREG_REG (val)),
8051                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8052            && pos + len <= GET_MODE_BITSIZE (submode))
8053     {
8054       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8055       mode = submode;
8056       val = SUBREG_REG (val);
8057     }
8058   else if (mode == HImode && pos + len <= 8)
8059     {
8060       /* Small HImode tests can be converted to QImode.  */
8061       mode = QImode;
8062       val = gen_lowpart (QImode, val);
8063     }
8064
8065   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8066   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8067
8068   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8069 })
8070
8071 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8072 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8073 ;; this is relatively important trick.
8074 ;; Do the conversion only post-reload to avoid limiting of the register class
8075 ;; to QI regs.
8076 (define_split
8077   [(set (match_operand 0 "flags_reg_operand" "")
8078         (match_operator 1 "compare_operator"
8079           [(and (match_operand 2 "register_operand" "")
8080                 (match_operand 3 "const_int_operand" ""))
8081            (const_int 0)]))]
8082    "reload_completed
8083     && QI_REG_P (operands[2])
8084     && GET_MODE (operands[2]) != QImode
8085     && ((ix86_match_ccmode (insn, CCZmode)
8086          && !(INTVAL (operands[3]) & ~(255 << 8)))
8087         || (ix86_match_ccmode (insn, CCNOmode)
8088             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8089   [(set (match_dup 0)
8090         (match_op_dup 1
8091           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8092                    (match_dup 3))
8093            (const_int 0)]))]
8094   "operands[2] = gen_lowpart (SImode, operands[2]);
8095    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8096
8097 (define_split
8098   [(set (match_operand 0 "flags_reg_operand" "")
8099         (match_operator 1 "compare_operator"
8100           [(and (match_operand 2 "nonimmediate_operand" "")
8101                 (match_operand 3 "const_int_operand" ""))
8102            (const_int 0)]))]
8103    "reload_completed
8104     && GET_MODE (operands[2]) != QImode
8105     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8106     && ((ix86_match_ccmode (insn, CCZmode)
8107          && !(INTVAL (operands[3]) & ~255))
8108         || (ix86_match_ccmode (insn, CCNOmode)
8109             && !(INTVAL (operands[3]) & ~127)))"
8110   [(set (match_dup 0)
8111         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8112                          (const_int 0)]))]
8113   "operands[2] = gen_lowpart (QImode, operands[2]);
8114    operands[3] = gen_lowpart (QImode, operands[3]);")
8115
8116
8117 ;; %%% This used to optimize known byte-wide and operations to memory,
8118 ;; and sometimes to QImode registers.  If this is considered useful,
8119 ;; it should be done with splitters.
8120
8121 (define_expand "anddi3"
8122   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8123         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8124                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8125    (clobber (reg:CC FLAGS_REG))]
8126   "TARGET_64BIT"
8127   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8128
8129 (define_insn "*anddi_1_rex64"
8130   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8131         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8132                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8133    (clobber (reg:CC FLAGS_REG))]
8134   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8135 {
8136   switch (get_attr_type (insn))
8137     {
8138     case TYPE_IMOVX:
8139       {
8140         enum machine_mode mode;
8141
8142         if (GET_CODE (operands[2]) != CONST_INT)
8143           abort ();
8144         if (INTVAL (operands[2]) == 0xff)
8145           mode = QImode;
8146         else if (INTVAL (operands[2]) == 0xffff)
8147           mode = HImode;
8148         else
8149           abort ();
8150         
8151         operands[1] = gen_lowpart (mode, operands[1]);
8152         if (mode == QImode)
8153           return "movz{bq|x}\t{%1,%0|%0, %1}";
8154         else
8155           return "movz{wq|x}\t{%1,%0|%0, %1}";
8156       }
8157
8158     default:
8159       if (! rtx_equal_p (operands[0], operands[1]))
8160         abort ();
8161       if (get_attr_mode (insn) == MODE_SI)
8162         return "and{l}\t{%k2, %k0|%k0, %k2}";
8163       else
8164         return "and{q}\t{%2, %0|%0, %2}";
8165     }
8166 }
8167   [(set_attr "type" "alu,alu,alu,imovx")
8168    (set_attr "length_immediate" "*,*,*,0")
8169    (set_attr "mode" "SI,DI,DI,DI")])
8170
8171 (define_insn "*anddi_2"
8172   [(set (reg FLAGS_REG)
8173         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8174                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8175                  (const_int 0)))
8176    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8177         (and:DI (match_dup 1) (match_dup 2)))]
8178   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8179    && ix86_binary_operator_ok (AND, DImode, operands)"
8180   "@
8181    and{l}\t{%k2, %k0|%k0, %k2}
8182    and{q}\t{%2, %0|%0, %2}
8183    and{q}\t{%2, %0|%0, %2}"
8184   [(set_attr "type" "alu")
8185    (set_attr "mode" "SI,DI,DI")])
8186
8187 (define_expand "andsi3"
8188   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8189         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8190                 (match_operand:SI 2 "general_operand" "")))
8191    (clobber (reg:CC FLAGS_REG))]
8192   ""
8193   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8194
8195 (define_insn "*andsi_1"
8196   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8197         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8198                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "ix86_binary_operator_ok (AND, SImode, operands)"
8201 {
8202   switch (get_attr_type (insn))
8203     {
8204     case TYPE_IMOVX:
8205       {
8206         enum machine_mode mode;
8207
8208         if (GET_CODE (operands[2]) != CONST_INT)
8209           abort ();
8210         if (INTVAL (operands[2]) == 0xff)
8211           mode = QImode;
8212         else if (INTVAL (operands[2]) == 0xffff)
8213           mode = HImode;
8214         else
8215           abort ();
8216         
8217         operands[1] = gen_lowpart (mode, operands[1]);
8218         if (mode == QImode)
8219           return "movz{bl|x}\t{%1,%0|%0, %1}";
8220         else
8221           return "movz{wl|x}\t{%1,%0|%0, %1}";
8222       }
8223
8224     default:
8225       if (! rtx_equal_p (operands[0], operands[1]))
8226         abort ();
8227       return "and{l}\t{%2, %0|%0, %2}";
8228     }
8229 }
8230   [(set_attr "type" "alu,alu,imovx")
8231    (set_attr "length_immediate" "*,*,0")
8232    (set_attr "mode" "SI")])
8233
8234 (define_split
8235   [(set (match_operand 0 "register_operand" "")
8236         (and (match_dup 0)
8237              (const_int -65536)))
8238    (clobber (reg:CC FLAGS_REG))]
8239   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8240   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8241   "operands[1] = gen_lowpart (HImode, operands[0]);")
8242
8243 (define_split
8244   [(set (match_operand 0 "ext_register_operand" "")
8245         (and (match_dup 0)
8246              (const_int -256)))
8247    (clobber (reg:CC FLAGS_REG))]
8248   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8249   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8250   "operands[1] = gen_lowpart (QImode, operands[0]);")
8251
8252 (define_split
8253   [(set (match_operand 0 "ext_register_operand" "")
8254         (and (match_dup 0)
8255              (const_int -65281)))
8256    (clobber (reg:CC FLAGS_REG))]
8257   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8258   [(parallel [(set (zero_extract:SI (match_dup 0)
8259                                     (const_int 8)
8260                                     (const_int 8))
8261                    (xor:SI 
8262                      (zero_extract:SI (match_dup 0)
8263                                       (const_int 8)
8264                                       (const_int 8))
8265                      (zero_extract:SI (match_dup 0)
8266                                       (const_int 8)
8267                                       (const_int 8))))
8268               (clobber (reg:CC FLAGS_REG))])]
8269   "operands[0] = gen_lowpart (SImode, operands[0]);")
8270
8271 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8272 (define_insn "*andsi_1_zext"
8273   [(set (match_operand:DI 0 "register_operand" "=r")
8274         (zero_extend:DI
8275           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8276                   (match_operand:SI 2 "general_operand" "rim"))))
8277    (clobber (reg:CC FLAGS_REG))]
8278   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8279   "and{l}\t{%2, %k0|%k0, %2}"
8280   [(set_attr "type" "alu")
8281    (set_attr "mode" "SI")])
8282
8283 (define_insn "*andsi_2"
8284   [(set (reg FLAGS_REG)
8285         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8286                          (match_operand:SI 2 "general_operand" "rim,ri"))
8287                  (const_int 0)))
8288    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8289         (and:SI (match_dup 1) (match_dup 2)))]
8290   "ix86_match_ccmode (insn, CCNOmode)
8291    && ix86_binary_operator_ok (AND, SImode, operands)"
8292   "and{l}\t{%2, %0|%0, %2}"
8293   [(set_attr "type" "alu")
8294    (set_attr "mode" "SI")])
8295
8296 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8297 (define_insn "*andsi_2_zext"
8298   [(set (reg FLAGS_REG)
8299         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8300                          (match_operand:SI 2 "general_operand" "rim"))
8301                  (const_int 0)))
8302    (set (match_operand:DI 0 "register_operand" "=r")
8303         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8304   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8305    && ix86_binary_operator_ok (AND, SImode, operands)"
8306   "and{l}\t{%2, %k0|%k0, %2}"
8307   [(set_attr "type" "alu")
8308    (set_attr "mode" "SI")])
8309
8310 (define_expand "andhi3"
8311   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8312         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8313                 (match_operand:HI 2 "general_operand" "")))
8314    (clobber (reg:CC FLAGS_REG))]
8315   "TARGET_HIMODE_MATH"
8316   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8317
8318 (define_insn "*andhi_1"
8319   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8320         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8321                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8322    (clobber (reg:CC FLAGS_REG))]
8323   "ix86_binary_operator_ok (AND, HImode, operands)"
8324 {
8325   switch (get_attr_type (insn))
8326     {
8327     case TYPE_IMOVX:
8328       if (GET_CODE (operands[2]) != CONST_INT)
8329         abort ();
8330       if (INTVAL (operands[2]) == 0xff)
8331         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8332       abort ();
8333
8334     default:
8335       if (! rtx_equal_p (operands[0], operands[1]))
8336         abort ();
8337
8338       return "and{w}\t{%2, %0|%0, %2}";
8339     }
8340 }
8341   [(set_attr "type" "alu,alu,imovx")
8342    (set_attr "length_immediate" "*,*,0")
8343    (set_attr "mode" "HI,HI,SI")])
8344
8345 (define_insn "*andhi_2"
8346   [(set (reg FLAGS_REG)
8347         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8348                          (match_operand:HI 2 "general_operand" "rim,ri"))
8349                  (const_int 0)))
8350    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8351         (and:HI (match_dup 1) (match_dup 2)))]
8352   "ix86_match_ccmode (insn, CCNOmode)
8353    && ix86_binary_operator_ok (AND, HImode, operands)"
8354   "and{w}\t{%2, %0|%0, %2}"
8355   [(set_attr "type" "alu")
8356    (set_attr "mode" "HI")])
8357
8358 (define_expand "andqi3"
8359   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8360         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8361                 (match_operand:QI 2 "general_operand" "")))
8362    (clobber (reg:CC FLAGS_REG))]
8363   "TARGET_QIMODE_MATH"
8364   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8365
8366 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8367 (define_insn "*andqi_1"
8368   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8369         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8370                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8371    (clobber (reg:CC FLAGS_REG))]
8372   "ix86_binary_operator_ok (AND, QImode, operands)"
8373   "@
8374    and{b}\t{%2, %0|%0, %2}
8375    and{b}\t{%2, %0|%0, %2}
8376    and{l}\t{%k2, %k0|%k0, %k2}"
8377   [(set_attr "type" "alu")
8378    (set_attr "mode" "QI,QI,SI")])
8379
8380 (define_insn "*andqi_1_slp"
8381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8382         (and:QI (match_dup 0)
8383                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8384    (clobber (reg:CC FLAGS_REG))]
8385   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8386    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8387   "and{b}\t{%1, %0|%0, %1}"
8388   [(set_attr "type" "alu1")
8389    (set_attr "mode" "QI")])
8390
8391 (define_insn "*andqi_2_maybe_si"
8392   [(set (reg FLAGS_REG)
8393         (compare (and:QI
8394                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8395                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8396                  (const_int 0)))
8397    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8398         (and:QI (match_dup 1) (match_dup 2)))]
8399   "ix86_binary_operator_ok (AND, QImode, operands)
8400    && ix86_match_ccmode (insn,
8401                          GET_CODE (operands[2]) == CONST_INT
8402                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8403 {
8404   if (which_alternative == 2)
8405     {
8406       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8407         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8408       return "and{l}\t{%2, %k0|%k0, %2}";
8409     }
8410   return "and{b}\t{%2, %0|%0, %2}";
8411 }
8412   [(set_attr "type" "alu")
8413    (set_attr "mode" "QI,QI,SI")])
8414
8415 (define_insn "*andqi_2"
8416   [(set (reg FLAGS_REG)
8417         (compare (and:QI
8418                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8419                    (match_operand:QI 2 "general_operand" "qim,qi"))
8420                  (const_int 0)))
8421    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8422         (and:QI (match_dup 1) (match_dup 2)))]
8423   "ix86_match_ccmode (insn, CCNOmode)
8424    && ix86_binary_operator_ok (AND, QImode, operands)"
8425   "and{b}\t{%2, %0|%0, %2}"
8426   [(set_attr "type" "alu")
8427    (set_attr "mode" "QI")])
8428
8429 (define_insn "*andqi_2_slp"
8430   [(set (reg FLAGS_REG)
8431         (compare (and:QI
8432                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8433                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8434                  (const_int 0)))
8435    (set (strict_low_part (match_dup 0))
8436         (and:QI (match_dup 0) (match_dup 1)))]
8437   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8438    && ix86_match_ccmode (insn, CCNOmode)
8439    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8440   "and{b}\t{%1, %0|%0, %1}"
8441   [(set_attr "type" "alu1")
8442    (set_attr "mode" "QI")])
8443
8444 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8445 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8446 ;; for a QImode operand, which of course failed.
8447
8448 (define_insn "andqi_ext_0"
8449   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8450                          (const_int 8)
8451                          (const_int 8))
8452         (and:SI 
8453           (zero_extract:SI
8454             (match_operand 1 "ext_register_operand" "0")
8455             (const_int 8)
8456             (const_int 8))
8457           (match_operand 2 "const_int_operand" "n")))
8458    (clobber (reg:CC FLAGS_REG))]
8459   ""
8460   "and{b}\t{%2, %h0|%h0, %2}"
8461   [(set_attr "type" "alu")
8462    (set_attr "length_immediate" "1")
8463    (set_attr "mode" "QI")])
8464
8465 ;; Generated by peephole translating test to and.  This shows up
8466 ;; often in fp comparisons.
8467
8468 (define_insn "*andqi_ext_0_cc"
8469   [(set (reg FLAGS_REG)
8470         (compare
8471           (and:SI
8472             (zero_extract:SI
8473               (match_operand 1 "ext_register_operand" "0")
8474               (const_int 8)
8475               (const_int 8))
8476             (match_operand 2 "const_int_operand" "n"))
8477           (const_int 0)))
8478    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479                          (const_int 8)
8480                          (const_int 8))
8481         (and:SI 
8482           (zero_extract:SI
8483             (match_dup 1)
8484             (const_int 8)
8485             (const_int 8))
8486           (match_dup 2)))]
8487   "ix86_match_ccmode (insn, CCNOmode)"
8488   "and{b}\t{%2, %h0|%h0, %2}"
8489   [(set_attr "type" "alu")
8490    (set_attr "length_immediate" "1")
8491    (set_attr "mode" "QI")])
8492
8493 (define_insn "*andqi_ext_1"
8494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8495                          (const_int 8)
8496                          (const_int 8))
8497         (and:SI 
8498           (zero_extract:SI
8499             (match_operand 1 "ext_register_operand" "0")
8500             (const_int 8)
8501             (const_int 8))
8502           (zero_extend:SI
8503             (match_operand:QI 2 "general_operand" "Qm"))))
8504    (clobber (reg:CC FLAGS_REG))]
8505   "!TARGET_64BIT"
8506   "and{b}\t{%2, %h0|%h0, %2}"
8507   [(set_attr "type" "alu")
8508    (set_attr "length_immediate" "0")
8509    (set_attr "mode" "QI")])
8510
8511 (define_insn "*andqi_ext_1_rex64"
8512   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8513                          (const_int 8)
8514                          (const_int 8))
8515         (and:SI 
8516           (zero_extract:SI
8517             (match_operand 1 "ext_register_operand" "0")
8518             (const_int 8)
8519             (const_int 8))
8520           (zero_extend:SI
8521             (match_operand 2 "ext_register_operand" "Q"))))
8522    (clobber (reg:CC FLAGS_REG))]
8523   "TARGET_64BIT"
8524   "and{b}\t{%2, %h0|%h0, %2}"
8525   [(set_attr "type" "alu")
8526    (set_attr "length_immediate" "0")
8527    (set_attr "mode" "QI")])
8528
8529 (define_insn "*andqi_ext_2"
8530   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8531                          (const_int 8)
8532                          (const_int 8))
8533         (and:SI
8534           (zero_extract:SI
8535             (match_operand 1 "ext_register_operand" "%0")
8536             (const_int 8)
8537             (const_int 8))
8538           (zero_extract:SI
8539             (match_operand 2 "ext_register_operand" "Q")
8540             (const_int 8)
8541             (const_int 8))))
8542    (clobber (reg:CC FLAGS_REG))]
8543   ""
8544   "and{b}\t{%h2, %h0|%h0, %h2}"
8545   [(set_attr "type" "alu")
8546    (set_attr "length_immediate" "0")
8547    (set_attr "mode" "QI")])
8548
8549 ;; Convert wide AND instructions with immediate operand to shorter QImode
8550 ;; equivalents when possible.
8551 ;; Don't do the splitting with memory operands, since it introduces risk
8552 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8553 ;; for size, but that can (should?) be handled by generic code instead.
8554 (define_split
8555   [(set (match_operand 0 "register_operand" "")
8556         (and (match_operand 1 "register_operand" "")
8557              (match_operand 2 "const_int_operand" "")))
8558    (clobber (reg:CC FLAGS_REG))]
8559    "reload_completed
8560     && QI_REG_P (operands[0])
8561     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8562     && !(~INTVAL (operands[2]) & ~(255 << 8))
8563     && GET_MODE (operands[0]) != QImode"
8564   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8565                    (and:SI (zero_extract:SI (match_dup 1)
8566                                             (const_int 8) (const_int 8))
8567                            (match_dup 2)))
8568               (clobber (reg:CC FLAGS_REG))])]
8569   "operands[0] = gen_lowpart (SImode, operands[0]);
8570    operands[1] = gen_lowpart (SImode, operands[1]);
8571    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8572
8573 ;; Since AND can be encoded with sign extended immediate, this is only
8574 ;; profitable when 7th bit is not set.
8575 (define_split
8576   [(set (match_operand 0 "register_operand" "")
8577         (and (match_operand 1 "general_operand" "")
8578              (match_operand 2 "const_int_operand" "")))
8579    (clobber (reg:CC FLAGS_REG))]
8580    "reload_completed
8581     && ANY_QI_REG_P (operands[0])
8582     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8583     && !(~INTVAL (operands[2]) & ~255)
8584     && !(INTVAL (operands[2]) & 128)
8585     && GET_MODE (operands[0]) != QImode"
8586   [(parallel [(set (strict_low_part (match_dup 0))
8587                    (and:QI (match_dup 1)
8588                            (match_dup 2)))
8589               (clobber (reg:CC FLAGS_REG))])]
8590   "operands[0] = gen_lowpart (QImode, operands[0]);
8591    operands[1] = gen_lowpart (QImode, operands[1]);
8592    operands[2] = gen_lowpart (QImode, operands[2]);")
8593 \f
8594 ;; Logical inclusive OR instructions
8595
8596 ;; %%% This used to optimize known byte-wide and operations to memory.
8597 ;; If this is considered useful, it should be done with splitters.
8598
8599 (define_expand "iordi3"
8600   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8601         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8602                 (match_operand:DI 2 "x86_64_general_operand" "")))
8603    (clobber (reg:CC FLAGS_REG))]
8604   "TARGET_64BIT"
8605   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8606
8607 (define_insn "*iordi_1_rex64"
8608   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8609         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8610                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8611    (clobber (reg:CC FLAGS_REG))]
8612   "TARGET_64BIT
8613    && ix86_binary_operator_ok (IOR, DImode, operands)"
8614   "or{q}\t{%2, %0|%0, %2}"
8615   [(set_attr "type" "alu")
8616    (set_attr "mode" "DI")])
8617
8618 (define_insn "*iordi_2_rex64"
8619   [(set (reg FLAGS_REG)
8620         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8621                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8622                  (const_int 0)))
8623    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8624         (ior:DI (match_dup 1) (match_dup 2)))]
8625   "TARGET_64BIT
8626    && ix86_match_ccmode (insn, CCNOmode)
8627    && ix86_binary_operator_ok (IOR, DImode, operands)"
8628   "or{q}\t{%2, %0|%0, %2}"
8629   [(set_attr "type" "alu")
8630    (set_attr "mode" "DI")])
8631
8632 (define_insn "*iordi_3_rex64"
8633   [(set (reg FLAGS_REG)
8634         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8635                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8636                  (const_int 0)))
8637    (clobber (match_scratch:DI 0 "=r"))]
8638   "TARGET_64BIT
8639    && ix86_match_ccmode (insn, CCNOmode)
8640    && ix86_binary_operator_ok (IOR, DImode, operands)"
8641   "or{q}\t{%2, %0|%0, %2}"
8642   [(set_attr "type" "alu")
8643    (set_attr "mode" "DI")])
8644
8645
8646 (define_expand "iorsi3"
8647   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8648         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8649                 (match_operand:SI 2 "general_operand" "")))
8650    (clobber (reg:CC FLAGS_REG))]
8651   ""
8652   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8653
8654 (define_insn "*iorsi_1"
8655   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8656         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8657                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8658    (clobber (reg:CC FLAGS_REG))]
8659   "ix86_binary_operator_ok (IOR, SImode, operands)"
8660   "or{l}\t{%2, %0|%0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8663
8664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665 (define_insn "*iorsi_1_zext"
8666   [(set (match_operand:DI 0 "register_operand" "=rm")
8667         (zero_extend:DI
8668           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669                   (match_operand:SI 2 "general_operand" "rim"))))
8670    (clobber (reg:CC FLAGS_REG))]
8671   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8672   "or{l}\t{%2, %k0|%k0, %2}"
8673   [(set_attr "type" "alu")
8674    (set_attr "mode" "SI")])
8675
8676 (define_insn "*iorsi_1_zext_imm"
8677   [(set (match_operand:DI 0 "register_operand" "=rm")
8678         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8679                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8680    (clobber (reg:CC FLAGS_REG))]
8681   "TARGET_64BIT"
8682   "or{l}\t{%2, %k0|%k0, %2}"
8683   [(set_attr "type" "alu")
8684    (set_attr "mode" "SI")])
8685
8686 (define_insn "*iorsi_2"
8687   [(set (reg FLAGS_REG)
8688         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8689                          (match_operand:SI 2 "general_operand" "rim,ri"))
8690                  (const_int 0)))
8691    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8692         (ior:SI (match_dup 1) (match_dup 2)))]
8693   "ix86_match_ccmode (insn, CCNOmode)
8694    && ix86_binary_operator_ok (IOR, SImode, operands)"
8695   "or{l}\t{%2, %0|%0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "SI")])
8698
8699 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8700 ;; ??? Special case for immediate operand is missing - it is tricky.
8701 (define_insn "*iorsi_2_zext"
8702   [(set (reg FLAGS_REG)
8703         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8704                          (match_operand:SI 2 "general_operand" "rim"))
8705                  (const_int 0)))
8706    (set (match_operand:DI 0 "register_operand" "=r")
8707         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8708   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8709    && ix86_binary_operator_ok (IOR, SImode, operands)"
8710   "or{l}\t{%2, %k0|%k0, %2}"
8711   [(set_attr "type" "alu")
8712    (set_attr "mode" "SI")])
8713
8714 (define_insn "*iorsi_2_zext_imm"
8715   [(set (reg FLAGS_REG)
8716         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8717                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8718                  (const_int 0)))
8719    (set (match_operand:DI 0 "register_operand" "=r")
8720         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8721   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8722    && ix86_binary_operator_ok (IOR, SImode, operands)"
8723   "or{l}\t{%2, %k0|%k0, %2}"
8724   [(set_attr "type" "alu")
8725    (set_attr "mode" "SI")])
8726
8727 (define_insn "*iorsi_3"
8728   [(set (reg FLAGS_REG)
8729         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8730                          (match_operand:SI 2 "general_operand" "rim"))
8731                  (const_int 0)))
8732    (clobber (match_scratch:SI 0 "=r"))]
8733   "ix86_match_ccmode (insn, CCNOmode)
8734    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8735   "or{l}\t{%2, %0|%0, %2}"
8736   [(set_attr "type" "alu")
8737    (set_attr "mode" "SI")])
8738
8739 (define_expand "iorhi3"
8740   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8741         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8742                 (match_operand:HI 2 "general_operand" "")))
8743    (clobber (reg:CC FLAGS_REG))]
8744   "TARGET_HIMODE_MATH"
8745   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8746
8747 (define_insn "*iorhi_1"
8748   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8749         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8750                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "ix86_binary_operator_ok (IOR, HImode, operands)"
8753   "or{w}\t{%2, %0|%0, %2}"
8754   [(set_attr "type" "alu")
8755    (set_attr "mode" "HI")])
8756
8757 (define_insn "*iorhi_2"
8758   [(set (reg FLAGS_REG)
8759         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8760                          (match_operand:HI 2 "general_operand" "rim,ri"))
8761                  (const_int 0)))
8762    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8763         (ior:HI (match_dup 1) (match_dup 2)))]
8764   "ix86_match_ccmode (insn, CCNOmode)
8765    && ix86_binary_operator_ok (IOR, HImode, operands)"
8766   "or{w}\t{%2, %0|%0, %2}"
8767   [(set_attr "type" "alu")
8768    (set_attr "mode" "HI")])
8769
8770 (define_insn "*iorhi_3"
8771   [(set (reg FLAGS_REG)
8772         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8773                          (match_operand:HI 2 "general_operand" "rim"))
8774                  (const_int 0)))
8775    (clobber (match_scratch:HI 0 "=r"))]
8776   "ix86_match_ccmode (insn, CCNOmode)
8777    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8778   "or{w}\t{%2, %0|%0, %2}"
8779   [(set_attr "type" "alu")
8780    (set_attr "mode" "HI")])
8781
8782 (define_expand "iorqi3"
8783   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8784         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8785                 (match_operand:QI 2 "general_operand" "")))
8786    (clobber (reg:CC FLAGS_REG))]
8787   "TARGET_QIMODE_MATH"
8788   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8789
8790 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8791 (define_insn "*iorqi_1"
8792   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8793         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8794                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8795    (clobber (reg:CC FLAGS_REG))]
8796   "ix86_binary_operator_ok (IOR, QImode, operands)"
8797   "@
8798    or{b}\t{%2, %0|%0, %2}
8799    or{b}\t{%2, %0|%0, %2}
8800    or{l}\t{%k2, %k0|%k0, %k2}"
8801   [(set_attr "type" "alu")
8802    (set_attr "mode" "QI,QI,SI")])
8803
8804 (define_insn "*iorqi_1_slp"
8805   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8806         (ior:QI (match_dup 0)
8807                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8808    (clobber (reg:CC FLAGS_REG))]
8809   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8810    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8811   "or{b}\t{%1, %0|%0, %1}"
8812   [(set_attr "type" "alu1")
8813    (set_attr "mode" "QI")])
8814
8815 (define_insn "*iorqi_2"
8816   [(set (reg FLAGS_REG)
8817         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8818                          (match_operand:QI 2 "general_operand" "qim,qi"))
8819                  (const_int 0)))
8820    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8821         (ior:QI (match_dup 1) (match_dup 2)))]
8822   "ix86_match_ccmode (insn, CCNOmode)
8823    && ix86_binary_operator_ok (IOR, QImode, operands)"
8824   "or{b}\t{%2, %0|%0, %2}"
8825   [(set_attr "type" "alu")
8826    (set_attr "mode" "QI")])
8827
8828 (define_insn "*iorqi_2_slp"
8829   [(set (reg FLAGS_REG)
8830         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8831                          (match_operand:QI 1 "general_operand" "qim,qi"))
8832                  (const_int 0)))
8833    (set (strict_low_part (match_dup 0))
8834         (ior:QI (match_dup 0) (match_dup 1)))]
8835   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8836    && ix86_match_ccmode (insn, CCNOmode)
8837    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8838   "or{b}\t{%1, %0|%0, %1}"
8839   [(set_attr "type" "alu1")
8840    (set_attr "mode" "QI")])
8841
8842 (define_insn "*iorqi_3"
8843   [(set (reg FLAGS_REG)
8844         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8845                          (match_operand:QI 2 "general_operand" "qim"))
8846                  (const_int 0)))
8847    (clobber (match_scratch:QI 0 "=q"))]
8848   "ix86_match_ccmode (insn, CCNOmode)
8849    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8850   "or{b}\t{%2, %0|%0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "mode" "QI")])
8853
8854 (define_insn "iorqi_ext_0"
8855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8856                          (const_int 8)
8857                          (const_int 8))
8858         (ior:SI 
8859           (zero_extract:SI
8860             (match_operand 1 "ext_register_operand" "0")
8861             (const_int 8)
8862             (const_int 8))
8863           (match_operand 2 "const_int_operand" "n")))
8864    (clobber (reg:CC FLAGS_REG))]
8865   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8866   "or{b}\t{%2, %h0|%h0, %2}"
8867   [(set_attr "type" "alu")
8868    (set_attr "length_immediate" "1")
8869    (set_attr "mode" "QI")])
8870
8871 (define_insn "*iorqi_ext_1"
8872   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8873                          (const_int 8)
8874                          (const_int 8))
8875         (ior:SI 
8876           (zero_extract:SI
8877             (match_operand 1 "ext_register_operand" "0")
8878             (const_int 8)
8879             (const_int 8))
8880           (zero_extend:SI
8881             (match_operand:QI 2 "general_operand" "Qm"))))
8882    (clobber (reg:CC FLAGS_REG))]
8883   "!TARGET_64BIT
8884    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8885   "or{b}\t{%2, %h0|%h0, %2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "length_immediate" "0")
8888    (set_attr "mode" "QI")])
8889
8890 (define_insn "*iorqi_ext_1_rex64"
8891   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8892                          (const_int 8)
8893                          (const_int 8))
8894         (ior:SI 
8895           (zero_extract:SI
8896             (match_operand 1 "ext_register_operand" "0")
8897             (const_int 8)
8898             (const_int 8))
8899           (zero_extend:SI
8900             (match_operand 2 "ext_register_operand" "Q"))))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "TARGET_64BIT
8903    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8904   "or{b}\t{%2, %h0|%h0, %2}"
8905   [(set_attr "type" "alu")
8906    (set_attr "length_immediate" "0")
8907    (set_attr "mode" "QI")])
8908
8909 (define_insn "*iorqi_ext_2"
8910   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8911                          (const_int 8)
8912                          (const_int 8))
8913         (ior:SI 
8914           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8915                            (const_int 8)
8916                            (const_int 8))
8917           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8918                            (const_int 8)
8919                            (const_int 8))))
8920    (clobber (reg:CC FLAGS_REG))]
8921   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8922   "ior{b}\t{%h2, %h0|%h0, %h2}"
8923   [(set_attr "type" "alu")
8924    (set_attr "length_immediate" "0")
8925    (set_attr "mode" "QI")])
8926
8927 (define_split
8928   [(set (match_operand 0 "register_operand" "")
8929         (ior (match_operand 1 "register_operand" "")
8930              (match_operand 2 "const_int_operand" "")))
8931    (clobber (reg:CC FLAGS_REG))]
8932    "reload_completed
8933     && QI_REG_P (operands[0])
8934     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8935     && !(INTVAL (operands[2]) & ~(255 << 8))
8936     && GET_MODE (operands[0]) != QImode"
8937   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8938                    (ior:SI (zero_extract:SI (match_dup 1)
8939                                             (const_int 8) (const_int 8))
8940                            (match_dup 2)))
8941               (clobber (reg:CC FLAGS_REG))])]
8942   "operands[0] = gen_lowpart (SImode, operands[0]);
8943    operands[1] = gen_lowpart (SImode, operands[1]);
8944    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8945
8946 ;; Since OR can be encoded with sign extended immediate, this is only
8947 ;; profitable when 7th bit is set.
8948 (define_split
8949   [(set (match_operand 0 "register_operand" "")
8950         (ior (match_operand 1 "general_operand" "")
8951              (match_operand 2 "const_int_operand" "")))
8952    (clobber (reg:CC FLAGS_REG))]
8953    "reload_completed
8954     && ANY_QI_REG_P (operands[0])
8955     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8956     && !(INTVAL (operands[2]) & ~255)
8957     && (INTVAL (operands[2]) & 128)
8958     && GET_MODE (operands[0]) != QImode"
8959   [(parallel [(set (strict_low_part (match_dup 0))
8960                    (ior:QI (match_dup 1)
8961                            (match_dup 2)))
8962               (clobber (reg:CC FLAGS_REG))])]
8963   "operands[0] = gen_lowpart (QImode, operands[0]);
8964    operands[1] = gen_lowpart (QImode, operands[1]);
8965    operands[2] = gen_lowpart (QImode, operands[2]);")
8966 \f
8967 ;; Logical XOR instructions
8968
8969 ;; %%% This used to optimize known byte-wide and operations to memory.
8970 ;; If this is considered useful, it should be done with splitters.
8971
8972 (define_expand "xordi3"
8973   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8974         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8975                 (match_operand:DI 2 "x86_64_general_operand" "")))
8976    (clobber (reg:CC FLAGS_REG))]
8977   "TARGET_64BIT"
8978   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8979
8980 (define_insn "*xordi_1_rex64"
8981   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8982         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8983                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8984    (clobber (reg:CC FLAGS_REG))]
8985   "TARGET_64BIT
8986    && ix86_binary_operator_ok (XOR, DImode, operands)"
8987   "@
8988    xor{q}\t{%2, %0|%0, %2}
8989    xor{q}\t{%2, %0|%0, %2}"
8990   [(set_attr "type" "alu")
8991    (set_attr "mode" "DI,DI")])
8992
8993 (define_insn "*xordi_2_rex64"
8994   [(set (reg FLAGS_REG)
8995         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8996                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8997                  (const_int 0)))
8998    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8999         (xor:DI (match_dup 1) (match_dup 2)))]
9000   "TARGET_64BIT
9001    && ix86_match_ccmode (insn, CCNOmode)
9002    && ix86_binary_operator_ok (XOR, DImode, operands)"
9003   "@
9004    xor{q}\t{%2, %0|%0, %2}
9005    xor{q}\t{%2, %0|%0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "mode" "DI,DI")])
9008
9009 (define_insn "*xordi_3_rex64"
9010   [(set (reg FLAGS_REG)
9011         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9012                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9013                  (const_int 0)))
9014    (clobber (match_scratch:DI 0 "=r"))]
9015   "TARGET_64BIT
9016    && ix86_match_ccmode (insn, CCNOmode)
9017    && ix86_binary_operator_ok (XOR, DImode, operands)"
9018   "xor{q}\t{%2, %0|%0, %2}"
9019   [(set_attr "type" "alu")
9020    (set_attr "mode" "DI")])
9021
9022 (define_expand "xorsi3"
9023   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9024         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9025                 (match_operand:SI 2 "general_operand" "")))
9026    (clobber (reg:CC FLAGS_REG))]
9027   ""
9028   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9029
9030 (define_insn "*xorsi_1"
9031   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9032         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9033                 (match_operand:SI 2 "general_operand" "ri,rm")))
9034    (clobber (reg:CC FLAGS_REG))]
9035   "ix86_binary_operator_ok (XOR, SImode, operands)"
9036   "xor{l}\t{%2, %0|%0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "mode" "SI")])
9039
9040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9041 ;; Add speccase for immediates
9042 (define_insn "*xorsi_1_zext"
9043   [(set (match_operand:DI 0 "register_operand" "=r")
9044         (zero_extend:DI
9045           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046                   (match_operand:SI 2 "general_operand" "rim"))))
9047    (clobber (reg:CC FLAGS_REG))]
9048   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9049   "xor{l}\t{%2, %k0|%k0, %2}"
9050   [(set_attr "type" "alu")
9051    (set_attr "mode" "SI")])
9052
9053 (define_insn "*xorsi_1_zext_imm"
9054   [(set (match_operand:DI 0 "register_operand" "=r")
9055         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9056                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9057    (clobber (reg:CC FLAGS_REG))]
9058   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9059   "xor{l}\t{%2, %k0|%k0, %2}"
9060   [(set_attr "type" "alu")
9061    (set_attr "mode" "SI")])
9062
9063 (define_insn "*xorsi_2"
9064   [(set (reg FLAGS_REG)
9065         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9066                          (match_operand:SI 2 "general_operand" "rim,ri"))
9067                  (const_int 0)))
9068    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9069         (xor:SI (match_dup 1) (match_dup 2)))]
9070   "ix86_match_ccmode (insn, CCNOmode)
9071    && ix86_binary_operator_ok (XOR, SImode, operands)"
9072   "xor{l}\t{%2, %0|%0, %2}"
9073   [(set_attr "type" "alu")
9074    (set_attr "mode" "SI")])
9075
9076 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9077 ;; ??? Special case for immediate operand is missing - it is tricky.
9078 (define_insn "*xorsi_2_zext"
9079   [(set (reg FLAGS_REG)
9080         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9081                          (match_operand:SI 2 "general_operand" "rim"))
9082                  (const_int 0)))
9083    (set (match_operand:DI 0 "register_operand" "=r")
9084         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9085   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9086    && ix86_binary_operator_ok (XOR, SImode, operands)"
9087   "xor{l}\t{%2, %k0|%k0, %2}"
9088   [(set_attr "type" "alu")
9089    (set_attr "mode" "SI")])
9090
9091 (define_insn "*xorsi_2_zext_imm"
9092   [(set (reg FLAGS_REG)
9093         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9094                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9095                  (const_int 0)))
9096    (set (match_operand:DI 0 "register_operand" "=r")
9097         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9098   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9099    && ix86_binary_operator_ok (XOR, SImode, operands)"
9100   "xor{l}\t{%2, %k0|%k0, %2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "mode" "SI")])
9103
9104 (define_insn "*xorsi_3"
9105   [(set (reg FLAGS_REG)
9106         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9107                          (match_operand:SI 2 "general_operand" "rim"))
9108                  (const_int 0)))
9109    (clobber (match_scratch:SI 0 "=r"))]
9110   "ix86_match_ccmode (insn, CCNOmode)
9111    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9112   "xor{l}\t{%2, %0|%0, %2}"
9113   [(set_attr "type" "alu")
9114    (set_attr "mode" "SI")])
9115
9116 (define_expand "xorhi3"
9117   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9118         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9119                 (match_operand:HI 2 "general_operand" "")))
9120    (clobber (reg:CC FLAGS_REG))]
9121   "TARGET_HIMODE_MATH"
9122   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9123
9124 (define_insn "*xorhi_1"
9125   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9126         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9127                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "ix86_binary_operator_ok (XOR, HImode, operands)"
9130   "xor{w}\t{%2, %0|%0, %2}"
9131   [(set_attr "type" "alu")
9132    (set_attr "mode" "HI")])
9133
9134 (define_insn "*xorhi_2"
9135   [(set (reg FLAGS_REG)
9136         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9137                          (match_operand:HI 2 "general_operand" "rim,ri"))
9138                  (const_int 0)))
9139    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9140         (xor:HI (match_dup 1) (match_dup 2)))]
9141   "ix86_match_ccmode (insn, CCNOmode)
9142    && ix86_binary_operator_ok (XOR, HImode, operands)"
9143   "xor{w}\t{%2, %0|%0, %2}"
9144   [(set_attr "type" "alu")
9145    (set_attr "mode" "HI")])
9146
9147 (define_insn "*xorhi_3"
9148   [(set (reg FLAGS_REG)
9149         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9150                          (match_operand:HI 2 "general_operand" "rim"))
9151                  (const_int 0)))
9152    (clobber (match_scratch:HI 0 "=r"))]
9153   "ix86_match_ccmode (insn, CCNOmode)
9154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9155   "xor{w}\t{%2, %0|%0, %2}"
9156   [(set_attr "type" "alu")
9157    (set_attr "mode" "HI")])
9158
9159 (define_expand "xorqi3"
9160   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9161         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9162                 (match_operand:QI 2 "general_operand" "")))
9163    (clobber (reg:CC FLAGS_REG))]
9164   "TARGET_QIMODE_MATH"
9165   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9166
9167 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9168 (define_insn "*xorqi_1"
9169   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9170         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9171                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9172    (clobber (reg:CC FLAGS_REG))]
9173   "ix86_binary_operator_ok (XOR, QImode, operands)"
9174   "@
9175    xor{b}\t{%2, %0|%0, %2}
9176    xor{b}\t{%2, %0|%0, %2}
9177    xor{l}\t{%k2, %k0|%k0, %k2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "mode" "QI,QI,SI")])
9180
9181 (define_insn "*xorqi_1_slp"
9182   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9183         (xor:QI (match_dup 0)
9184                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9187    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9188   "xor{b}\t{%1, %0|%0, %1}"
9189   [(set_attr "type" "alu1")
9190    (set_attr "mode" "QI")])
9191
9192 (define_insn "xorqi_ext_0"
9193   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9194                          (const_int 8)
9195                          (const_int 8))
9196         (xor:SI 
9197           (zero_extract:SI
9198             (match_operand 1 "ext_register_operand" "0")
9199             (const_int 8)
9200             (const_int 8))
9201           (match_operand 2 "const_int_operand" "n")))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9204   "xor{b}\t{%2, %h0|%h0, %2}"
9205   [(set_attr "type" "alu")
9206    (set_attr "length_immediate" "1")
9207    (set_attr "mode" "QI")])
9208
9209 (define_insn "*xorqi_ext_1"
9210   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9211                          (const_int 8)
9212                          (const_int 8))
9213         (xor:SI 
9214           (zero_extract:SI
9215             (match_operand 1 "ext_register_operand" "0")
9216             (const_int 8)
9217             (const_int 8))
9218           (zero_extend:SI
9219             (match_operand:QI 2 "general_operand" "Qm"))))
9220    (clobber (reg:CC FLAGS_REG))]
9221   "!TARGET_64BIT
9222    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9223   "xor{b}\t{%2, %h0|%h0, %2}"
9224   [(set_attr "type" "alu")
9225    (set_attr "length_immediate" "0")
9226    (set_attr "mode" "QI")])
9227
9228 (define_insn "*xorqi_ext_1_rex64"
9229   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9230                          (const_int 8)
9231                          (const_int 8))
9232         (xor:SI 
9233           (zero_extract:SI
9234             (match_operand 1 "ext_register_operand" "0")
9235             (const_int 8)
9236             (const_int 8))
9237           (zero_extend:SI
9238             (match_operand 2 "ext_register_operand" "Q"))))
9239    (clobber (reg:CC FLAGS_REG))]
9240   "TARGET_64BIT
9241    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9242   "xor{b}\t{%2, %h0|%h0, %2}"
9243   [(set_attr "type" "alu")
9244    (set_attr "length_immediate" "0")
9245    (set_attr "mode" "QI")])
9246
9247 (define_insn "*xorqi_ext_2"
9248   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9249                          (const_int 8)
9250                          (const_int 8))
9251         (xor:SI 
9252           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9253                            (const_int 8)
9254                            (const_int 8))
9255           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9256                            (const_int 8)
9257                            (const_int 8))))
9258    (clobber (reg:CC FLAGS_REG))]
9259   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9260   "xor{b}\t{%h2, %h0|%h0, %h2}"
9261   [(set_attr "type" "alu")
9262    (set_attr "length_immediate" "0")
9263    (set_attr "mode" "QI")])
9264
9265 (define_insn "*xorqi_cc_1"
9266   [(set (reg FLAGS_REG)
9267         (compare
9268           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9269                   (match_operand:QI 2 "general_operand" "qim,qi"))
9270           (const_int 0)))
9271    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9272         (xor:QI (match_dup 1) (match_dup 2)))]
9273   "ix86_match_ccmode (insn, CCNOmode)
9274    && ix86_binary_operator_ok (XOR, QImode, operands)"
9275   "xor{b}\t{%2, %0|%0, %2}"
9276   [(set_attr "type" "alu")
9277    (set_attr "mode" "QI")])
9278
9279 (define_insn "*xorqi_2_slp"
9280   [(set (reg FLAGS_REG)
9281         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9282                          (match_operand:QI 1 "general_operand" "qim,qi"))
9283                  (const_int 0)))
9284    (set (strict_low_part (match_dup 0))
9285         (xor:QI (match_dup 0) (match_dup 1)))]
9286   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9287    && ix86_match_ccmode (insn, CCNOmode)
9288    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9289   "xor{b}\t{%1, %0|%0, %1}"
9290   [(set_attr "type" "alu1")
9291    (set_attr "mode" "QI")])
9292
9293 (define_insn "*xorqi_cc_2"
9294   [(set (reg FLAGS_REG)
9295         (compare
9296           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9297                   (match_operand:QI 2 "general_operand" "qim"))
9298           (const_int 0)))
9299    (clobber (match_scratch:QI 0 "=q"))]
9300   "ix86_match_ccmode (insn, CCNOmode)
9301    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9302   "xor{b}\t{%2, %0|%0, %2}"
9303   [(set_attr "type" "alu")
9304    (set_attr "mode" "QI")])
9305
9306 (define_insn "*xorqi_cc_ext_1"
9307   [(set (reg FLAGS_REG)
9308         (compare
9309           (xor:SI
9310             (zero_extract:SI
9311               (match_operand 1 "ext_register_operand" "0")
9312               (const_int 8)
9313               (const_int 8))
9314             (match_operand:QI 2 "general_operand" "qmn"))
9315           (const_int 0)))
9316    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9317                          (const_int 8)
9318                          (const_int 8))
9319         (xor:SI 
9320           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9321           (match_dup 2)))]
9322   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9323   "xor{b}\t{%2, %h0|%h0, %2}"
9324   [(set_attr "type" "alu")
9325    (set_attr "mode" "QI")])
9326
9327 (define_insn "*xorqi_cc_ext_1_rex64"
9328   [(set (reg FLAGS_REG)
9329         (compare
9330           (xor:SI
9331             (zero_extract:SI
9332               (match_operand 1 "ext_register_operand" "0")
9333               (const_int 8)
9334               (const_int 8))
9335             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9336           (const_int 0)))
9337    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9338                          (const_int 8)
9339                          (const_int 8))
9340         (xor:SI 
9341           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9342           (match_dup 2)))]
9343   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9344   "xor{b}\t{%2, %h0|%h0, %2}"
9345   [(set_attr "type" "alu")
9346    (set_attr "mode" "QI")])
9347
9348 (define_expand "xorqi_cc_ext_1"
9349   [(parallel [
9350      (set (reg:CCNO FLAGS_REG)
9351           (compare:CCNO
9352             (xor:SI
9353               (zero_extract:SI
9354                 (match_operand 1 "ext_register_operand" "")
9355                 (const_int 8)
9356                 (const_int 8))
9357               (match_operand:QI 2 "general_operand" ""))
9358             (const_int 0)))
9359      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9360                            (const_int 8)
9361                            (const_int 8))
9362           (xor:SI 
9363             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9364             (match_dup 2)))])]
9365   ""
9366   "")
9367
9368 (define_split
9369   [(set (match_operand 0 "register_operand" "")
9370         (xor (match_operand 1 "register_operand" "")
9371              (match_operand 2 "const_int_operand" "")))
9372    (clobber (reg:CC FLAGS_REG))]
9373    "reload_completed
9374     && QI_REG_P (operands[0])
9375     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9376     && !(INTVAL (operands[2]) & ~(255 << 8))
9377     && GET_MODE (operands[0]) != QImode"
9378   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9379                    (xor:SI (zero_extract:SI (match_dup 1)
9380                                             (const_int 8) (const_int 8))
9381                            (match_dup 2)))
9382               (clobber (reg:CC FLAGS_REG))])]
9383   "operands[0] = gen_lowpart (SImode, operands[0]);
9384    operands[1] = gen_lowpart (SImode, operands[1]);
9385    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9386
9387 ;; Since XOR can be encoded with sign extended immediate, this is only
9388 ;; profitable when 7th bit is set.
9389 (define_split
9390   [(set (match_operand 0 "register_operand" "")
9391         (xor (match_operand 1 "general_operand" "")
9392              (match_operand 2 "const_int_operand" "")))
9393    (clobber (reg:CC FLAGS_REG))]
9394    "reload_completed
9395     && ANY_QI_REG_P (operands[0])
9396     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9397     && !(INTVAL (operands[2]) & ~255)
9398     && (INTVAL (operands[2]) & 128)
9399     && GET_MODE (operands[0]) != QImode"
9400   [(parallel [(set (strict_low_part (match_dup 0))
9401                    (xor:QI (match_dup 1)
9402                            (match_dup 2)))
9403               (clobber (reg:CC FLAGS_REG))])]
9404   "operands[0] = gen_lowpart (QImode, operands[0]);
9405    operands[1] = gen_lowpart (QImode, operands[1]);
9406    operands[2] = gen_lowpart (QImode, operands[2]);")
9407 \f
9408 ;; Negation instructions
9409
9410 (define_expand "negdi2"
9411   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9412                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9413               (clobber (reg:CC FLAGS_REG))])]
9414   ""
9415   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9416
9417 (define_insn "*negdi2_1"
9418   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9419         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9420    (clobber (reg:CC FLAGS_REG))]
9421   "!TARGET_64BIT
9422    && ix86_unary_operator_ok (NEG, DImode, operands)"
9423   "#")
9424
9425 (define_split
9426   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9427         (neg:DI (match_operand:DI 1 "general_operand" "")))
9428    (clobber (reg:CC FLAGS_REG))]
9429   "!TARGET_64BIT && reload_completed"
9430   [(parallel
9431     [(set (reg:CCZ FLAGS_REG)
9432           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9433      (set (match_dup 0) (neg:SI (match_dup 2)))])
9434    (parallel
9435     [(set (match_dup 1)
9436           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9437                             (match_dup 3))
9438                    (const_int 0)))
9439      (clobber (reg:CC FLAGS_REG))])
9440    (parallel
9441     [(set (match_dup 1)
9442           (neg:SI (match_dup 1)))
9443      (clobber (reg:CC FLAGS_REG))])]
9444   "split_di (operands+1, 1, operands+2, operands+3);
9445    split_di (operands+0, 1, operands+0, operands+1);")
9446
9447 (define_insn "*negdi2_1_rex64"
9448   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9449         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9450    (clobber (reg:CC FLAGS_REG))]
9451   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9452   "neg{q}\t%0"
9453   [(set_attr "type" "negnot")
9454    (set_attr "mode" "DI")])
9455
9456 ;; The problem with neg is that it does not perform (compare x 0),
9457 ;; it really performs (compare 0 x), which leaves us with the zero
9458 ;; flag being the only useful item.
9459
9460 (define_insn "*negdi2_cmpz_rex64"
9461   [(set (reg:CCZ FLAGS_REG)
9462         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9463                      (const_int 0)))
9464    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9465         (neg:DI (match_dup 1)))]
9466   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9467   "neg{q}\t%0"
9468   [(set_attr "type" "negnot")
9469    (set_attr "mode" "DI")])
9470
9471
9472 (define_expand "negsi2"
9473   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9474                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9475               (clobber (reg:CC FLAGS_REG))])]
9476   ""
9477   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9478
9479 (define_insn "*negsi2_1"
9480   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9481         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9482    (clobber (reg:CC FLAGS_REG))]
9483   "ix86_unary_operator_ok (NEG, SImode, operands)"
9484   "neg{l}\t%0"
9485   [(set_attr "type" "negnot")
9486    (set_attr "mode" "SI")])
9487
9488 ;; Combine is quite creative about this pattern.
9489 (define_insn "*negsi2_1_zext"
9490   [(set (match_operand:DI 0 "register_operand" "=r")
9491         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9492                                         (const_int 32)))
9493                      (const_int 32)))
9494    (clobber (reg:CC FLAGS_REG))]
9495   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9496   "neg{l}\t%k0"
9497   [(set_attr "type" "negnot")
9498    (set_attr "mode" "SI")])
9499
9500 ;; The problem with neg is that it does not perform (compare x 0),
9501 ;; it really performs (compare 0 x), which leaves us with the zero
9502 ;; flag being the only useful item.
9503
9504 (define_insn "*negsi2_cmpz"
9505   [(set (reg:CCZ FLAGS_REG)
9506         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9507                      (const_int 0)))
9508    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9509         (neg:SI (match_dup 1)))]
9510   "ix86_unary_operator_ok (NEG, SImode, operands)"
9511   "neg{l}\t%0"
9512   [(set_attr "type" "negnot")
9513    (set_attr "mode" "SI")])
9514
9515 (define_insn "*negsi2_cmpz_zext"
9516   [(set (reg:CCZ FLAGS_REG)
9517         (compare:CCZ (lshiftrt:DI
9518                        (neg:DI (ashift:DI
9519                                  (match_operand:DI 1 "register_operand" "0")
9520                                  (const_int 32)))
9521                        (const_int 32))
9522                      (const_int 0)))
9523    (set (match_operand:DI 0 "register_operand" "=r")
9524         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9525                                         (const_int 32)))
9526                      (const_int 32)))]
9527   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9528   "neg{l}\t%k0"
9529   [(set_attr "type" "negnot")
9530    (set_attr "mode" "SI")])
9531
9532 (define_expand "neghi2"
9533   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9534                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9535               (clobber (reg:CC FLAGS_REG))])]
9536   "TARGET_HIMODE_MATH"
9537   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9538
9539 (define_insn "*neghi2_1"
9540   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9541         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9542    (clobber (reg:CC FLAGS_REG))]
9543   "ix86_unary_operator_ok (NEG, HImode, operands)"
9544   "neg{w}\t%0"
9545   [(set_attr "type" "negnot")
9546    (set_attr "mode" "HI")])
9547
9548 (define_insn "*neghi2_cmpz"
9549   [(set (reg:CCZ FLAGS_REG)
9550         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9551                      (const_int 0)))
9552    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9553         (neg:HI (match_dup 1)))]
9554   "ix86_unary_operator_ok (NEG, HImode, operands)"
9555   "neg{w}\t%0"
9556   [(set_attr "type" "negnot")
9557    (set_attr "mode" "HI")])
9558
9559 (define_expand "negqi2"
9560   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9561                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9562               (clobber (reg:CC FLAGS_REG))])]
9563   "TARGET_QIMODE_MATH"
9564   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9565
9566 (define_insn "*negqi2_1"
9567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9568         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9569    (clobber (reg:CC FLAGS_REG))]
9570   "ix86_unary_operator_ok (NEG, QImode, operands)"
9571   "neg{b}\t%0"
9572   [(set_attr "type" "negnot")
9573    (set_attr "mode" "QI")])
9574
9575 (define_insn "*negqi2_cmpz"
9576   [(set (reg:CCZ FLAGS_REG)
9577         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9578                      (const_int 0)))
9579    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9580         (neg:QI (match_dup 1)))]
9581   "ix86_unary_operator_ok (NEG, QImode, operands)"
9582   "neg{b}\t%0"
9583   [(set_attr "type" "negnot")
9584    (set_attr "mode" "QI")])
9585
9586 ;; Changing of sign for FP values is doable using integer unit too.
9587
9588 (define_expand "negsf2"
9589   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9590         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9591   "TARGET_80387 || TARGET_SSE_MATH"
9592   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9593
9594 (define_expand "abssf2"
9595   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9596         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9597   "TARGET_80387 || TARGET_SSE_MATH"
9598   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9599
9600 (define_insn "*absnegsf2_mixed"
9601   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9602         (match_operator:SF 3 "absneg_operator"
9603           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9604    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9607    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9608   "#")
9609
9610 (define_insn "*absnegsf2_sse"
9611   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9612         (match_operator:SF 3 "absneg_operator"
9613           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9614    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9615    (clobber (reg:CC FLAGS_REG))]
9616   "TARGET_SSE_MATH
9617    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9618   "#")
9619
9620 (define_insn "*absnegsf2_i387"
9621   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9622         (match_operator:SF 3 "absneg_operator"
9623           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9624    (use (match_operand 2 "" ""))
9625    (clobber (reg:CC FLAGS_REG))]
9626   "TARGET_80387 && !TARGET_SSE_MATH
9627    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9628   "#")
9629
9630 (define_expand "negdf2"
9631   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9632         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9633   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9634   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9635
9636 (define_expand "absdf2"
9637   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9638         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9639   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9640   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9641
9642 (define_insn "*absnegdf2_mixed"
9643   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9644         (match_operator:DF 3 "absneg_operator"
9645           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9646    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9649    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9650   "#")
9651
9652 (define_insn "*absnegdf2_sse"
9653   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9654         (match_operator:DF 3 "absneg_operator"
9655           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9656    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9657    (clobber (reg:CC FLAGS_REG))]
9658   "TARGET_SSE2 && TARGET_SSE_MATH
9659    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9660   "#")
9661
9662 (define_insn "*absnegdf2_i387"
9663   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9664         (match_operator:DF 3 "absneg_operator"
9665           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9666    (use (match_operand 2 "" ""))
9667    (clobber (reg:CC FLAGS_REG))]
9668   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9669    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9670   "#")
9671
9672 (define_expand "negxf2"
9673   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9674         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9675   "TARGET_80387"
9676   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9677
9678 (define_expand "absxf2"
9679   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9680         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9681   "TARGET_80387"
9682   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9683
9684 (define_insn "*absnegxf2_i387"
9685   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9686         (match_operator:XF 3 "absneg_operator"
9687           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9688    (use (match_operand 2 "" ""))
9689    (clobber (reg:CC FLAGS_REG))]
9690   "TARGET_80387
9691    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9692   "#")
9693
9694 ;; Splitters for fp abs and neg.
9695
9696 (define_split
9697   [(set (match_operand 0 "fp_register_operand" "")
9698         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9699    (use (match_operand 2 "" ""))
9700    (clobber (reg:CC FLAGS_REG))]
9701   "reload_completed"
9702   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9703
9704 (define_split
9705   [(set (match_operand 0 "register_operand" "")
9706         (match_operator 3 "absneg_operator"
9707           [(match_operand 1 "register_operand" "")]))
9708    (use (match_operand 2 "nonimmediate_operand" ""))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "reload_completed && SSE_REG_P (operands[0])"
9711   [(set (match_dup 0) (match_dup 3))]
9712 {
9713   enum machine_mode mode = GET_MODE (operands[0]);
9714   enum machine_mode vmode = GET_MODE (operands[2]);
9715   rtx tmp;
9716   
9717   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9718   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9719   if (operands_match_p (operands[0], operands[2]))
9720     {
9721       tmp = operands[1];
9722       operands[1] = operands[2];
9723       operands[2] = tmp;
9724     }
9725   if (GET_CODE (operands[3]) == ABS)
9726     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9727   else
9728     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9729   operands[3] = tmp;
9730 })
9731
9732 (define_split
9733   [(set (match_operand:SF 0 "register_operand" "")
9734         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9735    (use (match_operand:V4SF 2 "" ""))
9736    (clobber (reg:CC FLAGS_REG))]
9737   "reload_completed"
9738   [(parallel [(set (match_dup 0) (match_dup 1))
9739               (clobber (reg:CC FLAGS_REG))])]
9740
9741   rtx tmp;
9742   operands[0] = gen_lowpart (SImode, operands[0]);
9743   if (GET_CODE (operands[1]) == ABS)
9744     {
9745       tmp = gen_int_mode (0x7fffffff, SImode);
9746       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9747     }
9748   else
9749     {
9750       tmp = gen_int_mode (0x80000000, SImode);
9751       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9752     }
9753   operands[1] = tmp;
9754 })
9755
9756 (define_split
9757   [(set (match_operand:DF 0 "register_operand" "")
9758         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9759    (use (match_operand 2 "" ""))
9760    (clobber (reg:CC FLAGS_REG))]
9761   "reload_completed"
9762   [(parallel [(set (match_dup 0) (match_dup 1))
9763               (clobber (reg:CC FLAGS_REG))])]
9764 {
9765   rtx tmp;
9766   if (TARGET_64BIT)
9767     {
9768       tmp = gen_lowpart (DImode, operands[0]);
9769       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9770       operands[0] = tmp;
9771
9772       if (GET_CODE (operands[1]) == ABS)
9773         tmp = const0_rtx;
9774       else
9775         tmp = gen_rtx_NOT (DImode, tmp);
9776     }
9777   else
9778     {
9779       operands[0] = gen_highpart (SImode, operands[0]);
9780       if (GET_CODE (operands[1]) == ABS)
9781         {
9782           tmp = gen_int_mode (0x7fffffff, SImode);
9783           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9784         }
9785       else
9786         {
9787           tmp = gen_int_mode (0x80000000, SImode);
9788           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9789         }
9790     }
9791   operands[1] = tmp;
9792 })
9793
9794 (define_split
9795   [(set (match_operand:XF 0 "register_operand" "")
9796         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9797    (use (match_operand 2 "" ""))
9798    (clobber (reg:CC FLAGS_REG))]
9799   "reload_completed"
9800   [(parallel [(set (match_dup 0) (match_dup 1))
9801               (clobber (reg:CC FLAGS_REG))])]
9802 {
9803   rtx tmp;
9804   operands[0] = gen_rtx_REG (SImode,
9805                              true_regnum (operands[0])
9806                              + (TARGET_64BIT ? 1 : 2));
9807   if (GET_CODE (operands[1]) == ABS)
9808     {
9809       tmp = GEN_INT (0x7fff);
9810       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9811     }
9812   else
9813     {
9814       tmp = GEN_INT (0x8000);
9815       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9816     }
9817   operands[1] = tmp;
9818 })
9819
9820 (define_split
9821   [(set (match_operand 0 "memory_operand" "")
9822         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9823    (use (match_operand 2 "" ""))
9824    (clobber (reg:CC FLAGS_REG))]
9825   "reload_completed"
9826   [(parallel [(set (match_dup 0) (match_dup 1))
9827               (clobber (reg:CC FLAGS_REG))])]
9828 {
9829   enum machine_mode mode = GET_MODE (operands[0]);
9830   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9831   rtx tmp;
9832
9833   operands[0] = adjust_address (operands[0], QImode, size - 1);
9834   if (GET_CODE (operands[1]) == ABS)
9835     {
9836       tmp = gen_int_mode (0x7f, QImode);
9837       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9838     }
9839   else
9840     {
9841       tmp = gen_int_mode (0x80, QImode);
9842       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9843     }
9844   operands[1] = tmp;
9845 })
9846
9847 ;; Conditionalize these after reload. If they match before reload, we 
9848 ;; lose the clobber and ability to use integer instructions.
9849
9850 (define_insn "*negsf2_1"
9851   [(set (match_operand:SF 0 "register_operand" "=f")
9852         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9853   "TARGET_80387 && reload_completed"
9854   "fchs"
9855   [(set_attr "type" "fsgn")
9856    (set_attr "mode" "SF")])
9857
9858 (define_insn "*negdf2_1"
9859   [(set (match_operand:DF 0 "register_operand" "=f")
9860         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9861   "TARGET_80387 && reload_completed"
9862   "fchs"
9863   [(set_attr "type" "fsgn")
9864    (set_attr "mode" "DF")])
9865
9866 (define_insn "*negxf2_1"
9867   [(set (match_operand:XF 0 "register_operand" "=f")
9868         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9869   "TARGET_80387 && reload_completed"
9870   "fchs"
9871   [(set_attr "type" "fsgn")
9872    (set_attr "mode" "XF")])
9873
9874 (define_insn "*abssf2_1"
9875   [(set (match_operand:SF 0 "register_operand" "=f")
9876         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9877   "TARGET_80387 && reload_completed"
9878   "fabs"
9879   [(set_attr "type" "fsgn")
9880    (set_attr "mode" "SF")])
9881
9882 (define_insn "*absdf2_1"
9883   [(set (match_operand:DF 0 "register_operand" "=f")
9884         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9885   "TARGET_80387 && reload_completed"
9886   "fabs"
9887   [(set_attr "type" "fsgn")
9888    (set_attr "mode" "DF")])
9889
9890 (define_insn "*absxf2_1"
9891   [(set (match_operand:XF 0 "register_operand" "=f")
9892         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9893   "TARGET_80387 && reload_completed"
9894   "fabs"
9895   [(set_attr "type" "fsgn")
9896    (set_attr "mode" "DF")])
9897
9898 (define_insn "*negextendsfdf2"
9899   [(set (match_operand:DF 0 "register_operand" "=f")
9900         (neg:DF (float_extend:DF
9901                   (match_operand:SF 1 "register_operand" "0"))))]
9902   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9903   "fchs"
9904   [(set_attr "type" "fsgn")
9905    (set_attr "mode" "DF")])
9906
9907 (define_insn "*negextenddfxf2"
9908   [(set (match_operand:XF 0 "register_operand" "=f")
9909         (neg:XF (float_extend:XF
9910                   (match_operand:DF 1 "register_operand" "0"))))]
9911   "TARGET_80387"
9912   "fchs"
9913   [(set_attr "type" "fsgn")
9914    (set_attr "mode" "XF")])
9915
9916 (define_insn "*negextendsfxf2"
9917   [(set (match_operand:XF 0 "register_operand" "=f")
9918         (neg:XF (float_extend:XF
9919                   (match_operand:SF 1 "register_operand" "0"))))]
9920   "TARGET_80387"
9921   "fchs"
9922   [(set_attr "type" "fsgn")
9923    (set_attr "mode" "XF")])
9924
9925 (define_insn "*absextendsfdf2"
9926   [(set (match_operand:DF 0 "register_operand" "=f")
9927         (abs:DF (float_extend:DF
9928                   (match_operand:SF 1 "register_operand" "0"))))]
9929   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9930   "fabs"
9931   [(set_attr "type" "fsgn")
9932    (set_attr "mode" "DF")])
9933
9934 (define_insn "*absextenddfxf2"
9935   [(set (match_operand:XF 0 "register_operand" "=f")
9936         (abs:XF (float_extend:XF
9937           (match_operand:DF 1 "register_operand" "0"))))]
9938   "TARGET_80387"
9939   "fabs"
9940   [(set_attr "type" "fsgn")
9941    (set_attr "mode" "XF")])
9942
9943 (define_insn "*absextendsfxf2"
9944   [(set (match_operand:XF 0 "register_operand" "=f")
9945         (abs:XF (float_extend:XF
9946           (match_operand:SF 1 "register_operand" "0"))))]
9947   "TARGET_80387"
9948   "fabs"
9949   [(set_attr "type" "fsgn")
9950    (set_attr "mode" "XF")])
9951 \f
9952 ;; One complement instructions
9953
9954 (define_expand "one_cmpldi2"
9955   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9956         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9957   "TARGET_64BIT"
9958   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9959
9960 (define_insn "*one_cmpldi2_1_rex64"
9961   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9962         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9963   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9964   "not{q}\t%0"
9965   [(set_attr "type" "negnot")
9966    (set_attr "mode" "DI")])
9967
9968 (define_insn "*one_cmpldi2_2_rex64"
9969   [(set (reg FLAGS_REG)
9970         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9971                  (const_int 0)))
9972    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9973         (not:DI (match_dup 1)))]
9974   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9975    && ix86_unary_operator_ok (NOT, DImode, operands)"
9976   "#"
9977   [(set_attr "type" "alu1")
9978    (set_attr "mode" "DI")])
9979
9980 (define_split
9981   [(set (match_operand 0 "flags_reg_operand" "")
9982         (match_operator 2 "compare_operator"
9983           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9984            (const_int 0)]))
9985    (set (match_operand:DI 1 "nonimmediate_operand" "")
9986         (not:DI (match_dup 3)))]
9987   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9988   [(parallel [(set (match_dup 0)
9989                    (match_op_dup 2
9990                      [(xor:DI (match_dup 3) (const_int -1))
9991                       (const_int 0)]))
9992               (set (match_dup 1)
9993                    (xor:DI (match_dup 3) (const_int -1)))])]
9994   "")
9995
9996 (define_expand "one_cmplsi2"
9997   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9998         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9999   ""
10000   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10001
10002 (define_insn "*one_cmplsi2_1"
10003   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10004         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10005   "ix86_unary_operator_ok (NOT, SImode, operands)"
10006   "not{l}\t%0"
10007   [(set_attr "type" "negnot")
10008    (set_attr "mode" "SI")])
10009
10010 ;; ??? Currently never generated - xor is used instead.
10011 (define_insn "*one_cmplsi2_1_zext"
10012   [(set (match_operand:DI 0 "register_operand" "=r")
10013         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10014   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10015   "not{l}\t%k0"
10016   [(set_attr "type" "negnot")
10017    (set_attr "mode" "SI")])
10018
10019 (define_insn "*one_cmplsi2_2"
10020   [(set (reg FLAGS_REG)
10021         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10022                  (const_int 0)))
10023    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024         (not:SI (match_dup 1)))]
10025   "ix86_match_ccmode (insn, CCNOmode)
10026    && ix86_unary_operator_ok (NOT, SImode, operands)"
10027   "#"
10028   [(set_attr "type" "alu1")
10029    (set_attr "mode" "SI")])
10030
10031 (define_split
10032   [(set (match_operand 0 "flags_reg_operand" "")
10033         (match_operator 2 "compare_operator"
10034           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10035            (const_int 0)]))
10036    (set (match_operand:SI 1 "nonimmediate_operand" "")
10037         (not:SI (match_dup 3)))]
10038   "ix86_match_ccmode (insn, CCNOmode)"
10039   [(parallel [(set (match_dup 0)
10040                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10041                                     (const_int 0)]))
10042               (set (match_dup 1)
10043                    (xor:SI (match_dup 3) (const_int -1)))])]
10044   "")
10045
10046 ;; ??? Currently never generated - xor is used instead.
10047 (define_insn "*one_cmplsi2_2_zext"
10048   [(set (reg FLAGS_REG)
10049         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10050                  (const_int 0)))
10051    (set (match_operand:DI 0 "register_operand" "=r")
10052         (zero_extend:DI (not:SI (match_dup 1))))]
10053   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10054    && ix86_unary_operator_ok (NOT, SImode, operands)"
10055   "#"
10056   [(set_attr "type" "alu1")
10057    (set_attr "mode" "SI")])
10058
10059 (define_split
10060   [(set (match_operand 0 "flags_reg_operand" "")
10061         (match_operator 2 "compare_operator"
10062           [(not:SI (match_operand:SI 3 "register_operand" ""))
10063            (const_int 0)]))
10064    (set (match_operand:DI 1 "register_operand" "")
10065         (zero_extend:DI (not:SI (match_dup 3))))]
10066   "ix86_match_ccmode (insn, CCNOmode)"
10067   [(parallel [(set (match_dup 0)
10068                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10069                                     (const_int 0)]))
10070               (set (match_dup 1)
10071                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10072   "")
10073
10074 (define_expand "one_cmplhi2"
10075   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10076         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10077   "TARGET_HIMODE_MATH"
10078   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10079
10080 (define_insn "*one_cmplhi2_1"
10081   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10082         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10083   "ix86_unary_operator_ok (NOT, HImode, operands)"
10084   "not{w}\t%0"
10085   [(set_attr "type" "negnot")
10086    (set_attr "mode" "HI")])
10087
10088 (define_insn "*one_cmplhi2_2"
10089   [(set (reg FLAGS_REG)
10090         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10091                  (const_int 0)))
10092    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10093         (not:HI (match_dup 1)))]
10094   "ix86_match_ccmode (insn, CCNOmode)
10095    && ix86_unary_operator_ok (NEG, HImode, operands)"
10096   "#"
10097   [(set_attr "type" "alu1")
10098    (set_attr "mode" "HI")])
10099
10100 (define_split
10101   [(set (match_operand 0 "flags_reg_operand" "")
10102         (match_operator 2 "compare_operator"
10103           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10104            (const_int 0)]))
10105    (set (match_operand:HI 1 "nonimmediate_operand" "")
10106         (not:HI (match_dup 3)))]
10107   "ix86_match_ccmode (insn, CCNOmode)"
10108   [(parallel [(set (match_dup 0)
10109                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10110                                     (const_int 0)]))
10111               (set (match_dup 1)
10112                    (xor:HI (match_dup 3) (const_int -1)))])]
10113   "")
10114
10115 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10116 (define_expand "one_cmplqi2"
10117   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10118         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10119   "TARGET_QIMODE_MATH"
10120   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10121
10122 (define_insn "*one_cmplqi2_1"
10123   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10124         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10125   "ix86_unary_operator_ok (NOT, QImode, operands)"
10126   "@
10127    not{b}\t%0
10128    not{l}\t%k0"
10129   [(set_attr "type" "negnot")
10130    (set_attr "mode" "QI,SI")])
10131
10132 (define_insn "*one_cmplqi2_2"
10133   [(set (reg FLAGS_REG)
10134         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10135                  (const_int 0)))
10136    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10137         (not:QI (match_dup 1)))]
10138   "ix86_match_ccmode (insn, CCNOmode)
10139    && ix86_unary_operator_ok (NOT, QImode, operands)"
10140   "#"
10141   [(set_attr "type" "alu1")
10142    (set_attr "mode" "QI")])
10143
10144 (define_split
10145   [(set (match_operand 0 "flags_reg_operand" "")
10146         (match_operator 2 "compare_operator"
10147           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10148            (const_int 0)]))
10149    (set (match_operand:QI 1 "nonimmediate_operand" "")
10150         (not:QI (match_dup 3)))]
10151   "ix86_match_ccmode (insn, CCNOmode)"
10152   [(parallel [(set (match_dup 0)
10153                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10154                                     (const_int 0)]))
10155               (set (match_dup 1)
10156                    (xor:QI (match_dup 3) (const_int -1)))])]
10157   "")
10158 \f
10159 ;; Arithmetic shift instructions
10160
10161 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10162 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10163 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10164 ;; from the assembler input.
10165 ;;
10166 ;; This instruction shifts the target reg/mem as usual, but instead of
10167 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10168 ;; is a left shift double, bits are taken from the high order bits of
10169 ;; reg, else if the insn is a shift right double, bits are taken from the
10170 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10171 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10172 ;;
10173 ;; Since sh[lr]d does not change the `reg' operand, that is done
10174 ;; separately, making all shifts emit pairs of shift double and normal
10175 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10176 ;; support a 63 bit shift, each shift where the count is in a reg expands
10177 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10178 ;;
10179 ;; If the shift count is a constant, we need never emit more than one
10180 ;; shift pair, instead using moves and sign extension for counts greater
10181 ;; than 31.
10182
10183 (define_expand "ashldi3"
10184   [(set (match_operand:DI 0 "shiftdi_operand" "")
10185         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10186                    (match_operand:QI 2 "nonmemory_operand" "")))]
10187   ""
10188   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10189
10190 (define_insn "*ashldi3_1_rex64"
10191   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10192         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10193                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10194    (clobber (reg:CC FLAGS_REG))]
10195   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10196 {
10197   switch (get_attr_type (insn))
10198     {
10199     case TYPE_ALU:
10200       if (operands[2] != const1_rtx)
10201         abort ();
10202       if (!rtx_equal_p (operands[0], operands[1]))
10203         abort ();
10204       return "add{q}\t{%0, %0|%0, %0}";
10205
10206     case TYPE_LEA:
10207       if (GET_CODE (operands[2]) != CONST_INT
10208           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10209         abort ();
10210       operands[1] = gen_rtx_MULT (DImode, operands[1],
10211                                   GEN_INT (1 << INTVAL (operands[2])));
10212       return "lea{q}\t{%a1, %0|%0, %a1}";
10213
10214     default:
10215       if (REG_P (operands[2]))
10216         return "sal{q}\t{%b2, %0|%0, %b2}";
10217       else if (operands[2] == const1_rtx
10218                && (TARGET_SHIFT1 || optimize_size))
10219         return "sal{q}\t%0";
10220       else
10221         return "sal{q}\t{%2, %0|%0, %2}";
10222     }
10223 }
10224   [(set (attr "type")
10225      (cond [(eq_attr "alternative" "1")
10226               (const_string "lea")
10227             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10228                           (const_int 0))
10229                       (match_operand 0 "register_operand" ""))
10230                  (match_operand 2 "const1_operand" ""))
10231               (const_string "alu")
10232            ]
10233            (const_string "ishift")))
10234    (set_attr "mode" "DI")])
10235
10236 ;; Convert lea to the lea pattern to avoid flags dependency.
10237 (define_split
10238   [(set (match_operand:DI 0 "register_operand" "")
10239         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10240                    (match_operand:QI 2 "immediate_operand" "")))
10241    (clobber (reg:CC FLAGS_REG))]
10242   "TARGET_64BIT && reload_completed
10243    && true_regnum (operands[0]) != true_regnum (operands[1])"
10244   [(set (match_dup 0)
10245         (mult:DI (match_dup 1)
10246                  (match_dup 2)))]
10247   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10248
10249 ;; This pattern can't accept a variable shift count, since shifts by
10250 ;; zero don't affect the flags.  We assume that shifts by constant
10251 ;; zero are optimized away.
10252 (define_insn "*ashldi3_cmp_rex64"
10253   [(set (reg FLAGS_REG)
10254         (compare
10255           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10256                      (match_operand:QI 2 "immediate_operand" "e"))
10257           (const_int 0)))
10258    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10259         (ashift:DI (match_dup 1) (match_dup 2)))]
10260   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10261    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10262 {
10263   switch (get_attr_type (insn))
10264     {
10265     case TYPE_ALU:
10266       if (operands[2] != const1_rtx)
10267         abort ();
10268       return "add{q}\t{%0, %0|%0, %0}";
10269
10270     default:
10271       if (REG_P (operands[2]))
10272         return "sal{q}\t{%b2, %0|%0, %b2}";
10273       else if (operands[2] == const1_rtx
10274                && (TARGET_SHIFT1 || optimize_size))
10275         return "sal{q}\t%0";
10276       else
10277         return "sal{q}\t{%2, %0|%0, %2}";
10278     }
10279 }
10280   [(set (attr "type")
10281      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10282                           (const_int 0))
10283                       (match_operand 0 "register_operand" ""))
10284                  (match_operand 2 "const1_operand" ""))
10285               (const_string "alu")
10286            ]
10287            (const_string "ishift")))
10288    (set_attr "mode" "DI")])
10289
10290 (define_insn "*ashldi3_1"
10291   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10292         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10293                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10294    (clobber (reg:CC FLAGS_REG))]
10295   "!TARGET_64BIT"
10296   "#"
10297   [(set_attr "type" "multi")])
10298
10299 ;; By default we don't ask for a scratch register, because when DImode
10300 ;; values are manipulated, registers are already at a premium.  But if
10301 ;; we have one handy, we won't turn it away.
10302 (define_peephole2
10303   [(match_scratch:SI 3 "r")
10304    (parallel [(set (match_operand:DI 0 "register_operand" "")
10305                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10306                               (match_operand:QI 2 "nonmemory_operand" "")))
10307               (clobber (reg:CC FLAGS_REG))])
10308    (match_dup 3)]
10309   "!TARGET_64BIT && TARGET_CMOVE"
10310   [(const_int 0)]
10311   "ix86_split_ashldi (operands, operands[3]); DONE;")
10312
10313 (define_split
10314   [(set (match_operand:DI 0 "register_operand" "")
10315         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10316                    (match_operand:QI 2 "nonmemory_operand" "")))
10317    (clobber (reg:CC FLAGS_REG))]
10318   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10319   [(const_int 0)]
10320   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10321
10322 (define_insn "x86_shld_1"
10323   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10324         (ior:SI (ashift:SI (match_dup 0)
10325                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10326                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10327                   (minus:QI (const_int 32) (match_dup 2)))))
10328    (clobber (reg:CC FLAGS_REG))]
10329   ""
10330   "@
10331    shld{l}\t{%2, %1, %0|%0, %1, %2}
10332    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10333   [(set_attr "type" "ishift")
10334    (set_attr "prefix_0f" "1")
10335    (set_attr "mode" "SI")
10336    (set_attr "pent_pair" "np")
10337    (set_attr "athlon_decode" "vector")])
10338
10339 (define_expand "x86_shift_adj_1"
10340   [(set (reg:CCZ FLAGS_REG)
10341         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10342                              (const_int 32))
10343                      (const_int 0)))
10344    (set (match_operand:SI 0 "register_operand" "")
10345         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10346                          (match_operand:SI 1 "register_operand" "")
10347                          (match_dup 0)))
10348    (set (match_dup 1)
10349         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10350                          (match_operand:SI 3 "register_operand" "r")
10351                          (match_dup 1)))]
10352   "TARGET_CMOVE"
10353   "")
10354
10355 (define_expand "x86_shift_adj_2"
10356   [(use (match_operand:SI 0 "register_operand" ""))
10357    (use (match_operand:SI 1 "register_operand" ""))
10358    (use (match_operand:QI 2 "register_operand" ""))]
10359   ""
10360 {
10361   rtx label = gen_label_rtx ();
10362   rtx tmp;
10363
10364   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10365
10366   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10367   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10368   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10369                               gen_rtx_LABEL_REF (VOIDmode, label),
10370                               pc_rtx);
10371   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10372   JUMP_LABEL (tmp) = label;
10373
10374   emit_move_insn (operands[0], operands[1]);
10375   ix86_expand_clear (operands[1]);
10376
10377   emit_label (label);
10378   LABEL_NUSES (label) = 1;
10379
10380   DONE;
10381 })
10382
10383 (define_expand "ashlsi3"
10384   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10385         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10386                    (match_operand:QI 2 "nonmemory_operand" "")))
10387    (clobber (reg:CC FLAGS_REG))]
10388   ""
10389   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10390
10391 (define_insn "*ashlsi3_1"
10392   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10393         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10394                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10395    (clobber (reg:CC FLAGS_REG))]
10396   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10397 {
10398   switch (get_attr_type (insn))
10399     {
10400     case TYPE_ALU:
10401       if (operands[2] != const1_rtx)
10402         abort ();
10403       if (!rtx_equal_p (operands[0], operands[1]))
10404         abort ();
10405       return "add{l}\t{%0, %0|%0, %0}";
10406
10407     case TYPE_LEA:
10408       return "#";
10409
10410     default:
10411       if (REG_P (operands[2]))
10412         return "sal{l}\t{%b2, %0|%0, %b2}";
10413       else if (operands[2] == const1_rtx
10414                && (TARGET_SHIFT1 || optimize_size))
10415         return "sal{l}\t%0";
10416       else
10417         return "sal{l}\t{%2, %0|%0, %2}";
10418     }
10419 }
10420   [(set (attr "type")
10421      (cond [(eq_attr "alternative" "1")
10422               (const_string "lea")
10423             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10424                           (const_int 0))
10425                       (match_operand 0 "register_operand" ""))
10426                  (match_operand 2 "const1_operand" ""))
10427               (const_string "alu")
10428            ]
10429            (const_string "ishift")))
10430    (set_attr "mode" "SI")])
10431
10432 ;; Convert lea to the lea pattern to avoid flags dependency.
10433 (define_split
10434   [(set (match_operand 0 "register_operand" "")
10435         (ashift (match_operand 1 "index_register_operand" "")
10436                 (match_operand:QI 2 "const_int_operand" "")))
10437    (clobber (reg:CC FLAGS_REG))]
10438   "reload_completed
10439    && true_regnum (operands[0]) != true_regnum (operands[1])
10440    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10441   [(const_int 0)]
10442 {
10443   rtx pat;
10444   enum machine_mode mode = GET_MODE (operands[0]);
10445
10446   if (GET_MODE_SIZE (mode) < 4)
10447     operands[0] = gen_lowpart (SImode, operands[0]);
10448   if (mode != Pmode)
10449     operands[1] = gen_lowpart (Pmode, operands[1]);
10450   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10451
10452   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10453   if (Pmode != SImode)
10454     pat = gen_rtx_SUBREG (SImode, pat, 0);
10455   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10456   DONE;
10457 })
10458
10459 ;; Rare case of shifting RSP is handled by generating move and shift
10460 (define_split
10461   [(set (match_operand 0 "register_operand" "")
10462         (ashift (match_operand 1 "register_operand" "")
10463                 (match_operand:QI 2 "const_int_operand" "")))
10464    (clobber (reg:CC FLAGS_REG))]
10465   "reload_completed
10466    && true_regnum (operands[0]) != true_regnum (operands[1])"
10467   [(const_int 0)]
10468 {
10469   rtx pat, clob;
10470   emit_move_insn (operands[1], operands[0]);
10471   pat = gen_rtx_SET (VOIDmode, operands[0],
10472                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10473                                      operands[0], operands[2]));
10474   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10475   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10476   DONE;
10477 })
10478
10479 (define_insn "*ashlsi3_1_zext"
10480   [(set (match_operand:DI 0 "register_operand" "=r,r")
10481         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10482                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10483    (clobber (reg:CC FLAGS_REG))]
10484   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10485 {
10486   switch (get_attr_type (insn))
10487     {
10488     case TYPE_ALU:
10489       if (operands[2] != const1_rtx)
10490         abort ();
10491       return "add{l}\t{%k0, %k0|%k0, %k0}";
10492
10493     case TYPE_LEA:
10494       return "#";
10495
10496     default:
10497       if (REG_P (operands[2]))
10498         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10499       else if (operands[2] == const1_rtx
10500                && (TARGET_SHIFT1 || optimize_size))
10501         return "sal{l}\t%k0";
10502       else
10503         return "sal{l}\t{%2, %k0|%k0, %2}";
10504     }
10505 }
10506   [(set (attr "type")
10507      (cond [(eq_attr "alternative" "1")
10508               (const_string "lea")
10509             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10510                      (const_int 0))
10511                  (match_operand 2 "const1_operand" ""))
10512               (const_string "alu")
10513            ]
10514            (const_string "ishift")))
10515    (set_attr "mode" "SI")])
10516
10517 ;; Convert lea to the lea pattern to avoid flags dependency.
10518 (define_split
10519   [(set (match_operand:DI 0 "register_operand" "")
10520         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10521                                 (match_operand:QI 2 "const_int_operand" ""))))
10522    (clobber (reg:CC FLAGS_REG))]
10523   "TARGET_64BIT && reload_completed
10524    && true_regnum (operands[0]) != true_regnum (operands[1])"
10525   [(set (match_dup 0) (zero_extend:DI
10526                         (subreg:SI (mult:SI (match_dup 1)
10527                                             (match_dup 2)) 0)))]
10528 {
10529   operands[1] = gen_lowpart (Pmode, operands[1]);
10530   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10531 })
10532
10533 ;; This pattern can't accept a variable shift count, since shifts by
10534 ;; zero don't affect the flags.  We assume that shifts by constant
10535 ;; zero are optimized away.
10536 (define_insn "*ashlsi3_cmp"
10537   [(set (reg FLAGS_REG)
10538         (compare
10539           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10540                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10541           (const_int 0)))
10542    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10543         (ashift:SI (match_dup 1) (match_dup 2)))]
10544   "ix86_match_ccmode (insn, CCGOCmode)
10545    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10546 {
10547   switch (get_attr_type (insn))
10548     {
10549     case TYPE_ALU:
10550       if (operands[2] != const1_rtx)
10551         abort ();
10552       return "add{l}\t{%0, %0|%0, %0}";
10553
10554     default:
10555       if (REG_P (operands[2]))
10556         return "sal{l}\t{%b2, %0|%0, %b2}";
10557       else if (operands[2] == const1_rtx
10558                && (TARGET_SHIFT1 || optimize_size))
10559         return "sal{l}\t%0";
10560       else
10561         return "sal{l}\t{%2, %0|%0, %2}";
10562     }
10563 }
10564   [(set (attr "type")
10565      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10566                           (const_int 0))
10567                       (match_operand 0 "register_operand" ""))
10568                  (match_operand 2 "const1_operand" ""))
10569               (const_string "alu")
10570            ]
10571            (const_string "ishift")))
10572    (set_attr "mode" "SI")])
10573
10574 (define_insn "*ashlsi3_cmp_zext"
10575   [(set (reg FLAGS_REG)
10576         (compare
10577           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10578                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10579           (const_int 0)))
10580    (set (match_operand:DI 0 "register_operand" "=r")
10581         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10582   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10583    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10584 {
10585   switch (get_attr_type (insn))
10586     {
10587     case TYPE_ALU:
10588       if (operands[2] != const1_rtx)
10589         abort ();
10590       return "add{l}\t{%k0, %k0|%k0, %k0}";
10591
10592     default:
10593       if (REG_P (operands[2]))
10594         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10595       else if (operands[2] == const1_rtx
10596                && (TARGET_SHIFT1 || optimize_size))
10597         return "sal{l}\t%k0";
10598       else
10599         return "sal{l}\t{%2, %k0|%k0, %2}";
10600     }
10601 }
10602   [(set (attr "type")
10603      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10604                      (const_int 0))
10605                  (match_operand 2 "const1_operand" ""))
10606               (const_string "alu")
10607            ]
10608            (const_string "ishift")))
10609    (set_attr "mode" "SI")])
10610
10611 (define_expand "ashlhi3"
10612   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10613         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10614                    (match_operand:QI 2 "nonmemory_operand" "")))
10615    (clobber (reg:CC FLAGS_REG))]
10616   "TARGET_HIMODE_MATH"
10617   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10618
10619 (define_insn "*ashlhi3_1_lea"
10620   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10621         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10622                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "!TARGET_PARTIAL_REG_STALL
10625    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10626 {
10627   switch (get_attr_type (insn))
10628     {
10629     case TYPE_LEA:
10630       return "#";
10631     case TYPE_ALU:
10632       if (operands[2] != const1_rtx)
10633         abort ();
10634       return "add{w}\t{%0, %0|%0, %0}";
10635
10636     default:
10637       if (REG_P (operands[2]))
10638         return "sal{w}\t{%b2, %0|%0, %b2}";
10639       else if (operands[2] == const1_rtx
10640                && (TARGET_SHIFT1 || optimize_size))
10641         return "sal{w}\t%0";
10642       else
10643         return "sal{w}\t{%2, %0|%0, %2}";
10644     }
10645 }
10646   [(set (attr "type")
10647      (cond [(eq_attr "alternative" "1")
10648               (const_string "lea")
10649             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10650                           (const_int 0))
10651                       (match_operand 0 "register_operand" ""))
10652                  (match_operand 2 "const1_operand" ""))
10653               (const_string "alu")
10654            ]
10655            (const_string "ishift")))
10656    (set_attr "mode" "HI,SI")])
10657
10658 (define_insn "*ashlhi3_1"
10659   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10660         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10661                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10662    (clobber (reg:CC FLAGS_REG))]
10663   "TARGET_PARTIAL_REG_STALL
10664    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10665 {
10666   switch (get_attr_type (insn))
10667     {
10668     case TYPE_ALU:
10669       if (operands[2] != const1_rtx)
10670         abort ();
10671       return "add{w}\t{%0, %0|%0, %0}";
10672
10673     default:
10674       if (REG_P (operands[2]))
10675         return "sal{w}\t{%b2, %0|%0, %b2}";
10676       else if (operands[2] == const1_rtx
10677                && (TARGET_SHIFT1 || optimize_size))
10678         return "sal{w}\t%0";
10679       else
10680         return "sal{w}\t{%2, %0|%0, %2}";
10681     }
10682 }
10683   [(set (attr "type")
10684      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10685                           (const_int 0))
10686                       (match_operand 0 "register_operand" ""))
10687                  (match_operand 2 "const1_operand" ""))
10688               (const_string "alu")
10689            ]
10690            (const_string "ishift")))
10691    (set_attr "mode" "HI")])
10692
10693 ;; This pattern can't accept a variable shift count, since shifts by
10694 ;; zero don't affect the flags.  We assume that shifts by constant
10695 ;; zero are optimized away.
10696 (define_insn "*ashlhi3_cmp"
10697   [(set (reg FLAGS_REG)
10698         (compare
10699           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10700                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10701           (const_int 0)))
10702    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10703         (ashift:HI (match_dup 1) (match_dup 2)))]
10704   "ix86_match_ccmode (insn, CCGOCmode)
10705    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10706 {
10707   switch (get_attr_type (insn))
10708     {
10709     case TYPE_ALU:
10710       if (operands[2] != const1_rtx)
10711         abort ();
10712       return "add{w}\t{%0, %0|%0, %0}";
10713
10714     default:
10715       if (REG_P (operands[2]))
10716         return "sal{w}\t{%b2, %0|%0, %b2}";
10717       else if (operands[2] == const1_rtx
10718                && (TARGET_SHIFT1 || optimize_size))
10719         return "sal{w}\t%0";
10720       else
10721         return "sal{w}\t{%2, %0|%0, %2}";
10722     }
10723 }
10724   [(set (attr "type")
10725      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10726                           (const_int 0))
10727                       (match_operand 0 "register_operand" ""))
10728                  (match_operand 2 "const1_operand" ""))
10729               (const_string "alu")
10730            ]
10731            (const_string "ishift")))
10732    (set_attr "mode" "HI")])
10733
10734 (define_expand "ashlqi3"
10735   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10736         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10737                    (match_operand:QI 2 "nonmemory_operand" "")))
10738    (clobber (reg:CC FLAGS_REG))]
10739   "TARGET_QIMODE_MATH"
10740   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10741
10742 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10743
10744 (define_insn "*ashlqi3_1_lea"
10745   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10746         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10747                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10748    (clobber (reg:CC FLAGS_REG))]
10749   "!TARGET_PARTIAL_REG_STALL
10750    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10751 {
10752   switch (get_attr_type (insn))
10753     {
10754     case TYPE_LEA:
10755       return "#";
10756     case TYPE_ALU:
10757       if (operands[2] != const1_rtx)
10758         abort ();
10759       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10760         return "add{l}\t{%k0, %k0|%k0, %k0}";
10761       else
10762         return "add{b}\t{%0, %0|%0, %0}";
10763
10764     default:
10765       if (REG_P (operands[2]))
10766         {
10767           if (get_attr_mode (insn) == MODE_SI)
10768             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10769           else
10770             return "sal{b}\t{%b2, %0|%0, %b2}";
10771         }
10772       else if (operands[2] == const1_rtx
10773                && (TARGET_SHIFT1 || optimize_size))
10774         {
10775           if (get_attr_mode (insn) == MODE_SI)
10776             return "sal{l}\t%0";
10777           else
10778             return "sal{b}\t%0";
10779         }
10780       else
10781         {
10782           if (get_attr_mode (insn) == MODE_SI)
10783             return "sal{l}\t{%2, %k0|%k0, %2}";
10784           else
10785             return "sal{b}\t{%2, %0|%0, %2}";
10786         }
10787     }
10788 }
10789   [(set (attr "type")
10790      (cond [(eq_attr "alternative" "2")
10791               (const_string "lea")
10792             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10793                           (const_int 0))
10794                       (match_operand 0 "register_operand" ""))
10795                  (match_operand 2 "const1_operand" ""))
10796               (const_string "alu")
10797            ]
10798            (const_string "ishift")))
10799    (set_attr "mode" "QI,SI,SI")])
10800
10801 (define_insn "*ashlqi3_1"
10802   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10803         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10804                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10805    (clobber (reg:CC FLAGS_REG))]
10806   "TARGET_PARTIAL_REG_STALL
10807    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10808 {
10809   switch (get_attr_type (insn))
10810     {
10811     case TYPE_ALU:
10812       if (operands[2] != const1_rtx)
10813         abort ();
10814       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10815         return "add{l}\t{%k0, %k0|%k0, %k0}";
10816       else
10817         return "add{b}\t{%0, %0|%0, %0}";
10818
10819     default:
10820       if (REG_P (operands[2]))
10821         {
10822           if (get_attr_mode (insn) == MODE_SI)
10823             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10824           else
10825             return "sal{b}\t{%b2, %0|%0, %b2}";
10826         }
10827       else if (operands[2] == const1_rtx
10828                && (TARGET_SHIFT1 || optimize_size))
10829         {
10830           if (get_attr_mode (insn) == MODE_SI)
10831             return "sal{l}\t%0";
10832           else
10833             return "sal{b}\t%0";
10834         }
10835       else
10836         {
10837           if (get_attr_mode (insn) == MODE_SI)
10838             return "sal{l}\t{%2, %k0|%k0, %2}";
10839           else
10840             return "sal{b}\t{%2, %0|%0, %2}";
10841         }
10842     }
10843 }
10844   [(set (attr "type")
10845      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10846                           (const_int 0))
10847                       (match_operand 0 "register_operand" ""))
10848                  (match_operand 2 "const1_operand" ""))
10849               (const_string "alu")
10850            ]
10851            (const_string "ishift")))
10852    (set_attr "mode" "QI,SI")])
10853
10854 ;; This pattern can't accept a variable shift count, since shifts by
10855 ;; zero don't affect the flags.  We assume that shifts by constant
10856 ;; zero are optimized away.
10857 (define_insn "*ashlqi3_cmp"
10858   [(set (reg FLAGS_REG)
10859         (compare
10860           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10861                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10862           (const_int 0)))
10863    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10864         (ashift:QI (match_dup 1) (match_dup 2)))]
10865   "ix86_match_ccmode (insn, CCGOCmode)
10866    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10867 {
10868   switch (get_attr_type (insn))
10869     {
10870     case TYPE_ALU:
10871       if (operands[2] != const1_rtx)
10872         abort ();
10873       return "add{b}\t{%0, %0|%0, %0}";
10874
10875     default:
10876       if (REG_P (operands[2]))
10877         return "sal{b}\t{%b2, %0|%0, %b2}";
10878       else if (operands[2] == const1_rtx
10879                && (TARGET_SHIFT1 || optimize_size))
10880         return "sal{b}\t%0";
10881       else
10882         return "sal{b}\t{%2, %0|%0, %2}";
10883     }
10884 }
10885   [(set (attr "type")
10886      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10887                           (const_int 0))
10888                       (match_operand 0 "register_operand" ""))
10889                  (match_operand 2 "const1_operand" ""))
10890               (const_string "alu")
10891            ]
10892            (const_string "ishift")))
10893    (set_attr "mode" "QI")])
10894
10895 ;; See comment above `ashldi3' about how this works.
10896
10897 (define_expand "ashrdi3"
10898   [(set (match_operand:DI 0 "shiftdi_operand" "")
10899         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10900                      (match_operand:QI 2 "nonmemory_operand" "")))]
10901   ""
10902   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10903
10904 (define_insn "*ashrdi3_63_rex64"
10905   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10906         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10907                      (match_operand:DI 2 "const_int_operand" "i,i")))
10908    (clobber (reg:CC FLAGS_REG))]
10909   "TARGET_64BIT && INTVAL (operands[2]) == 63
10910    && (TARGET_USE_CLTD || optimize_size)
10911    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10912   "@
10913    {cqto|cqo}
10914    sar{q}\t{%2, %0|%0, %2}"
10915   [(set_attr "type" "imovx,ishift")
10916    (set_attr "prefix_0f" "0,*")
10917    (set_attr "length_immediate" "0,*")
10918    (set_attr "modrm" "0,1")
10919    (set_attr "mode" "DI")])
10920
10921 (define_insn "*ashrdi3_1_one_bit_rex64"
10922   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10923         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10924                      (match_operand:QI 2 "const1_operand" "")))
10925    (clobber (reg:CC FLAGS_REG))]
10926   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10927    && (TARGET_SHIFT1 || optimize_size)"
10928   "sar{q}\t%0"
10929   [(set_attr "type" "ishift")
10930    (set (attr "length") 
10931      (if_then_else (match_operand:DI 0 "register_operand" "") 
10932         (const_string "2")
10933         (const_string "*")))])
10934
10935 (define_insn "*ashrdi3_1_rex64"
10936   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10937         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10938                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10939    (clobber (reg:CC FLAGS_REG))]
10940   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10941   "@
10942    sar{q}\t{%2, %0|%0, %2}
10943    sar{q}\t{%b2, %0|%0, %b2}"
10944   [(set_attr "type" "ishift")
10945    (set_attr "mode" "DI")])
10946
10947 ;; This pattern can't accept a variable shift count, since shifts by
10948 ;; zero don't affect the flags.  We assume that shifts by constant
10949 ;; zero are optimized away.
10950 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10951   [(set (reg FLAGS_REG)
10952         (compare
10953           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10954                        (match_operand:QI 2 "const1_operand" ""))
10955           (const_int 0)))
10956    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10957         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10958   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10959    && (TARGET_SHIFT1 || optimize_size)
10960    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10961   "sar{q}\t%0"
10962   [(set_attr "type" "ishift")
10963    (set (attr "length") 
10964      (if_then_else (match_operand:DI 0 "register_operand" "") 
10965         (const_string "2")
10966         (const_string "*")))])
10967
10968 ;; This pattern can't accept a variable shift count, since shifts by
10969 ;; zero don't affect the flags.  We assume that shifts by constant
10970 ;; zero are optimized away.
10971 (define_insn "*ashrdi3_cmp_rex64"
10972   [(set (reg FLAGS_REG)
10973         (compare
10974           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10975                        (match_operand:QI 2 "const_int_operand" "n"))
10976           (const_int 0)))
10977    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10978         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10979   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10980    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10981   "sar{q}\t{%2, %0|%0, %2}"
10982   [(set_attr "type" "ishift")
10983    (set_attr "mode" "DI")])
10984
10985 (define_insn "*ashrdi3_1"
10986   [(set (match_operand:DI 0 "register_operand" "=r")
10987         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10988                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10989    (clobber (reg:CC FLAGS_REG))]
10990   "!TARGET_64BIT"
10991   "#"
10992   [(set_attr "type" "multi")])
10993
10994 ;; By default we don't ask for a scratch register, because when DImode
10995 ;; values are manipulated, registers are already at a premium.  But if
10996 ;; we have one handy, we won't turn it away.
10997 (define_peephole2
10998   [(match_scratch:SI 3 "r")
10999    (parallel [(set (match_operand:DI 0 "register_operand" "")
11000                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11001                                 (match_operand:QI 2 "nonmemory_operand" "")))
11002               (clobber (reg:CC FLAGS_REG))])
11003    (match_dup 3)]
11004   "!TARGET_64BIT && TARGET_CMOVE"
11005   [(const_int 0)]
11006   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11007
11008 (define_split
11009   [(set (match_operand:DI 0 "register_operand" "")
11010         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11011                      (match_operand:QI 2 "nonmemory_operand" "")))
11012    (clobber (reg:CC FLAGS_REG))]
11013   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11014   [(const_int 0)]
11015   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11016
11017 (define_insn "x86_shrd_1"
11018   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11019         (ior:SI (ashiftrt:SI (match_dup 0)
11020                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11021                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11022                   (minus:QI (const_int 32) (match_dup 2)))))
11023    (clobber (reg:CC FLAGS_REG))]
11024   ""
11025   "@
11026    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11027    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11028   [(set_attr "type" "ishift")
11029    (set_attr "prefix_0f" "1")
11030    (set_attr "pent_pair" "np")
11031    (set_attr "mode" "SI")])
11032
11033 (define_expand "x86_shift_adj_3"
11034   [(use (match_operand:SI 0 "register_operand" ""))
11035    (use (match_operand:SI 1 "register_operand" ""))
11036    (use (match_operand:QI 2 "register_operand" ""))]
11037   ""
11038 {
11039   rtx label = gen_label_rtx ();
11040   rtx tmp;
11041
11042   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11043
11044   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11045   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11046   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11047                               gen_rtx_LABEL_REF (VOIDmode, label),
11048                               pc_rtx);
11049   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11050   JUMP_LABEL (tmp) = label;
11051
11052   emit_move_insn (operands[0], operands[1]);
11053   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11054
11055   emit_label (label);
11056   LABEL_NUSES (label) = 1;
11057
11058   DONE;
11059 })
11060
11061 (define_insn "ashrsi3_31"
11062   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11063         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11064                      (match_operand:SI 2 "const_int_operand" "i,i")))
11065    (clobber (reg:CC FLAGS_REG))]
11066   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11067    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11068   "@
11069    {cltd|cdq}
11070    sar{l}\t{%2, %0|%0, %2}"
11071   [(set_attr "type" "imovx,ishift")
11072    (set_attr "prefix_0f" "0,*")
11073    (set_attr "length_immediate" "0,*")
11074    (set_attr "modrm" "0,1")
11075    (set_attr "mode" "SI")])
11076
11077 (define_insn "*ashrsi3_31_zext"
11078   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11079         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11080                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11081    (clobber (reg:CC FLAGS_REG))]
11082   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11083    && INTVAL (operands[2]) == 31
11084    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11085   "@
11086    {cltd|cdq}
11087    sar{l}\t{%2, %k0|%k0, %2}"
11088   [(set_attr "type" "imovx,ishift")
11089    (set_attr "prefix_0f" "0,*")
11090    (set_attr "length_immediate" "0,*")
11091    (set_attr "modrm" "0,1")
11092    (set_attr "mode" "SI")])
11093
11094 (define_expand "ashrsi3"
11095   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11096         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11097                      (match_operand:QI 2 "nonmemory_operand" "")))
11098    (clobber (reg:CC FLAGS_REG))]
11099   ""
11100   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11101
11102 (define_insn "*ashrsi3_1_one_bit"
11103   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11104         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11105                      (match_operand:QI 2 "const1_operand" "")))
11106    (clobber (reg:CC FLAGS_REG))]
11107   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11108    && (TARGET_SHIFT1 || optimize_size)"
11109   "sar{l}\t%0"
11110   [(set_attr "type" "ishift")
11111    (set (attr "length") 
11112      (if_then_else (match_operand:SI 0 "register_operand" "") 
11113         (const_string "2")
11114         (const_string "*")))])
11115
11116 (define_insn "*ashrsi3_1_one_bit_zext"
11117   [(set (match_operand:DI 0 "register_operand" "=r")
11118         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11119                                      (match_operand:QI 2 "const1_operand" ""))))
11120    (clobber (reg:CC FLAGS_REG))]
11121   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11122    && (TARGET_SHIFT1 || optimize_size)"
11123   "sar{l}\t%k0"
11124   [(set_attr "type" "ishift")
11125    (set_attr "length" "2")])
11126
11127 (define_insn "*ashrsi3_1"
11128   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11129         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11130                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11131    (clobber (reg:CC FLAGS_REG))]
11132   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11133   "@
11134    sar{l}\t{%2, %0|%0, %2}
11135    sar{l}\t{%b2, %0|%0, %b2}"
11136   [(set_attr "type" "ishift")
11137    (set_attr "mode" "SI")])
11138
11139 (define_insn "*ashrsi3_1_zext"
11140   [(set (match_operand:DI 0 "register_operand" "=r,r")
11141         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11142                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11143    (clobber (reg:CC FLAGS_REG))]
11144   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11145   "@
11146    sar{l}\t{%2, %k0|%k0, %2}
11147    sar{l}\t{%b2, %k0|%k0, %b2}"
11148   [(set_attr "type" "ishift")
11149    (set_attr "mode" "SI")])
11150
11151 ;; This pattern can't accept a variable shift count, since shifts by
11152 ;; zero don't affect the flags.  We assume that shifts by constant
11153 ;; zero are optimized away.
11154 (define_insn "*ashrsi3_one_bit_cmp"
11155   [(set (reg FLAGS_REG)
11156         (compare
11157           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11158                        (match_operand:QI 2 "const1_operand" ""))
11159           (const_int 0)))
11160    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11161         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11162   "ix86_match_ccmode (insn, CCGOCmode)
11163    && (TARGET_SHIFT1 || optimize_size)
11164    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11165   "sar{l}\t%0"
11166   [(set_attr "type" "ishift")
11167    (set (attr "length") 
11168      (if_then_else (match_operand:SI 0 "register_operand" "") 
11169         (const_string "2")
11170         (const_string "*")))])
11171
11172 (define_insn "*ashrsi3_one_bit_cmp_zext"
11173   [(set (reg FLAGS_REG)
11174         (compare
11175           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11176                        (match_operand:QI 2 "const1_operand" ""))
11177           (const_int 0)))
11178    (set (match_operand:DI 0 "register_operand" "=r")
11179         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11180   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11181    && (TARGET_SHIFT1 || optimize_size)
11182    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11183   "sar{l}\t%k0"
11184   [(set_attr "type" "ishift")
11185    (set_attr "length" "2")])
11186
11187 ;; This pattern can't accept a variable shift count, since shifts by
11188 ;; zero don't affect the flags.  We assume that shifts by constant
11189 ;; zero are optimized away.
11190 (define_insn "*ashrsi3_cmp"
11191   [(set (reg FLAGS_REG)
11192         (compare
11193           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11194                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11195           (const_int 0)))
11196    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11197         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11198   "ix86_match_ccmode (insn, CCGOCmode)
11199    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11200   "sar{l}\t{%2, %0|%0, %2}"
11201   [(set_attr "type" "ishift")
11202    (set_attr "mode" "SI")])
11203
11204 (define_insn "*ashrsi3_cmp_zext"
11205   [(set (reg FLAGS_REG)
11206         (compare
11207           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11208                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11209           (const_int 0)))
11210    (set (match_operand:DI 0 "register_operand" "=r")
11211         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11212   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11213    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11214   "sar{l}\t{%2, %k0|%k0, %2}"
11215   [(set_attr "type" "ishift")
11216    (set_attr "mode" "SI")])
11217
11218 (define_expand "ashrhi3"
11219   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11220         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11221                      (match_operand:QI 2 "nonmemory_operand" "")))
11222    (clobber (reg:CC FLAGS_REG))]
11223   "TARGET_HIMODE_MATH"
11224   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11225
11226 (define_insn "*ashrhi3_1_one_bit"
11227   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11228         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11229                      (match_operand:QI 2 "const1_operand" "")))
11230    (clobber (reg:CC FLAGS_REG))]
11231   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11232    && (TARGET_SHIFT1 || optimize_size)"
11233   "sar{w}\t%0"
11234   [(set_attr "type" "ishift")
11235    (set (attr "length") 
11236      (if_then_else (match_operand 0 "register_operand" "") 
11237         (const_string "2")
11238         (const_string "*")))])
11239
11240 (define_insn "*ashrhi3_1"
11241   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11242         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11243                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11244    (clobber (reg:CC FLAGS_REG))]
11245   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11246   "@
11247    sar{w}\t{%2, %0|%0, %2}
11248    sar{w}\t{%b2, %0|%0, %b2}"
11249   [(set_attr "type" "ishift")
11250    (set_attr "mode" "HI")])
11251
11252 ;; This pattern can't accept a variable shift count, since shifts by
11253 ;; zero don't affect the flags.  We assume that shifts by constant
11254 ;; zero are optimized away.
11255 (define_insn "*ashrhi3_one_bit_cmp"
11256   [(set (reg FLAGS_REG)
11257         (compare
11258           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11259                        (match_operand:QI 2 "const1_operand" ""))
11260           (const_int 0)))
11261    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11262         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11263   "ix86_match_ccmode (insn, CCGOCmode)
11264    && (TARGET_SHIFT1 || optimize_size)
11265    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11266   "sar{w}\t%0"
11267   [(set_attr "type" "ishift")
11268    (set (attr "length") 
11269      (if_then_else (match_operand 0 "register_operand" "") 
11270         (const_string "2")
11271         (const_string "*")))])
11272
11273 ;; This pattern can't accept a variable shift count, since shifts by
11274 ;; zero don't affect the flags.  We assume that shifts by constant
11275 ;; zero are optimized away.
11276 (define_insn "*ashrhi3_cmp"
11277   [(set (reg FLAGS_REG)
11278         (compare
11279           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11280                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11281           (const_int 0)))
11282    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11283         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11284   "ix86_match_ccmode (insn, CCGOCmode)
11285    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11286   "sar{w}\t{%2, %0|%0, %2}"
11287   [(set_attr "type" "ishift")
11288    (set_attr "mode" "HI")])
11289
11290 (define_expand "ashrqi3"
11291   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11292         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11293                      (match_operand:QI 2 "nonmemory_operand" "")))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "TARGET_QIMODE_MATH"
11296   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11297
11298 (define_insn "*ashrqi3_1_one_bit"
11299   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11300         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11301                      (match_operand:QI 2 "const1_operand" "")))
11302    (clobber (reg:CC FLAGS_REG))]
11303   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11304    && (TARGET_SHIFT1 || optimize_size)"
11305   "sar{b}\t%0"
11306   [(set_attr "type" "ishift")
11307    (set (attr "length") 
11308      (if_then_else (match_operand 0 "register_operand" "") 
11309         (const_string "2")
11310         (const_string "*")))])
11311
11312 (define_insn "*ashrqi3_1_one_bit_slp"
11313   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11314         (ashiftrt:QI (match_dup 0)
11315                      (match_operand:QI 1 "const1_operand" "")))
11316    (clobber (reg:CC FLAGS_REG))]
11317   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11318    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11319    && (TARGET_SHIFT1 || optimize_size)"
11320   "sar{b}\t%0"
11321   [(set_attr "type" "ishift1")
11322    (set (attr "length") 
11323      (if_then_else (match_operand 0 "register_operand" "") 
11324         (const_string "2")
11325         (const_string "*")))])
11326
11327 (define_insn "*ashrqi3_1"
11328   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11329         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11330                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11333   "@
11334    sar{b}\t{%2, %0|%0, %2}
11335    sar{b}\t{%b2, %0|%0, %b2}"
11336   [(set_attr "type" "ishift")
11337    (set_attr "mode" "QI")])
11338
11339 (define_insn "*ashrqi3_1_slp"
11340   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11341         (ashiftrt:QI (match_dup 0)
11342                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11343    (clobber (reg:CC FLAGS_REG))]
11344   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11345    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11346   "@
11347    sar{b}\t{%1, %0|%0, %1}
11348    sar{b}\t{%b1, %0|%0, %b1}"
11349   [(set_attr "type" "ishift1")
11350    (set_attr "mode" "QI")])
11351
11352 ;; This pattern can't accept a variable shift count, since shifts by
11353 ;; zero don't affect the flags.  We assume that shifts by constant
11354 ;; zero are optimized away.
11355 (define_insn "*ashrqi3_one_bit_cmp"
11356   [(set (reg FLAGS_REG)
11357         (compare
11358           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11359                        (match_operand:QI 2 "const1_operand" "I"))
11360           (const_int 0)))
11361    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11362         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11363   "ix86_match_ccmode (insn, CCGOCmode)
11364    && (TARGET_SHIFT1 || optimize_size)
11365    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11366   "sar{b}\t%0"
11367   [(set_attr "type" "ishift")
11368    (set (attr "length") 
11369      (if_then_else (match_operand 0 "register_operand" "") 
11370         (const_string "2")
11371         (const_string "*")))])
11372
11373 ;; This pattern can't accept a variable shift count, since shifts by
11374 ;; zero don't affect the flags.  We assume that shifts by constant
11375 ;; zero are optimized away.
11376 (define_insn "*ashrqi3_cmp"
11377   [(set (reg FLAGS_REG)
11378         (compare
11379           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11380                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11381           (const_int 0)))
11382    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11383         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11384   "ix86_match_ccmode (insn, CCGOCmode)
11385    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11386   "sar{b}\t{%2, %0|%0, %2}"
11387   [(set_attr "type" "ishift")
11388    (set_attr "mode" "QI")])
11389 \f
11390 ;; Logical shift instructions
11391
11392 ;; See comment above `ashldi3' about how this works.
11393
11394 (define_expand "lshrdi3"
11395   [(set (match_operand:DI 0 "shiftdi_operand" "")
11396         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11397                      (match_operand:QI 2 "nonmemory_operand" "")))]
11398   ""
11399   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11400
11401 (define_insn "*lshrdi3_1_one_bit_rex64"
11402   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11403         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404                      (match_operand:QI 2 "const1_operand" "")))
11405    (clobber (reg:CC FLAGS_REG))]
11406   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11407    && (TARGET_SHIFT1 || optimize_size)"
11408   "shr{q}\t%0"
11409   [(set_attr "type" "ishift")
11410    (set (attr "length") 
11411      (if_then_else (match_operand:DI 0 "register_operand" "") 
11412         (const_string "2")
11413         (const_string "*")))])
11414
11415 (define_insn "*lshrdi3_1_rex64"
11416   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11417         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11418                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11419    (clobber (reg:CC FLAGS_REG))]
11420   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11421   "@
11422    shr{q}\t{%2, %0|%0, %2}
11423    shr{q}\t{%b2, %0|%0, %b2}"
11424   [(set_attr "type" "ishift")
11425    (set_attr "mode" "DI")])
11426
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags.  We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11431   [(set (reg FLAGS_REG)
11432         (compare
11433           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434                        (match_operand:QI 2 "const1_operand" ""))
11435           (const_int 0)))
11436    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11438   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439    && (TARGET_SHIFT1 || optimize_size)
11440    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11441   "shr{q}\t%0"
11442   [(set_attr "type" "ishift")
11443    (set (attr "length") 
11444      (if_then_else (match_operand:DI 0 "register_operand" "") 
11445         (const_string "2")
11446         (const_string "*")))])
11447
11448 ;; This pattern can't accept a variable shift count, since shifts by
11449 ;; zero don't affect the flags.  We assume that shifts by constant
11450 ;; zero are optimized away.
11451 (define_insn "*lshrdi3_cmp_rex64"
11452   [(set (reg FLAGS_REG)
11453         (compare
11454           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11455                        (match_operand:QI 2 "const_int_operand" "e"))
11456           (const_int 0)))
11457    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11458         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11459   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11460    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11461   "shr{q}\t{%2, %0|%0, %2}"
11462   [(set_attr "type" "ishift")
11463    (set_attr "mode" "DI")])
11464
11465 (define_insn "*lshrdi3_1"
11466   [(set (match_operand:DI 0 "register_operand" "=r")
11467         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11468                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11469    (clobber (reg:CC FLAGS_REG))]
11470   "!TARGET_64BIT"
11471   "#"
11472   [(set_attr "type" "multi")])
11473
11474 ;; By default we don't ask for a scratch register, because when DImode
11475 ;; values are manipulated, registers are already at a premium.  But if
11476 ;; we have one handy, we won't turn it away.
11477 (define_peephole2
11478   [(match_scratch:SI 3 "r")
11479    (parallel [(set (match_operand:DI 0 "register_operand" "")
11480                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11481                                 (match_operand:QI 2 "nonmemory_operand" "")))
11482               (clobber (reg:CC FLAGS_REG))])
11483    (match_dup 3)]
11484   "!TARGET_64BIT && TARGET_CMOVE"
11485   [(const_int 0)]
11486   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11487
11488 (define_split 
11489   [(set (match_operand:DI 0 "register_operand" "")
11490         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11491                      (match_operand:QI 2 "nonmemory_operand" "")))
11492    (clobber (reg:CC FLAGS_REG))]
11493   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11494   [(const_int 0)]
11495   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11496
11497 (define_expand "lshrsi3"
11498   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11499         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11500                      (match_operand:QI 2 "nonmemory_operand" "")))
11501    (clobber (reg:CC FLAGS_REG))]
11502   ""
11503   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11504
11505 (define_insn "*lshrsi3_1_one_bit"
11506   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11507         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11508                      (match_operand:QI 2 "const1_operand" "")))
11509    (clobber (reg:CC FLAGS_REG))]
11510   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11511    && (TARGET_SHIFT1 || optimize_size)"
11512   "shr{l}\t%0"
11513   [(set_attr "type" "ishift")
11514    (set (attr "length") 
11515      (if_then_else (match_operand:SI 0 "register_operand" "") 
11516         (const_string "2")
11517         (const_string "*")))])
11518
11519 (define_insn "*lshrsi3_1_one_bit_zext"
11520   [(set (match_operand:DI 0 "register_operand" "=r")
11521         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11522                      (match_operand:QI 2 "const1_operand" "")))
11523    (clobber (reg:CC FLAGS_REG))]
11524   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11525    && (TARGET_SHIFT1 || optimize_size)"
11526   "shr{l}\t%k0"
11527   [(set_attr "type" "ishift")
11528    (set_attr "length" "2")])
11529
11530 (define_insn "*lshrsi3_1"
11531   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11532         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11533                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11534    (clobber (reg:CC FLAGS_REG))]
11535   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11536   "@
11537    shr{l}\t{%2, %0|%0, %2}
11538    shr{l}\t{%b2, %0|%0, %b2}"
11539   [(set_attr "type" "ishift")
11540    (set_attr "mode" "SI")])
11541
11542 (define_insn "*lshrsi3_1_zext"
11543   [(set (match_operand:DI 0 "register_operand" "=r,r")
11544         (zero_extend:DI
11545           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11546                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11547    (clobber (reg:CC FLAGS_REG))]
11548   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11549   "@
11550    shr{l}\t{%2, %k0|%k0, %2}
11551    shr{l}\t{%b2, %k0|%k0, %b2}"
11552   [(set_attr "type" "ishift")
11553    (set_attr "mode" "SI")])
11554
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags.  We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*lshrsi3_one_bit_cmp"
11559   [(set (reg FLAGS_REG)
11560         (compare
11561           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11562                        (match_operand:QI 2 "const1_operand" ""))
11563           (const_int 0)))
11564    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11565         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11566   "ix86_match_ccmode (insn, CCGOCmode)
11567    && (TARGET_SHIFT1 || optimize_size)
11568    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11569   "shr{l}\t%0"
11570   [(set_attr "type" "ishift")
11571    (set (attr "length") 
11572      (if_then_else (match_operand:SI 0 "register_operand" "") 
11573         (const_string "2")
11574         (const_string "*")))])
11575
11576 (define_insn "*lshrsi3_cmp_one_bit_zext"
11577   [(set (reg FLAGS_REG)
11578         (compare
11579           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11580                        (match_operand:QI 2 "const1_operand" ""))
11581           (const_int 0)))
11582    (set (match_operand:DI 0 "register_operand" "=r")
11583         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11584   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11585    && (TARGET_SHIFT1 || optimize_size)
11586    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11587   "shr{l}\t%k0"
11588   [(set_attr "type" "ishift")
11589    (set_attr "length" "2")])
11590
11591 ;; This pattern can't accept a variable shift count, since shifts by
11592 ;; zero don't affect the flags.  We assume that shifts by constant
11593 ;; zero are optimized away.
11594 (define_insn "*lshrsi3_cmp"
11595   [(set (reg FLAGS_REG)
11596         (compare
11597           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11598                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11599           (const_int 0)))
11600    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11601         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11602   "ix86_match_ccmode (insn, CCGOCmode)
11603    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11604   "shr{l}\t{%2, %0|%0, %2}"
11605   [(set_attr "type" "ishift")
11606    (set_attr "mode" "SI")])
11607
11608 (define_insn "*lshrsi3_cmp_zext"
11609   [(set (reg FLAGS_REG)
11610         (compare
11611           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11612                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11613           (const_int 0)))
11614    (set (match_operand:DI 0 "register_operand" "=r")
11615         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11616   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11617    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11618   "shr{l}\t{%2, %k0|%k0, %2}"
11619   [(set_attr "type" "ishift")
11620    (set_attr "mode" "SI")])
11621
11622 (define_expand "lshrhi3"
11623   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11624         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11625                      (match_operand:QI 2 "nonmemory_operand" "")))
11626    (clobber (reg:CC FLAGS_REG))]
11627   "TARGET_HIMODE_MATH"
11628   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11629
11630 (define_insn "*lshrhi3_1_one_bit"
11631   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11632         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11633                      (match_operand:QI 2 "const1_operand" "")))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11636    && (TARGET_SHIFT1 || optimize_size)"
11637   "shr{w}\t%0"
11638   [(set_attr "type" "ishift")
11639    (set (attr "length") 
11640      (if_then_else (match_operand 0 "register_operand" "") 
11641         (const_string "2")
11642         (const_string "*")))])
11643
11644 (define_insn "*lshrhi3_1"
11645   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11646         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11647                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11648    (clobber (reg:CC FLAGS_REG))]
11649   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11650   "@
11651    shr{w}\t{%2, %0|%0, %2}
11652    shr{w}\t{%b2, %0|%0, %b2}"
11653   [(set_attr "type" "ishift")
11654    (set_attr "mode" "HI")])
11655
11656 ;; This pattern can't accept a variable shift count, since shifts by
11657 ;; zero don't affect the flags.  We assume that shifts by constant
11658 ;; zero are optimized away.
11659 (define_insn "*lshrhi3_one_bit_cmp"
11660   [(set (reg FLAGS_REG)
11661         (compare
11662           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11663                        (match_operand:QI 2 "const1_operand" ""))
11664           (const_int 0)))
11665    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11666         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11667   "ix86_match_ccmode (insn, CCGOCmode)
11668    && (TARGET_SHIFT1 || optimize_size)
11669    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11670   "shr{w}\t%0"
11671   [(set_attr "type" "ishift")
11672    (set (attr "length") 
11673      (if_then_else (match_operand:SI 0 "register_operand" "") 
11674         (const_string "2")
11675         (const_string "*")))])
11676
11677 ;; This pattern can't accept a variable shift count, since shifts by
11678 ;; zero don't affect the flags.  We assume that shifts by constant
11679 ;; zero are optimized away.
11680 (define_insn "*lshrhi3_cmp"
11681   [(set (reg FLAGS_REG)
11682         (compare
11683           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11684                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11685           (const_int 0)))
11686    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11687         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11688   "ix86_match_ccmode (insn, CCGOCmode)
11689    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11690   "shr{w}\t{%2, %0|%0, %2}"
11691   [(set_attr "type" "ishift")
11692    (set_attr "mode" "HI")])
11693
11694 (define_expand "lshrqi3"
11695   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11696         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11697                      (match_operand:QI 2 "nonmemory_operand" "")))
11698    (clobber (reg:CC FLAGS_REG))]
11699   "TARGET_QIMODE_MATH"
11700   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11701
11702 (define_insn "*lshrqi3_1_one_bit"
11703   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11704         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11705                      (match_operand:QI 2 "const1_operand" "")))
11706    (clobber (reg:CC FLAGS_REG))]
11707   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11708    && (TARGET_SHIFT1 || optimize_size)"
11709   "shr{b}\t%0"
11710   [(set_attr "type" "ishift")
11711    (set (attr "length") 
11712      (if_then_else (match_operand 0 "register_operand" "") 
11713         (const_string "2")
11714         (const_string "*")))])
11715
11716 (define_insn "*lshrqi3_1_one_bit_slp"
11717   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11718         (lshiftrt:QI (match_dup 0)
11719                      (match_operand:QI 1 "const1_operand" "")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11722    && (TARGET_SHIFT1 || optimize_size)"
11723   "shr{b}\t%0"
11724   [(set_attr "type" "ishift1")
11725    (set (attr "length") 
11726      (if_then_else (match_operand 0 "register_operand" "") 
11727         (const_string "2")
11728         (const_string "*")))])
11729
11730 (define_insn "*lshrqi3_1"
11731   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11732         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11733                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11736   "@
11737    shr{b}\t{%2, %0|%0, %2}
11738    shr{b}\t{%b2, %0|%0, %b2}"
11739   [(set_attr "type" "ishift")
11740    (set_attr "mode" "QI")])
11741
11742 (define_insn "*lshrqi3_1_slp"
11743   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11744         (lshiftrt:QI (match_dup 0)
11745                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11746    (clobber (reg:CC FLAGS_REG))]
11747   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11748    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11749   "@
11750    shr{b}\t{%1, %0|%0, %1}
11751    shr{b}\t{%b1, %0|%0, %b1}"
11752   [(set_attr "type" "ishift1")
11753    (set_attr "mode" "QI")])
11754
11755 ;; This pattern can't accept a variable shift count, since shifts by
11756 ;; zero don't affect the flags.  We assume that shifts by constant
11757 ;; zero are optimized away.
11758 (define_insn "*lshrqi2_one_bit_cmp"
11759   [(set (reg FLAGS_REG)
11760         (compare
11761           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11762                        (match_operand:QI 2 "const1_operand" ""))
11763           (const_int 0)))
11764    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11765         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11766   "ix86_match_ccmode (insn, CCGOCmode)
11767    && (TARGET_SHIFT1 || optimize_size)
11768    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11769   "shr{b}\t%0"
11770   [(set_attr "type" "ishift")
11771    (set (attr "length") 
11772      (if_then_else (match_operand:SI 0 "register_operand" "") 
11773         (const_string "2")
11774         (const_string "*")))])
11775
11776 ;; This pattern can't accept a variable shift count, since shifts by
11777 ;; zero don't affect the flags.  We assume that shifts by constant
11778 ;; zero are optimized away.
11779 (define_insn "*lshrqi2_cmp"
11780   [(set (reg FLAGS_REG)
11781         (compare
11782           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11783                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11784           (const_int 0)))
11785    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11786         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11787   "ix86_match_ccmode (insn, CCGOCmode)
11788    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11789   "shr{b}\t{%2, %0|%0, %2}"
11790   [(set_attr "type" "ishift")
11791    (set_attr "mode" "QI")])
11792 \f
11793 ;; Rotate instructions
11794
11795 (define_expand "rotldi3"
11796   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11797         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11798                    (match_operand:QI 2 "nonmemory_operand" "")))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "TARGET_64BIT"
11801   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11802
11803 (define_insn "*rotlsi3_1_one_bit_rex64"
11804   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11805         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11806                    (match_operand:QI 2 "const1_operand" "")))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11809    && (TARGET_SHIFT1 || optimize_size)"
11810   "rol{q}\t%0"
11811   [(set_attr "type" "rotate")
11812    (set (attr "length") 
11813      (if_then_else (match_operand:DI 0 "register_operand" "") 
11814         (const_string "2")
11815         (const_string "*")))])
11816
11817 (define_insn "*rotldi3_1_rex64"
11818   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11819         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11820                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11821    (clobber (reg:CC FLAGS_REG))]
11822   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11823   "@
11824    rol{q}\t{%2, %0|%0, %2}
11825    rol{q}\t{%b2, %0|%0, %b2}"
11826   [(set_attr "type" "rotate")
11827    (set_attr "mode" "DI")])
11828
11829 (define_expand "rotlsi3"
11830   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11831         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11832                    (match_operand:QI 2 "nonmemory_operand" "")))
11833    (clobber (reg:CC FLAGS_REG))]
11834   ""
11835   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11836
11837 (define_insn "*rotlsi3_1_one_bit"
11838   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11839         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11840                    (match_operand:QI 2 "const1_operand" "")))
11841    (clobber (reg:CC FLAGS_REG))]
11842   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11843    && (TARGET_SHIFT1 || optimize_size)"
11844   "rol{l}\t%0"
11845   [(set_attr "type" "rotate")
11846    (set (attr "length") 
11847      (if_then_else (match_operand:SI 0 "register_operand" "") 
11848         (const_string "2")
11849         (const_string "*")))])
11850
11851 (define_insn "*rotlsi3_1_one_bit_zext"
11852   [(set (match_operand:DI 0 "register_operand" "=r")
11853         (zero_extend:DI
11854           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11855                      (match_operand:QI 2 "const1_operand" ""))))
11856    (clobber (reg:CC FLAGS_REG))]
11857   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11858    && (TARGET_SHIFT1 || optimize_size)"
11859   "rol{l}\t%k0"
11860   [(set_attr "type" "rotate")
11861    (set_attr "length" "2")])
11862
11863 (define_insn "*rotlsi3_1"
11864   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11865         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11866                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11867    (clobber (reg:CC FLAGS_REG))]
11868   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11869   "@
11870    rol{l}\t{%2, %0|%0, %2}
11871    rol{l}\t{%b2, %0|%0, %b2}"
11872   [(set_attr "type" "rotate")
11873    (set_attr "mode" "SI")])
11874
11875 (define_insn "*rotlsi3_1_zext"
11876   [(set (match_operand:DI 0 "register_operand" "=r,r")
11877         (zero_extend:DI
11878           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11879                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11882   "@
11883    rol{l}\t{%2, %k0|%k0, %2}
11884    rol{l}\t{%b2, %k0|%k0, %b2}"
11885   [(set_attr "type" "rotate")
11886    (set_attr "mode" "SI")])
11887
11888 (define_expand "rotlhi3"
11889   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11890         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11891                    (match_operand:QI 2 "nonmemory_operand" "")))
11892    (clobber (reg:CC FLAGS_REG))]
11893   "TARGET_HIMODE_MATH"
11894   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11895
11896 (define_insn "*rotlhi3_1_one_bit"
11897   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11898         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11899                    (match_operand:QI 2 "const1_operand" "")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11902    && (TARGET_SHIFT1 || optimize_size)"
11903   "rol{w}\t%0"
11904   [(set_attr "type" "rotate")
11905    (set (attr "length") 
11906      (if_then_else (match_operand 0 "register_operand" "") 
11907         (const_string "2")
11908         (const_string "*")))])
11909
11910 (define_insn "*rotlhi3_1"
11911   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11912         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11913                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11914    (clobber (reg:CC FLAGS_REG))]
11915   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11916   "@
11917    rol{w}\t{%2, %0|%0, %2}
11918    rol{w}\t{%b2, %0|%0, %b2}"
11919   [(set_attr "type" "rotate")
11920    (set_attr "mode" "HI")])
11921
11922 (define_expand "rotlqi3"
11923   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11924         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11925                    (match_operand:QI 2 "nonmemory_operand" "")))
11926    (clobber (reg:CC FLAGS_REG))]
11927   "TARGET_QIMODE_MATH"
11928   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11929
11930 (define_insn "*rotlqi3_1_one_bit_slp"
11931   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11932         (rotate:QI (match_dup 0)
11933                    (match_operand:QI 1 "const1_operand" "")))
11934    (clobber (reg:CC FLAGS_REG))]
11935   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11936    && (TARGET_SHIFT1 || optimize_size)"
11937   "rol{b}\t%0"
11938   [(set_attr "type" "rotate1")
11939    (set (attr "length") 
11940      (if_then_else (match_operand 0 "register_operand" "") 
11941         (const_string "2")
11942         (const_string "*")))])
11943
11944 (define_insn "*rotlqi3_1_one_bit"
11945   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947                    (match_operand:QI 2 "const1_operand" "")))
11948    (clobber (reg:CC FLAGS_REG))]
11949   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11950    && (TARGET_SHIFT1 || optimize_size)"
11951   "rol{b}\t%0"
11952   [(set_attr "type" "rotate")
11953    (set (attr "length") 
11954      (if_then_else (match_operand 0 "register_operand" "") 
11955         (const_string "2")
11956         (const_string "*")))])
11957
11958 (define_insn "*rotlqi3_1_slp"
11959   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11960         (rotate:QI (match_dup 0)
11961                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11962    (clobber (reg:CC FLAGS_REG))]
11963   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11964    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11965   "@
11966    rol{b}\t{%1, %0|%0, %1}
11967    rol{b}\t{%b1, %0|%0, %b1}"
11968   [(set_attr "type" "rotate1")
11969    (set_attr "mode" "QI")])
11970
11971 (define_insn "*rotlqi3_1"
11972   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11973         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11974                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11977   "@
11978    rol{b}\t{%2, %0|%0, %2}
11979    rol{b}\t{%b2, %0|%0, %b2}"
11980   [(set_attr "type" "rotate")
11981    (set_attr "mode" "QI")])
11982
11983 (define_expand "rotrdi3"
11984   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11985         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11986                      (match_operand:QI 2 "nonmemory_operand" "")))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "TARGET_64BIT"
11989   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11990
11991 (define_insn "*rotrdi3_1_one_bit_rex64"
11992   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11993         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11994                      (match_operand:QI 2 "const1_operand" "")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11997    && (TARGET_SHIFT1 || optimize_size)"
11998   "ror{q}\t%0"
11999   [(set_attr "type" "rotate")
12000    (set (attr "length") 
12001      (if_then_else (match_operand:DI 0 "register_operand" "") 
12002         (const_string "2")
12003         (const_string "*")))])
12004
12005 (define_insn "*rotrdi3_1_rex64"
12006   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12007         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12008                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12009    (clobber (reg:CC FLAGS_REG))]
12010   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12011   "@
12012    ror{q}\t{%2, %0|%0, %2}
12013    ror{q}\t{%b2, %0|%0, %b2}"
12014   [(set_attr "type" "rotate")
12015    (set_attr "mode" "DI")])
12016
12017 (define_expand "rotrsi3"
12018   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12019         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12020                      (match_operand:QI 2 "nonmemory_operand" "")))
12021    (clobber (reg:CC FLAGS_REG))]
12022   ""
12023   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12024
12025 (define_insn "*rotrsi3_1_one_bit"
12026   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12027         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12028                      (match_operand:QI 2 "const1_operand" "")))
12029    (clobber (reg:CC FLAGS_REG))]
12030   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12031    && (TARGET_SHIFT1 || optimize_size)"
12032   "ror{l}\t%0"
12033   [(set_attr "type" "rotate")
12034    (set (attr "length") 
12035      (if_then_else (match_operand:SI 0 "register_operand" "") 
12036         (const_string "2")
12037         (const_string "*")))])
12038
12039 (define_insn "*rotrsi3_1_one_bit_zext"
12040   [(set (match_operand:DI 0 "register_operand" "=r")
12041         (zero_extend:DI
12042           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12043                        (match_operand:QI 2 "const1_operand" ""))))
12044    (clobber (reg:CC FLAGS_REG))]
12045   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12046    && (TARGET_SHIFT1 || optimize_size)"
12047   "ror{l}\t%k0"
12048   [(set_attr "type" "rotate")
12049    (set (attr "length") 
12050      (if_then_else (match_operand:SI 0 "register_operand" "") 
12051         (const_string "2")
12052         (const_string "*")))])
12053
12054 (define_insn "*rotrsi3_1"
12055   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12056         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12057                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12058    (clobber (reg:CC FLAGS_REG))]
12059   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12060   "@
12061    ror{l}\t{%2, %0|%0, %2}
12062    ror{l}\t{%b2, %0|%0, %b2}"
12063   [(set_attr "type" "rotate")
12064    (set_attr "mode" "SI")])
12065
12066 (define_insn "*rotrsi3_1_zext"
12067   [(set (match_operand:DI 0 "register_operand" "=r,r")
12068         (zero_extend:DI
12069           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12070                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12071    (clobber (reg:CC FLAGS_REG))]
12072   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12073   "@
12074    ror{l}\t{%2, %k0|%k0, %2}
12075    ror{l}\t{%b2, %k0|%k0, %b2}"
12076   [(set_attr "type" "rotate")
12077    (set_attr "mode" "SI")])
12078
12079 (define_expand "rotrhi3"
12080   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12081         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12082                      (match_operand:QI 2 "nonmemory_operand" "")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "TARGET_HIMODE_MATH"
12085   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12086
12087 (define_insn "*rotrhi3_one_bit"
12088   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12089         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12090                      (match_operand:QI 2 "const1_operand" "")))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12093    && (TARGET_SHIFT1 || optimize_size)"
12094   "ror{w}\t%0"
12095   [(set_attr "type" "rotate")
12096    (set (attr "length") 
12097      (if_then_else (match_operand 0 "register_operand" "") 
12098         (const_string "2")
12099         (const_string "*")))])
12100
12101 (define_insn "*rotrhi3"
12102   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12103         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12104                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12105    (clobber (reg:CC FLAGS_REG))]
12106   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12107   "@
12108    ror{w}\t{%2, %0|%0, %2}
12109    ror{w}\t{%b2, %0|%0, %b2}"
12110   [(set_attr "type" "rotate")
12111    (set_attr "mode" "HI")])
12112
12113 (define_expand "rotrqi3"
12114   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12115         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12116                      (match_operand:QI 2 "nonmemory_operand" "")))
12117    (clobber (reg:CC FLAGS_REG))]
12118   "TARGET_QIMODE_MATH"
12119   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12120
12121 (define_insn "*rotrqi3_1_one_bit"
12122   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12123         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12124                      (match_operand:QI 2 "const1_operand" "")))
12125    (clobber (reg:CC FLAGS_REG))]
12126   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12127    && (TARGET_SHIFT1 || optimize_size)"
12128   "ror{b}\t%0"
12129   [(set_attr "type" "rotate")
12130    (set (attr "length") 
12131      (if_then_else (match_operand 0 "register_operand" "") 
12132         (const_string "2")
12133         (const_string "*")))])
12134
12135 (define_insn "*rotrqi3_1_one_bit_slp"
12136   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12137         (rotatert:QI (match_dup 0)
12138                      (match_operand:QI 1 "const1_operand" "")))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12141    && (TARGET_SHIFT1 || optimize_size)"
12142   "ror{b}\t%0"
12143   [(set_attr "type" "rotate1")
12144    (set (attr "length") 
12145      (if_then_else (match_operand 0 "register_operand" "") 
12146         (const_string "2")
12147         (const_string "*")))])
12148
12149 (define_insn "*rotrqi3_1"
12150   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12151         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12152                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12153    (clobber (reg:CC FLAGS_REG))]
12154   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12155   "@
12156    ror{b}\t{%2, %0|%0, %2}
12157    ror{b}\t{%b2, %0|%0, %b2}"
12158   [(set_attr "type" "rotate")
12159    (set_attr "mode" "QI")])
12160
12161 (define_insn "*rotrqi3_1_slp"
12162   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12163         (rotatert:QI (match_dup 0)
12164                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12165    (clobber (reg:CC FLAGS_REG))]
12166   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12168   "@
12169    ror{b}\t{%1, %0|%0, %1}
12170    ror{b}\t{%b1, %0|%0, %b1}"
12171   [(set_attr "type" "rotate1")
12172    (set_attr "mode" "QI")])
12173 \f
12174 ;; Bit set / bit test instructions
12175
12176 (define_expand "extv"
12177   [(set (match_operand:SI 0 "register_operand" "")
12178         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12179                          (match_operand:SI 2 "immediate_operand" "")
12180                          (match_operand:SI 3 "immediate_operand" "")))]
12181   ""
12182 {
12183   /* Handle extractions from %ah et al.  */
12184   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12185     FAIL;
12186
12187   /* From mips.md: extract_bit_field doesn't verify that our source
12188      matches the predicate, so check it again here.  */
12189   if (! register_operand (operands[1], VOIDmode))
12190     FAIL;
12191 })
12192
12193 (define_expand "extzv"
12194   [(set (match_operand:SI 0 "register_operand" "")
12195         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12196                          (match_operand:SI 2 "immediate_operand" "")
12197                          (match_operand:SI 3 "immediate_operand" "")))]
12198   ""
12199 {
12200   /* Handle extractions from %ah et al.  */
12201   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12202     FAIL;
12203
12204   /* From mips.md: extract_bit_field doesn't verify that our source
12205      matches the predicate, so check it again here.  */
12206   if (! register_operand (operands[1], VOIDmode))
12207     FAIL;
12208 })
12209
12210 (define_expand "insv"
12211   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12212                       (match_operand 1 "immediate_operand" "")
12213                       (match_operand 2 "immediate_operand" ""))
12214         (match_operand 3 "register_operand" ""))]
12215   ""
12216 {
12217   /* Handle extractions from %ah et al.  */
12218   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12219     FAIL;
12220
12221   /* From mips.md: insert_bit_field doesn't verify that our source
12222      matches the predicate, so check it again here.  */
12223   if (! register_operand (operands[0], VOIDmode))
12224     FAIL;
12225
12226   if (TARGET_64BIT)
12227     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12228   else
12229     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12230
12231   DONE;
12232 })
12233
12234 ;; %%% bts, btr, btc, bt.
12235 ;; In general these instructions are *slow* when applied to memory,
12236 ;; since they enforce atomic operation.  When applied to registers,
12237 ;; it depends on the cpu implementation.  They're never faster than
12238 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12239 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12240 ;; within the instruction itself, so operating on bits in the high
12241 ;; 32-bits of a register becomes easier.
12242 ;;
12243 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12244 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12245 ;; negdf respectively, so they can never be disabled entirely.
12246
12247 (define_insn "*btsq"
12248   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12249                          (const_int 1)
12250                          (match_operand 1 "const_0_to_63_operand" ""))
12251         (const_int 1))
12252    (clobber (reg:CC FLAGS_REG))]
12253   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12254   "bts{q} %1,%0"
12255   [(set_attr "type" "alu1")])
12256
12257 (define_insn "*btrq"
12258   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12259                          (const_int 1)
12260                          (match_operand 1 "const_0_to_63_operand" ""))
12261         (const_int 0))
12262    (clobber (reg:CC FLAGS_REG))]
12263   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12264   "btr{q} %1,%0"
12265   [(set_attr "type" "alu1")])
12266
12267 (define_insn "*btcq"
12268   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12269                          (const_int 1)
12270                          (match_operand 1 "const_0_to_63_operand" ""))
12271         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12272    (clobber (reg:CC FLAGS_REG))]
12273   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12274   "btc{q} %1,%0"
12275   [(set_attr "type" "alu1")])
12276
12277 ;; Allow Nocona to avoid these instructions if a register is available.
12278
12279 (define_peephole2
12280   [(match_scratch:DI 2 "r")
12281    (parallel [(set (zero_extract:DI
12282                      (match_operand 0 "register_operand" "")
12283                      (const_int 1)
12284                      (match_operand 1 "const_0_to_63_operand" ""))
12285                    (const_int 1))
12286               (clobber (reg:CC FLAGS_REG))])]
12287   "TARGET_64BIT && !TARGET_USE_BT"
12288   [(const_int 0)]
12289 {
12290   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12291   rtx op1;
12292
12293   if (HOST_BITS_PER_WIDE_INT >= 64)
12294     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12295   else if (i < HOST_BITS_PER_WIDE_INT)
12296     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12297   else
12298     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12299
12300   op1 = immed_double_const (lo, hi, DImode);
12301   if (i >= 31)
12302     {
12303       emit_move_insn (operands[2], op1);
12304       op1 = operands[2];
12305     }
12306
12307   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12308   DONE;
12309 })
12310
12311 (define_peephole2
12312   [(match_scratch:DI 2 "r")
12313    (parallel [(set (zero_extract:DI
12314                      (match_operand 0 "register_operand" "")
12315                      (const_int 1)
12316                      (match_operand 1 "const_0_to_63_operand" ""))
12317                    (const_int 0))
12318               (clobber (reg:CC FLAGS_REG))])]
12319   "TARGET_64BIT && !TARGET_USE_BT"
12320   [(const_int 0)]
12321 {
12322   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12323   rtx op1;
12324
12325   if (HOST_BITS_PER_WIDE_INT >= 64)
12326     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12327   else if (i < HOST_BITS_PER_WIDE_INT)
12328     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12329   else
12330     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12331
12332   op1 = immed_double_const (~lo, ~hi, DImode);
12333   if (i >= 32)
12334     {
12335       emit_move_insn (operands[2], op1);
12336       op1 = operands[2];
12337     }
12338
12339   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12340   DONE;
12341 })
12342
12343 (define_peephole2
12344   [(match_scratch:DI 2 "r")
12345    (parallel [(set (zero_extract:DI
12346                      (match_operand 0 "register_operand" "")
12347                      (const_int 1)
12348                      (match_operand 1 "const_0_to_63_operand" ""))
12349               (not:DI (zero_extract:DI
12350                         (match_dup 0) (const_int 1) (match_dup 1))))
12351               (clobber (reg:CC FLAGS_REG))])]
12352   "TARGET_64BIT && !TARGET_USE_BT"
12353   [(const_int 0)]
12354 {
12355   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12356   rtx op1;
12357
12358   if (HOST_BITS_PER_WIDE_INT >= 64)
12359     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12360   else if (i < HOST_BITS_PER_WIDE_INT)
12361     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12362   else
12363     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12364
12365   op1 = immed_double_const (lo, hi, DImode);
12366   if (i >= 31)
12367     {
12368       emit_move_insn (operands[2], op1);
12369       op1 = operands[2];
12370     }
12371
12372   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12373   DONE;
12374 })
12375 \f
12376 ;; Store-flag instructions.
12377
12378 ;; For all sCOND expanders, also expand the compare or test insn that
12379 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12380
12381 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12382 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12383 ;; way, which can later delete the movzx if only QImode is needed.
12384
12385 (define_expand "seq"
12386   [(set (match_operand:QI 0 "register_operand" "")
12387         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12388   ""
12389   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12390
12391 (define_expand "sne"
12392   [(set (match_operand:QI 0 "register_operand" "")
12393         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12394   ""
12395   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12396
12397 (define_expand "sgt"
12398   [(set (match_operand:QI 0 "register_operand" "")
12399         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12400   ""
12401   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12402
12403 (define_expand "sgtu"
12404   [(set (match_operand:QI 0 "register_operand" "")
12405         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12406   ""
12407   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12408
12409 (define_expand "slt"
12410   [(set (match_operand:QI 0 "register_operand" "")
12411         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12412   ""
12413   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12414
12415 (define_expand "sltu"
12416   [(set (match_operand:QI 0 "register_operand" "")
12417         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12418   ""
12419   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12420
12421 (define_expand "sge"
12422   [(set (match_operand:QI 0 "register_operand" "")
12423         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12424   ""
12425   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12426
12427 (define_expand "sgeu"
12428   [(set (match_operand:QI 0 "register_operand" "")
12429         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12430   ""
12431   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12432
12433 (define_expand "sle"
12434   [(set (match_operand:QI 0 "register_operand" "")
12435         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12436   ""
12437   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12438
12439 (define_expand "sleu"
12440   [(set (match_operand:QI 0 "register_operand" "")
12441         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12442   ""
12443   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12444
12445 (define_expand "sunordered"
12446   [(set (match_operand:QI 0 "register_operand" "")
12447         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12448   "TARGET_80387 || TARGET_SSE"
12449   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12450
12451 (define_expand "sordered"
12452   [(set (match_operand:QI 0 "register_operand" "")
12453         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12454   "TARGET_80387"
12455   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12456
12457 (define_expand "suneq"
12458   [(set (match_operand:QI 0 "register_operand" "")
12459         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12460   "TARGET_80387 || TARGET_SSE"
12461   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12462
12463 (define_expand "sunge"
12464   [(set (match_operand:QI 0 "register_operand" "")
12465         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12466   "TARGET_80387 || TARGET_SSE"
12467   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12468
12469 (define_expand "sungt"
12470   [(set (match_operand:QI 0 "register_operand" "")
12471         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12472   "TARGET_80387 || TARGET_SSE"
12473   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12474
12475 (define_expand "sunle"
12476   [(set (match_operand:QI 0 "register_operand" "")
12477         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12478   "TARGET_80387 || TARGET_SSE"
12479   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12480
12481 (define_expand "sunlt"
12482   [(set (match_operand:QI 0 "register_operand" "")
12483         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12484   "TARGET_80387 || TARGET_SSE"
12485   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12486
12487 (define_expand "sltgt"
12488   [(set (match_operand:QI 0 "register_operand" "")
12489         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12490   "TARGET_80387 || TARGET_SSE"
12491   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12492
12493 (define_insn "*setcc_1"
12494   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12495         (match_operator:QI 1 "ix86_comparison_operator"
12496           [(reg FLAGS_REG) (const_int 0)]))]
12497   ""
12498   "set%C1\t%0"
12499   [(set_attr "type" "setcc")
12500    (set_attr "mode" "QI")])
12501
12502 (define_insn "*setcc_2"
12503   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12504         (match_operator:QI 1 "ix86_comparison_operator"
12505           [(reg FLAGS_REG) (const_int 0)]))]
12506   ""
12507   "set%C1\t%0"
12508   [(set_attr "type" "setcc")
12509    (set_attr "mode" "QI")])
12510
12511 ;; In general it is not safe to assume too much about CCmode registers,
12512 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12513 ;; conditions this is safe on x86, so help combine not create
12514 ;;
12515 ;;      seta    %al
12516 ;;      testb   %al, %al
12517 ;;      sete    %al
12518
12519 (define_split 
12520   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12521         (ne:QI (match_operator 1 "ix86_comparison_operator"
12522                  [(reg FLAGS_REG) (const_int 0)])
12523             (const_int 0)))]
12524   ""
12525   [(set (match_dup 0) (match_dup 1))]
12526 {
12527   PUT_MODE (operands[1], QImode);
12528 })
12529
12530 (define_split 
12531   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12532         (ne:QI (match_operator 1 "ix86_comparison_operator"
12533                  [(reg FLAGS_REG) (const_int 0)])
12534             (const_int 0)))]
12535   ""
12536   [(set (match_dup 0) (match_dup 1))]
12537 {
12538   PUT_MODE (operands[1], QImode);
12539 })
12540
12541 (define_split 
12542   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12543         (eq:QI (match_operator 1 "ix86_comparison_operator"
12544                  [(reg FLAGS_REG) (const_int 0)])
12545             (const_int 0)))]
12546   ""
12547   [(set (match_dup 0) (match_dup 1))]
12548 {
12549   rtx new_op1 = copy_rtx (operands[1]);
12550   operands[1] = new_op1;
12551   PUT_MODE (new_op1, QImode);
12552   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12553                                              GET_MODE (XEXP (new_op1, 0))));
12554
12555   /* Make sure that (a) the CCmode we have for the flags is strong
12556      enough for the reversed compare or (b) we have a valid FP compare.  */
12557   if (! ix86_comparison_operator (new_op1, VOIDmode))
12558     FAIL;
12559 })
12560
12561 (define_split 
12562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12563         (eq:QI (match_operator 1 "ix86_comparison_operator"
12564                  [(reg FLAGS_REG) (const_int 0)])
12565             (const_int 0)))]
12566   ""
12567   [(set (match_dup 0) (match_dup 1))]
12568 {
12569   rtx new_op1 = copy_rtx (operands[1]);
12570   operands[1] = new_op1;
12571   PUT_MODE (new_op1, QImode);
12572   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12573                                              GET_MODE (XEXP (new_op1, 0))));
12574
12575   /* Make sure that (a) the CCmode we have for the flags is strong
12576      enough for the reversed compare or (b) we have a valid FP compare.  */
12577   if (! ix86_comparison_operator (new_op1, VOIDmode))
12578     FAIL;
12579 })
12580
12581 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12582 ;; subsequent logical operations are used to imitate conditional moves.
12583 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12584 ;; it directly.  Further holding this value in pseudo register might bring
12585 ;; problem in implicit normalization in spill code.
12586 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12587 ;; instructions after reload by splitting the conditional move patterns.
12588
12589 (define_insn "*sse_setccsf"
12590   [(set (match_operand:SF 0 "register_operand" "=x")
12591         (match_operator:SF 1 "sse_comparison_operator"
12592           [(match_operand:SF 2 "register_operand" "0")
12593            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12594   "TARGET_SSE && reload_completed"
12595   "cmp%D1ss\t{%3, %0|%0, %3}"
12596   [(set_attr "type" "ssecmp")
12597    (set_attr "mode" "SF")])
12598
12599 (define_insn "*sse_setccdf"
12600   [(set (match_operand:DF 0 "register_operand" "=Y")
12601         (match_operator:DF 1 "sse_comparison_operator"
12602           [(match_operand:DF 2 "register_operand" "0")
12603            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12604   "TARGET_SSE2 && reload_completed"
12605   "cmp%D1sd\t{%3, %0|%0, %3}"
12606   [(set_attr "type" "ssecmp")
12607    (set_attr "mode" "DF")])
12608 \f
12609 ;; Basic conditional jump instructions.
12610 ;; We ignore the overflow flag for signed branch instructions.
12611
12612 ;; For all bCOND expanders, also expand the compare or test insn that
12613 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12614
12615 (define_expand "beq"
12616   [(set (pc)
12617         (if_then_else (match_dup 1)
12618                       (label_ref (match_operand 0 "" ""))
12619                       (pc)))]
12620   ""
12621   "ix86_expand_branch (EQ, operands[0]); DONE;")
12622
12623 (define_expand "bne"
12624   [(set (pc)
12625         (if_then_else (match_dup 1)
12626                       (label_ref (match_operand 0 "" ""))
12627                       (pc)))]
12628   ""
12629   "ix86_expand_branch (NE, operands[0]); DONE;")
12630
12631 (define_expand "bgt"
12632   [(set (pc)
12633         (if_then_else (match_dup 1)
12634                       (label_ref (match_operand 0 "" ""))
12635                       (pc)))]
12636   ""
12637   "ix86_expand_branch (GT, operands[0]); DONE;")
12638
12639 (define_expand "bgtu"
12640   [(set (pc)
12641         (if_then_else (match_dup 1)
12642                       (label_ref (match_operand 0 "" ""))
12643                       (pc)))]
12644   ""
12645   "ix86_expand_branch (GTU, operands[0]); DONE;")
12646
12647 (define_expand "blt"
12648   [(set (pc)
12649         (if_then_else (match_dup 1)
12650                       (label_ref (match_operand 0 "" ""))
12651                       (pc)))]
12652   ""
12653   "ix86_expand_branch (LT, operands[0]); DONE;")
12654
12655 (define_expand "bltu"
12656   [(set (pc)
12657         (if_then_else (match_dup 1)
12658                       (label_ref (match_operand 0 "" ""))
12659                       (pc)))]
12660   ""
12661   "ix86_expand_branch (LTU, operands[0]); DONE;")
12662
12663 (define_expand "bge"
12664   [(set (pc)
12665         (if_then_else (match_dup 1)
12666                       (label_ref (match_operand 0 "" ""))
12667                       (pc)))]
12668   ""
12669   "ix86_expand_branch (GE, operands[0]); DONE;")
12670
12671 (define_expand "bgeu"
12672   [(set (pc)
12673         (if_then_else (match_dup 1)
12674                       (label_ref (match_operand 0 "" ""))
12675                       (pc)))]
12676   ""
12677   "ix86_expand_branch (GEU, operands[0]); DONE;")
12678
12679 (define_expand "ble"
12680   [(set (pc)
12681         (if_then_else (match_dup 1)
12682                       (label_ref (match_operand 0 "" ""))
12683                       (pc)))]
12684   ""
12685   "ix86_expand_branch (LE, operands[0]); DONE;")
12686
12687 (define_expand "bleu"
12688   [(set (pc)
12689         (if_then_else (match_dup 1)
12690                       (label_ref (match_operand 0 "" ""))
12691                       (pc)))]
12692   ""
12693   "ix86_expand_branch (LEU, operands[0]); DONE;")
12694
12695 (define_expand "bunordered"
12696   [(set (pc)
12697         (if_then_else (match_dup 1)
12698                       (label_ref (match_operand 0 "" ""))
12699                       (pc)))]
12700   "TARGET_80387 || TARGET_SSE"
12701   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12702
12703 (define_expand "bordered"
12704   [(set (pc)
12705         (if_then_else (match_dup 1)
12706                       (label_ref (match_operand 0 "" ""))
12707                       (pc)))]
12708   "TARGET_80387 || TARGET_SSE"
12709   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12710
12711 (define_expand "buneq"
12712   [(set (pc)
12713         (if_then_else (match_dup 1)
12714                       (label_ref (match_operand 0 "" ""))
12715                       (pc)))]
12716   "TARGET_80387 || TARGET_SSE"
12717   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12718
12719 (define_expand "bunge"
12720   [(set (pc)
12721         (if_then_else (match_dup 1)
12722                       (label_ref (match_operand 0 "" ""))
12723                       (pc)))]
12724   "TARGET_80387 || TARGET_SSE"
12725   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12726
12727 (define_expand "bungt"
12728   [(set (pc)
12729         (if_then_else (match_dup 1)
12730                       (label_ref (match_operand 0 "" ""))
12731                       (pc)))]
12732   "TARGET_80387 || TARGET_SSE"
12733   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12734
12735 (define_expand "bunle"
12736   [(set (pc)
12737         (if_then_else (match_dup 1)
12738                       (label_ref (match_operand 0 "" ""))
12739                       (pc)))]
12740   "TARGET_80387 || TARGET_SSE"
12741   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12742
12743 (define_expand "bunlt"
12744   [(set (pc)
12745         (if_then_else (match_dup 1)
12746                       (label_ref (match_operand 0 "" ""))
12747                       (pc)))]
12748   "TARGET_80387 || TARGET_SSE"
12749   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12750
12751 (define_expand "bltgt"
12752   [(set (pc)
12753         (if_then_else (match_dup 1)
12754                       (label_ref (match_operand 0 "" ""))
12755                       (pc)))]
12756   "TARGET_80387 || TARGET_SSE"
12757   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12758
12759 (define_insn "*jcc_1"
12760   [(set (pc)
12761         (if_then_else (match_operator 1 "ix86_comparison_operator"
12762                                       [(reg FLAGS_REG) (const_int 0)])
12763                       (label_ref (match_operand 0 "" ""))
12764                       (pc)))]
12765   ""
12766   "%+j%C1\t%l0"
12767   [(set_attr "type" "ibr")
12768    (set_attr "modrm" "0")
12769    (set (attr "length")
12770            (if_then_else (and (ge (minus (match_dup 0) (pc))
12771                                   (const_int -126))
12772                               (lt (minus (match_dup 0) (pc))
12773                                   (const_int 128)))
12774              (const_int 2)
12775              (const_int 6)))])
12776
12777 (define_insn "*jcc_2"
12778   [(set (pc)
12779         (if_then_else (match_operator 1 "ix86_comparison_operator"
12780                                       [(reg FLAGS_REG) (const_int 0)])
12781                       (pc)
12782                       (label_ref (match_operand 0 "" ""))))]
12783   ""
12784   "%+j%c1\t%l0"
12785   [(set_attr "type" "ibr")
12786    (set_attr "modrm" "0")
12787    (set (attr "length")
12788            (if_then_else (and (ge (minus (match_dup 0) (pc))
12789                                   (const_int -126))
12790                               (lt (minus (match_dup 0) (pc))
12791                                   (const_int 128)))
12792              (const_int 2)
12793              (const_int 6)))])
12794
12795 ;; In general it is not safe to assume too much about CCmode registers,
12796 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12797 ;; conditions this is safe on x86, so help combine not create
12798 ;;
12799 ;;      seta    %al
12800 ;;      testb   %al, %al
12801 ;;      je      Lfoo
12802
12803 (define_split 
12804   [(set (pc)
12805         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12806                                       [(reg FLAGS_REG) (const_int 0)])
12807                           (const_int 0))
12808                       (label_ref (match_operand 1 "" ""))
12809                       (pc)))]
12810   ""
12811   [(set (pc)
12812         (if_then_else (match_dup 0)
12813                       (label_ref (match_dup 1))
12814                       (pc)))]
12815 {
12816   PUT_MODE (operands[0], VOIDmode);
12817 })
12818   
12819 (define_split 
12820   [(set (pc)
12821         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12822                                       [(reg FLAGS_REG) (const_int 0)])
12823                           (const_int 0))
12824                       (label_ref (match_operand 1 "" ""))
12825                       (pc)))]
12826   ""
12827   [(set (pc)
12828         (if_then_else (match_dup 0)
12829                       (label_ref (match_dup 1))
12830                       (pc)))]
12831 {
12832   rtx new_op0 = copy_rtx (operands[0]);
12833   operands[0] = new_op0;
12834   PUT_MODE (new_op0, VOIDmode);
12835   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12836                                              GET_MODE (XEXP (new_op0, 0))));
12837
12838   /* Make sure that (a) the CCmode we have for the flags is strong
12839      enough for the reversed compare or (b) we have a valid FP compare.  */
12840   if (! ix86_comparison_operator (new_op0, VOIDmode))
12841     FAIL;
12842 })
12843
12844 ;; Define combination compare-and-branch fp compare instructions to use
12845 ;; during early optimization.  Splitting the operation apart early makes
12846 ;; for bad code when we want to reverse the operation.
12847
12848 (define_insn "*fp_jcc_1"
12849   [(set (pc)
12850         (if_then_else (match_operator 0 "comparison_operator"
12851                         [(match_operand 1 "register_operand" "f")
12852                          (match_operand 2 "register_operand" "f")])
12853           (label_ref (match_operand 3 "" ""))
12854           (pc)))
12855    (clobber (reg:CCFP FPSR_REG))
12856    (clobber (reg:CCFP FLAGS_REG))]
12857   "TARGET_CMOVE && TARGET_80387
12858    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12859    && FLOAT_MODE_P (GET_MODE (operands[1]))
12860    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12861    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12862   "#")
12863
12864 (define_insn "*fp_jcc_1_sse"
12865   [(set (pc)
12866         (if_then_else (match_operator 0 "comparison_operator"
12867                         [(match_operand 1 "register_operand" "f#x,x#f")
12868                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12869           (label_ref (match_operand 3 "" ""))
12870           (pc)))
12871    (clobber (reg:CCFP FPSR_REG))
12872    (clobber (reg:CCFP FLAGS_REG))]
12873   "TARGET_80387
12874    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12875    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12876    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12877   "#")
12878
12879 (define_insn "*fp_jcc_1_sse_only"
12880   [(set (pc)
12881         (if_then_else (match_operator 0 "comparison_operator"
12882                         [(match_operand 1 "register_operand" "x")
12883                          (match_operand 2 "nonimmediate_operand" "xm")])
12884           (label_ref (match_operand 3 "" ""))
12885           (pc)))
12886    (clobber (reg:CCFP FPSR_REG))
12887    (clobber (reg:CCFP FLAGS_REG))]
12888   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12889    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12890    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12891   "#")
12892
12893 (define_insn "*fp_jcc_2"
12894   [(set (pc)
12895         (if_then_else (match_operator 0 "comparison_operator"
12896                         [(match_operand 1 "register_operand" "f")
12897                          (match_operand 2 "register_operand" "f")])
12898           (pc)
12899           (label_ref (match_operand 3 "" ""))))
12900    (clobber (reg:CCFP FPSR_REG))
12901    (clobber (reg:CCFP FLAGS_REG))]
12902   "TARGET_CMOVE && TARGET_80387
12903    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12904    && FLOAT_MODE_P (GET_MODE (operands[1]))
12905    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12906    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12907   "#")
12908
12909 (define_insn "*fp_jcc_2_sse"
12910   [(set (pc)
12911         (if_then_else (match_operator 0 "comparison_operator"
12912                         [(match_operand 1 "register_operand" "f#x,x#f")
12913                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12914           (pc)
12915           (label_ref (match_operand 3 "" ""))))
12916    (clobber (reg:CCFP FPSR_REG))
12917    (clobber (reg:CCFP FLAGS_REG))]
12918   "TARGET_80387
12919    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12920    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12921    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12922   "#")
12923
12924 (define_insn "*fp_jcc_2_sse_only"
12925   [(set (pc)
12926         (if_then_else (match_operator 0 "comparison_operator"
12927                         [(match_operand 1 "register_operand" "x")
12928                          (match_operand 2 "nonimmediate_operand" "xm")])
12929           (pc)
12930           (label_ref (match_operand 3 "" ""))))
12931    (clobber (reg:CCFP FPSR_REG))
12932    (clobber (reg:CCFP FLAGS_REG))]
12933   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12934    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12935    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12936   "#")
12937
12938 (define_insn "*fp_jcc_3"
12939   [(set (pc)
12940         (if_then_else (match_operator 0 "comparison_operator"
12941                         [(match_operand 1 "register_operand" "f")
12942                          (match_operand 2 "nonimmediate_operand" "fm")])
12943           (label_ref (match_operand 3 "" ""))
12944           (pc)))
12945    (clobber (reg:CCFP FPSR_REG))
12946    (clobber (reg:CCFP FLAGS_REG))
12947    (clobber (match_scratch:HI 4 "=a"))]
12948   "TARGET_80387
12949    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12950    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12951    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12952    && SELECT_CC_MODE (GET_CODE (operands[0]),
12953                       operands[1], operands[2]) == CCFPmode
12954    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12955   "#")
12956
12957 (define_insn "*fp_jcc_4"
12958   [(set (pc)
12959         (if_then_else (match_operator 0 "comparison_operator"
12960                         [(match_operand 1 "register_operand" "f")
12961                          (match_operand 2 "nonimmediate_operand" "fm")])
12962           (pc)
12963           (label_ref (match_operand 3 "" ""))))
12964    (clobber (reg:CCFP FPSR_REG))
12965    (clobber (reg:CCFP FLAGS_REG))
12966    (clobber (match_scratch:HI 4 "=a"))]
12967   "TARGET_80387
12968    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12969    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12970    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12971    && SELECT_CC_MODE (GET_CODE (operands[0]),
12972                       operands[1], operands[2]) == CCFPmode
12973    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12974   "#")
12975
12976 (define_insn "*fp_jcc_5"
12977   [(set (pc)
12978         (if_then_else (match_operator 0 "comparison_operator"
12979                         [(match_operand 1 "register_operand" "f")
12980                          (match_operand 2 "register_operand" "f")])
12981           (label_ref (match_operand 3 "" ""))
12982           (pc)))
12983    (clobber (reg:CCFP FPSR_REG))
12984    (clobber (reg:CCFP FLAGS_REG))
12985    (clobber (match_scratch:HI 4 "=a"))]
12986   "TARGET_80387
12987    && FLOAT_MODE_P (GET_MODE (operands[1]))
12988    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12989    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12990   "#")
12991
12992 (define_insn "*fp_jcc_6"
12993   [(set (pc)
12994         (if_then_else (match_operator 0 "comparison_operator"
12995                         [(match_operand 1 "register_operand" "f")
12996                          (match_operand 2 "register_operand" "f")])
12997           (pc)
12998           (label_ref (match_operand 3 "" ""))))
12999    (clobber (reg:CCFP FPSR_REG))
13000    (clobber (reg:CCFP FLAGS_REG))
13001    (clobber (match_scratch:HI 4 "=a"))]
13002   "TARGET_80387
13003    && FLOAT_MODE_P (GET_MODE (operands[1]))
13004    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13005    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13006   "#")
13007
13008 (define_insn "*fp_jcc_7"
13009   [(set (pc)
13010         (if_then_else (match_operator 0 "comparison_operator"
13011                         [(match_operand 1 "register_operand" "f")
13012                          (match_operand 2 "const_double_operand" "C")])
13013           (label_ref (match_operand 3 "" ""))
13014           (pc)))
13015    (clobber (reg:CCFP FPSR_REG))
13016    (clobber (reg:CCFP FLAGS_REG))
13017    (clobber (match_scratch:HI 4 "=a"))]
13018   "TARGET_80387
13019    && FLOAT_MODE_P (GET_MODE (operands[1]))
13020    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13021    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13022    && SELECT_CC_MODE (GET_CODE (operands[0]),
13023                       operands[1], operands[2]) == CCFPmode
13024    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13025   "#")
13026
13027 ;; The order of operands in *fp_jcc_8 is forced by combine in
13028 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13029 ;; with a precedence over other operators and is always put in the first
13030 ;; place. Swap condition and operands to match ficom instruction.
13031
13032 (define_insn "*fp_jcc_8"
13033   [(set (pc)
13034         (if_then_else (match_operator 0 "comparison_operator"
13035                         [(match_operator 1 "float_operator"
13036                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13037                            (match_operand 3 "register_operand" "f,f")])
13038           (label_ref (match_operand 4 "" ""))
13039           (pc)))
13040    (clobber (reg:CCFP FPSR_REG))
13041    (clobber (reg:CCFP FLAGS_REG))
13042    (clobber (match_scratch:HI 5 "=a,a"))]
13043   "TARGET_80387 && TARGET_USE_FIOP
13044    && FLOAT_MODE_P (GET_MODE (operands[3]))
13045    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13046    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13047    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13048    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13049   "#")
13050
13051 (define_split
13052   [(set (pc)
13053         (if_then_else (match_operator 0 "comparison_operator"
13054                         [(match_operand 1 "register_operand" "")
13055                          (match_operand 2 "nonimmediate_operand" "")])
13056           (match_operand 3 "" "")
13057           (match_operand 4 "" "")))
13058    (clobber (reg:CCFP FPSR_REG))
13059    (clobber (reg:CCFP FLAGS_REG))]
13060   "reload_completed"
13061   [(const_int 0)]
13062 {
13063   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13064                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13065   DONE;
13066 })
13067
13068 (define_split
13069   [(set (pc)
13070         (if_then_else (match_operator 0 "comparison_operator"
13071                         [(match_operand 1 "register_operand" "")
13072                          (match_operand 2 "general_operand" "")])
13073           (match_operand 3 "" "")
13074           (match_operand 4 "" "")))
13075    (clobber (reg:CCFP FPSR_REG))
13076    (clobber (reg:CCFP FLAGS_REG))
13077    (clobber (match_scratch:HI 5 "=a"))]
13078   "reload_completed"
13079   [(const_int 0)]
13080 {
13081   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13082                         operands[3], operands[4], operands[5], NULL_RTX);
13083   DONE;
13084 })
13085
13086 (define_split
13087   [(set (pc)
13088         (if_then_else (match_operator 0 "comparison_operator"
13089                         [(match_operator 1 "float_operator"
13090                            [(match_operand:SI 2 "memory_operand" "")])
13091                            (match_operand 3 "register_operand" "")])
13092           (match_operand 4 "" "")
13093           (match_operand 5 "" "")))
13094    (clobber (reg:CCFP FPSR_REG))
13095    (clobber (reg:CCFP FLAGS_REG))
13096    (clobber (match_scratch:HI 6 "=a"))]
13097   "reload_completed"
13098   [(const_int 0)]
13099 {
13100   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13101   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13102                         operands[3], operands[7],
13103                         operands[4], operands[5], operands[6], NULL_RTX);
13104   DONE;
13105 })
13106
13107 ;; %%% Kill this when reload knows how to do it.
13108 (define_split
13109   [(set (pc)
13110         (if_then_else (match_operator 0 "comparison_operator"
13111                         [(match_operator 1 "float_operator"
13112                            [(match_operand:SI 2 "register_operand" "")])
13113                            (match_operand 3 "register_operand" "")])
13114           (match_operand 4 "" "")
13115           (match_operand 5 "" "")))
13116    (clobber (reg:CCFP FPSR_REG))
13117    (clobber (reg:CCFP FLAGS_REG))
13118    (clobber (match_scratch:HI 6 "=a"))]
13119   "reload_completed"
13120   [(const_int 0)]
13121 {
13122   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13123   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13124   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13125                         operands[3], operands[7],
13126                         operands[4], operands[5], operands[6], operands[2]);
13127   DONE;
13128 })
13129 \f
13130 ;; Unconditional and other jump instructions
13131
13132 (define_insn "jump"
13133   [(set (pc)
13134         (label_ref (match_operand 0 "" "")))]
13135   ""
13136   "jmp\t%l0"
13137   [(set_attr "type" "ibr")
13138    (set (attr "length")
13139            (if_then_else (and (ge (minus (match_dup 0) (pc))
13140                                   (const_int -126))
13141                               (lt (minus (match_dup 0) (pc))
13142                                   (const_int 128)))
13143              (const_int 2)
13144              (const_int 5)))
13145    (set_attr "modrm" "0")])
13146
13147 (define_expand "indirect_jump"
13148   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13149   ""
13150   "")
13151
13152 (define_insn "*indirect_jump"
13153   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13154   "!TARGET_64BIT"
13155   "jmp\t%A0"
13156   [(set_attr "type" "ibr")
13157    (set_attr "length_immediate" "0")])
13158
13159 (define_insn "*indirect_jump_rtx64"
13160   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13161   "TARGET_64BIT"
13162   "jmp\t%A0"
13163   [(set_attr "type" "ibr")
13164    (set_attr "length_immediate" "0")])
13165
13166 (define_expand "tablejump"
13167   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13168               (use (label_ref (match_operand 1 "" "")))])]
13169   ""
13170 {
13171   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13172      relative.  Convert the relative address to an absolute address.  */
13173   if (flag_pic)
13174     {
13175       rtx op0, op1;
13176       enum rtx_code code;
13177
13178       if (TARGET_64BIT)
13179         {
13180           code = PLUS;
13181           op0 = operands[0];
13182           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13183         }
13184       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13185         {
13186           code = PLUS;
13187           op0 = operands[0];
13188           op1 = pic_offset_table_rtx;
13189         }
13190       else
13191         {
13192           code = MINUS;
13193           op0 = pic_offset_table_rtx;
13194           op1 = operands[0];
13195         }
13196
13197       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13198                                          OPTAB_DIRECT);
13199     }
13200 })
13201
13202 (define_insn "*tablejump_1"
13203   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13204    (use (label_ref (match_operand 1 "" "")))]
13205   "!TARGET_64BIT"
13206   "jmp\t%A0"
13207   [(set_attr "type" "ibr")
13208    (set_attr "length_immediate" "0")])
13209
13210 (define_insn "*tablejump_1_rtx64"
13211   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13212    (use (label_ref (match_operand 1 "" "")))]
13213   "TARGET_64BIT"
13214   "jmp\t%A0"
13215   [(set_attr "type" "ibr")
13216    (set_attr "length_immediate" "0")])
13217 \f
13218 ;; Loop instruction
13219 ;;
13220 ;; This is all complicated by the fact that since this is a jump insn
13221 ;; we must handle our own reloads.
13222
13223 (define_expand "doloop_end"
13224   [(use (match_operand 0 "" ""))        ; loop pseudo
13225    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13226    (use (match_operand 2 "" ""))        ; max iterations
13227    (use (match_operand 3 "" ""))        ; loop level 
13228    (use (match_operand 4 "" ""))]       ; label
13229   "!TARGET_64BIT && TARGET_USE_LOOP"
13230   "                                 
13231 {
13232   /* Only use cloop on innermost loops.  */
13233   if (INTVAL (operands[3]) > 1)
13234     FAIL;
13235   if (GET_MODE (operands[0]) != SImode)
13236     FAIL;
13237   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13238                                            operands[0]));
13239   DONE;
13240 }")
13241
13242 (define_insn "doloop_end_internal"
13243   [(set (pc)
13244         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13245                           (const_int 1))
13246                       (label_ref (match_operand 0 "" ""))
13247                       (pc)))
13248    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13249         (plus:SI (match_dup 1)
13250                  (const_int -1)))
13251    (clobber (match_scratch:SI 3 "=X,X,r"))
13252    (clobber (reg:CC FLAGS_REG))]
13253   "!TARGET_64BIT && TARGET_USE_LOOP
13254    && (reload_in_progress || reload_completed
13255        || register_operand (operands[2], VOIDmode))"
13256 {
13257   if (which_alternative != 0)
13258     return "#";
13259   if (get_attr_length (insn) == 2)
13260     return "%+loop\t%l0";
13261   else
13262     return "dec{l}\t%1\;%+jne\t%l0";
13263 }
13264   [(set (attr "length")
13265         (if_then_else (and (eq_attr "alternative" "0")
13266                            (and (ge (minus (match_dup 0) (pc))
13267                                     (const_int -126))
13268                                 (lt (minus (match_dup 0) (pc))
13269                                     (const_int 128))))
13270                       (const_int 2)
13271                       (const_int 16)))
13272    ;; We don't know the type before shorten branches.  Optimistically expect
13273    ;; the loop instruction to match.
13274    (set (attr "type") (const_string "ibr"))])
13275
13276 (define_split
13277   [(set (pc)
13278         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13279                           (const_int 1))
13280                       (match_operand 0 "" "")
13281                       (pc)))
13282    (set (match_dup 1)
13283         (plus:SI (match_dup 1)
13284                  (const_int -1)))
13285    (clobber (match_scratch:SI 2 ""))
13286    (clobber (reg:CC FLAGS_REG))]
13287   "!TARGET_64BIT && TARGET_USE_LOOP
13288    && reload_completed
13289    && REGNO (operands[1]) != 2"
13290   [(parallel [(set (reg:CCZ FLAGS_REG)
13291                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13292                                  (const_int 0)))
13293               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13294    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13295                            (match_dup 0)
13296                            (pc)))]
13297   "")
13298   
13299 (define_split
13300   [(set (pc)
13301         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13302                           (const_int 1))
13303                       (match_operand 0 "" "")
13304                       (pc)))
13305    (set (match_operand:SI 2 "nonimmediate_operand" "")
13306         (plus:SI (match_dup 1)
13307                  (const_int -1)))
13308    (clobber (match_scratch:SI 3 ""))
13309    (clobber (reg:CC FLAGS_REG))]
13310   "!TARGET_64BIT && TARGET_USE_LOOP
13311    && reload_completed
13312    && (! REG_P (operands[2])
13313        || ! rtx_equal_p (operands[1], operands[2]))"
13314   [(set (match_dup 3) (match_dup 1))
13315    (parallel [(set (reg:CCZ FLAGS_REG)
13316                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13317                                 (const_int 0)))
13318               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13319    (set (match_dup 2) (match_dup 3))
13320    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13321                            (match_dup 0)
13322                            (pc)))]
13323   "")
13324
13325 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13326
13327 (define_peephole2
13328   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13329    (set (match_operand:QI 1 "register_operand" "")
13330         (match_operator:QI 2 "ix86_comparison_operator"
13331           [(reg FLAGS_REG) (const_int 0)]))
13332    (set (match_operand 3 "q_regs_operand" "")
13333         (zero_extend (match_dup 1)))]
13334   "(peep2_reg_dead_p (3, operands[1])
13335     || operands_match_p (operands[1], operands[3]))
13336    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13337   [(set (match_dup 4) (match_dup 0))
13338    (set (strict_low_part (match_dup 5))
13339         (match_dup 2))]
13340 {
13341   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13342   operands[5] = gen_lowpart (QImode, operands[3]);
13343   ix86_expand_clear (operands[3]);
13344 })
13345
13346 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13347
13348 (define_peephole2
13349   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13350    (set (match_operand:QI 1 "register_operand" "")
13351         (match_operator:QI 2 "ix86_comparison_operator"
13352           [(reg FLAGS_REG) (const_int 0)]))
13353    (parallel [(set (match_operand 3 "q_regs_operand" "")
13354                    (zero_extend (match_dup 1)))
13355               (clobber (reg:CC FLAGS_REG))])]
13356   "(peep2_reg_dead_p (3, operands[1])
13357     || operands_match_p (operands[1], operands[3]))
13358    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13359   [(set (match_dup 4) (match_dup 0))
13360    (set (strict_low_part (match_dup 5))
13361         (match_dup 2))]
13362 {
13363   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13364   operands[5] = gen_lowpart (QImode, operands[3]);
13365   ix86_expand_clear (operands[3]);
13366 })
13367 \f
13368 ;; Call instructions.
13369
13370 ;; The predicates normally associated with named expanders are not properly
13371 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13372 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13373
13374 ;; Call subroutine returning no value.
13375
13376 (define_expand "call_pop"
13377   [(parallel [(call (match_operand:QI 0 "" "")
13378                     (match_operand:SI 1 "" ""))
13379               (set (reg:SI SP_REG)
13380                    (plus:SI (reg:SI SP_REG)
13381                             (match_operand:SI 3 "" "")))])]
13382   "!TARGET_64BIT"
13383 {
13384   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13385   DONE;
13386 })
13387
13388 (define_insn "*call_pop_0"
13389   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13390          (match_operand:SI 1 "" ""))
13391    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13392                             (match_operand:SI 2 "immediate_operand" "")))]
13393   "!TARGET_64BIT"
13394 {
13395   if (SIBLING_CALL_P (insn))
13396     return "jmp\t%P0";
13397   else
13398     return "call\t%P0";
13399 }
13400   [(set_attr "type" "call")])
13401   
13402 (define_insn "*call_pop_1"
13403   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13404          (match_operand:SI 1 "" ""))
13405    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13406                             (match_operand:SI 2 "immediate_operand" "i")))]
13407   "!TARGET_64BIT"
13408 {
13409   if (constant_call_address_operand (operands[0], Pmode))
13410     {
13411       if (SIBLING_CALL_P (insn))
13412         return "jmp\t%P0";
13413       else
13414         return "call\t%P0";
13415     }
13416   if (SIBLING_CALL_P (insn))
13417     return "jmp\t%A0";
13418   else
13419     return "call\t%A0";
13420 }
13421   [(set_attr "type" "call")])
13422
13423 (define_expand "call"
13424   [(call (match_operand:QI 0 "" "")
13425          (match_operand 1 "" ""))
13426    (use (match_operand 2 "" ""))]
13427   ""
13428 {
13429   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13430   DONE;
13431 })
13432
13433 (define_expand "sibcall"
13434   [(call (match_operand:QI 0 "" "")
13435          (match_operand 1 "" ""))
13436    (use (match_operand 2 "" ""))]
13437   ""
13438 {
13439   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13440   DONE;
13441 })
13442
13443 (define_insn "*call_0"
13444   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13445          (match_operand 1 "" ""))]
13446   ""
13447 {
13448   if (SIBLING_CALL_P (insn))
13449     return "jmp\t%P0";
13450   else
13451     return "call\t%P0";
13452 }
13453   [(set_attr "type" "call")])
13454
13455 (define_insn "*call_1"
13456   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13457          (match_operand 1 "" ""))]
13458   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13459 {
13460   if (constant_call_address_operand (operands[0], Pmode))
13461     return "call\t%P0";
13462   return "call\t%A0";
13463 }
13464   [(set_attr "type" "call")])
13465
13466 (define_insn "*sibcall_1"
13467   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13468          (match_operand 1 "" ""))]
13469   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13470 {
13471   if (constant_call_address_operand (operands[0], Pmode))
13472     return "jmp\t%P0";
13473   return "jmp\t%A0";
13474 }
13475   [(set_attr "type" "call")])
13476
13477 (define_insn "*call_1_rex64"
13478   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13479          (match_operand 1 "" ""))]
13480   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13481 {
13482   if (constant_call_address_operand (operands[0], Pmode))
13483     return "call\t%P0";
13484   return "call\t%A0";
13485 }
13486   [(set_attr "type" "call")])
13487
13488 (define_insn "*sibcall_1_rex64"
13489   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13490          (match_operand 1 "" ""))]
13491   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13492   "jmp\t%P0"
13493   [(set_attr "type" "call")])
13494
13495 (define_insn "*sibcall_1_rex64_v"
13496   [(call (mem:QI (reg:DI 40))
13497          (match_operand 0 "" ""))]
13498   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13499   "jmp\t*%%r11"
13500   [(set_attr "type" "call")])
13501
13502
13503 ;; Call subroutine, returning value in operand 0
13504
13505 (define_expand "call_value_pop"
13506   [(parallel [(set (match_operand 0 "" "")
13507                    (call (match_operand:QI 1 "" "")
13508                          (match_operand:SI 2 "" "")))
13509               (set (reg:SI SP_REG)
13510                    (plus:SI (reg:SI SP_REG)
13511                             (match_operand:SI 4 "" "")))])]
13512   "!TARGET_64BIT"
13513 {
13514   ix86_expand_call (operands[0], operands[1], operands[2],
13515                     operands[3], operands[4], 0);
13516   DONE;
13517 })
13518
13519 (define_expand "call_value"
13520   [(set (match_operand 0 "" "")
13521         (call (match_operand:QI 1 "" "")
13522               (match_operand:SI 2 "" "")))
13523    (use (match_operand:SI 3 "" ""))]
13524   ;; Operand 2 not used on the i386.
13525   ""
13526 {
13527   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13528   DONE;
13529 })
13530
13531 (define_expand "sibcall_value"
13532   [(set (match_operand 0 "" "")
13533         (call (match_operand:QI 1 "" "")
13534               (match_operand:SI 2 "" "")))
13535    (use (match_operand:SI 3 "" ""))]
13536   ;; Operand 2 not used on the i386.
13537   ""
13538 {
13539   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13540   DONE;
13541 })
13542
13543 ;; Call subroutine returning any type.
13544
13545 (define_expand "untyped_call"
13546   [(parallel [(call (match_operand 0 "" "")
13547                     (const_int 0))
13548               (match_operand 1 "" "")
13549               (match_operand 2 "" "")])]
13550   ""
13551 {
13552   int i;
13553
13554   /* In order to give reg-stack an easier job in validating two
13555      coprocessor registers as containing a possible return value,
13556      simply pretend the untyped call returns a complex long double
13557      value.  */
13558
13559   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13560                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13561                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13562                     NULL, 0);
13563
13564   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13565     {
13566       rtx set = XVECEXP (operands[2], 0, i);
13567       emit_move_insn (SET_DEST (set), SET_SRC (set));
13568     }
13569
13570   /* The optimizer does not know that the call sets the function value
13571      registers we stored in the result block.  We avoid problems by
13572      claiming that all hard registers are used and clobbered at this
13573      point.  */
13574   emit_insn (gen_blockage (const0_rtx));
13575
13576   DONE;
13577 })
13578 \f
13579 ;; Prologue and epilogue instructions
13580
13581 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13582 ;; all of memory.  This blocks insns from being moved across this point.
13583
13584 (define_insn "blockage"
13585   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13586   ""
13587   ""
13588   [(set_attr "length" "0")])
13589
13590 ;; Insn emitted into the body of a function to return from a function.
13591 ;; This is only done if the function's epilogue is known to be simple.
13592 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13593
13594 (define_expand "return"
13595   [(return)]
13596   "ix86_can_use_return_insn_p ()"
13597 {
13598   if (current_function_pops_args)
13599     {
13600       rtx popc = GEN_INT (current_function_pops_args);
13601       emit_jump_insn (gen_return_pop_internal (popc));
13602       DONE;
13603     }
13604 })
13605
13606 (define_insn "return_internal"
13607   [(return)]
13608   "reload_completed"
13609   "ret"
13610   [(set_attr "length" "1")
13611    (set_attr "length_immediate" "0")
13612    (set_attr "modrm" "0")])
13613
13614 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13615 ;; instruction Athlon and K8 have.
13616
13617 (define_insn "return_internal_long"
13618   [(return)
13619    (unspec [(const_int 0)] UNSPEC_REP)]
13620   "reload_completed"
13621   "rep {;} ret"
13622   [(set_attr "length" "1")
13623    (set_attr "length_immediate" "0")
13624    (set_attr "prefix_rep" "1")
13625    (set_attr "modrm" "0")])
13626
13627 (define_insn "return_pop_internal"
13628   [(return)
13629    (use (match_operand:SI 0 "const_int_operand" ""))]
13630   "reload_completed"
13631   "ret\t%0"
13632   [(set_attr "length" "3")
13633    (set_attr "length_immediate" "2")
13634    (set_attr "modrm" "0")])
13635
13636 (define_insn "return_indirect_internal"
13637   [(return)
13638    (use (match_operand:SI 0 "register_operand" "r"))]
13639   "reload_completed"
13640   "jmp\t%A0"
13641   [(set_attr "type" "ibr")
13642    (set_attr "length_immediate" "0")])
13643
13644 (define_insn "nop"
13645   [(const_int 0)]
13646   ""
13647   "nop"
13648   [(set_attr "length" "1")
13649    (set_attr "length_immediate" "0")
13650    (set_attr "modrm" "0")])
13651
13652 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13653 ;; branch prediction penalty for the third jump in a 16-byte
13654 ;; block on K8.
13655
13656 (define_insn "align"
13657   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13658   ""
13659 {
13660 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13661   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13662 #else
13663   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13664      The align insn is used to avoid 3 jump instructions in the row to improve
13665      branch prediction and the benefits hardly outweight the cost of extra 8
13666      nops on the average inserted by full alignment pseudo operation.  */
13667 #endif
13668   return "";
13669 }
13670   [(set_attr "length" "16")])
13671
13672 (define_expand "prologue"
13673   [(const_int 1)]
13674   ""
13675   "ix86_expand_prologue (); DONE;")
13676
13677 (define_insn "set_got"
13678   [(set (match_operand:SI 0 "register_operand" "=r")
13679         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13680    (clobber (reg:CC FLAGS_REG))]
13681   "!TARGET_64BIT"
13682   { return output_set_got (operands[0]); }
13683   [(set_attr "type" "multi")
13684    (set_attr "length" "12")])
13685
13686 (define_expand "epilogue"
13687   [(const_int 1)]
13688   ""
13689   "ix86_expand_epilogue (1); DONE;")
13690
13691 (define_expand "sibcall_epilogue"
13692   [(const_int 1)]
13693   ""
13694   "ix86_expand_epilogue (0); DONE;")
13695
13696 (define_expand "eh_return"
13697   [(use (match_operand 0 "register_operand" ""))]
13698   ""
13699 {
13700   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13701
13702   /* Tricky bit: we write the address of the handler to which we will
13703      be returning into someone else's stack frame, one word below the
13704      stack address we wish to restore.  */
13705   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13706   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13707   tmp = gen_rtx_MEM (Pmode, tmp);
13708   emit_move_insn (tmp, ra);
13709
13710   if (Pmode == SImode)
13711     emit_jump_insn (gen_eh_return_si (sa));
13712   else
13713     emit_jump_insn (gen_eh_return_di (sa));
13714   emit_barrier ();
13715   DONE;
13716 })
13717
13718 (define_insn_and_split "eh_return_si"
13719   [(set (pc) 
13720         (unspec [(match_operand:SI 0 "register_operand" "c")]
13721                  UNSPEC_EH_RETURN))]
13722   "!TARGET_64BIT"
13723   "#"
13724   "reload_completed"
13725   [(const_int 1)]
13726   "ix86_expand_epilogue (2); DONE;")
13727
13728 (define_insn_and_split "eh_return_di"
13729   [(set (pc) 
13730         (unspec [(match_operand:DI 0 "register_operand" "c")]
13731                  UNSPEC_EH_RETURN))]
13732   "TARGET_64BIT"
13733   "#"
13734   "reload_completed"
13735   [(const_int 1)]
13736   "ix86_expand_epilogue (2); DONE;")
13737
13738 (define_insn "leave"
13739   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13740    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13741    (clobber (mem:BLK (scratch)))]
13742   "!TARGET_64BIT"
13743   "leave"
13744   [(set_attr "type" "leave")])
13745
13746 (define_insn "leave_rex64"
13747   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13748    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13749    (clobber (mem:BLK (scratch)))]
13750   "TARGET_64BIT"
13751   "leave"
13752   [(set_attr "type" "leave")])
13753 \f
13754 (define_expand "ffssi2"
13755   [(parallel
13756      [(set (match_operand:SI 0 "register_operand" "") 
13757            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13758       (clobber (match_scratch:SI 2 ""))
13759       (clobber (reg:CC FLAGS_REG))])]
13760   ""
13761   "")
13762
13763 (define_insn_and_split "*ffs_cmove"
13764   [(set (match_operand:SI 0 "register_operand" "=r") 
13765         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13766    (clobber (match_scratch:SI 2 "=&r"))
13767    (clobber (reg:CC FLAGS_REG))]
13768   "TARGET_CMOVE"
13769   "#"
13770   "&& reload_completed"
13771   [(set (match_dup 2) (const_int -1))
13772    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13773               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13774    (set (match_dup 0) (if_then_else:SI
13775                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13776                         (match_dup 2)
13777                         (match_dup 0)))
13778    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13779               (clobber (reg:CC FLAGS_REG))])]
13780   "")
13781
13782 (define_insn_and_split "*ffs_no_cmove"
13783   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13784         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13785    (clobber (match_scratch:SI 2 "=&q"))
13786    (clobber (reg:CC FLAGS_REG))]
13787   ""
13788   "#"
13789   "reload_completed"
13790   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13791               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13792    (set (strict_low_part (match_dup 3))
13793         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13794    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13795               (clobber (reg:CC FLAGS_REG))])
13796    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13797               (clobber (reg:CC FLAGS_REG))])
13798    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13799               (clobber (reg:CC FLAGS_REG))])]
13800 {
13801   operands[3] = gen_lowpart (QImode, operands[2]);
13802   ix86_expand_clear (operands[2]);
13803 })
13804
13805 (define_insn "*ffssi_1"
13806   [(set (reg:CCZ FLAGS_REG)
13807         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13808                      (const_int 0)))
13809    (set (match_operand:SI 0 "register_operand" "=r")
13810         (ctz:SI (match_dup 1)))]
13811   ""
13812   "bsf{l}\t{%1, %0|%0, %1}"
13813   [(set_attr "prefix_0f" "1")])
13814
13815 (define_expand "ffsdi2"
13816   [(parallel
13817      [(set (match_operand:DI 0 "register_operand" "") 
13818            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13819       (clobber (match_scratch:DI 2 ""))
13820       (clobber (reg:CC FLAGS_REG))])]
13821   "TARGET_64BIT && TARGET_CMOVE"
13822   "")
13823
13824 (define_insn_and_split "*ffs_rex64"
13825   [(set (match_operand:DI 0 "register_operand" "=r") 
13826         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13827    (clobber (match_scratch:DI 2 "=&r"))
13828    (clobber (reg:CC FLAGS_REG))]
13829   "TARGET_64BIT && TARGET_CMOVE"
13830   "#"
13831   "&& reload_completed"
13832   [(set (match_dup 2) (const_int -1))
13833    (parallel [(set (reg:CCZ FLAGS_REG)
13834                    (compare:CCZ (match_dup 1) (const_int 0)))
13835               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13836    (set (match_dup 0) (if_then_else:DI
13837                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13838                         (match_dup 2)
13839                         (match_dup 0)))
13840    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13841               (clobber (reg:CC FLAGS_REG))])]
13842   "")
13843
13844 (define_insn "*ffsdi_1"
13845   [(set (reg:CCZ FLAGS_REG)
13846         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13847                      (const_int 0)))
13848    (set (match_operand:DI 0 "register_operand" "=r")
13849         (ctz:DI (match_dup 1)))]
13850   "TARGET_64BIT"
13851   "bsf{q}\t{%1, %0|%0, %1}"
13852   [(set_attr "prefix_0f" "1")])
13853
13854 (define_insn "ctzsi2"
13855   [(set (match_operand:SI 0 "register_operand" "=r")
13856         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13857    (clobber (reg:CC FLAGS_REG))]
13858   ""
13859   "bsf{l}\t{%1, %0|%0, %1}"
13860   [(set_attr "prefix_0f" "1")])
13861
13862 (define_insn "ctzdi2"
13863   [(set (match_operand:DI 0 "register_operand" "=r")
13864         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13865    (clobber (reg:CC FLAGS_REG))]
13866   "TARGET_64BIT"
13867   "bsf{q}\t{%1, %0|%0, %1}"
13868   [(set_attr "prefix_0f" "1")])
13869
13870 (define_expand "clzsi2"
13871   [(parallel
13872      [(set (match_operand:SI 0 "register_operand" "")
13873            (minus:SI (const_int 31)
13874                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13875       (clobber (reg:CC FLAGS_REG))])
13876    (parallel
13877      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13878       (clobber (reg:CC FLAGS_REG))])]
13879   ""
13880   "")
13881
13882 (define_insn "*bsr"
13883   [(set (match_operand:SI 0 "register_operand" "=r")
13884         (minus:SI (const_int 31)
13885                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13886    (clobber (reg:CC FLAGS_REG))]
13887   ""
13888   "bsr{l}\t{%1, %0|%0, %1}"
13889   [(set_attr "prefix_0f" "1")])
13890
13891 (define_expand "clzdi2"
13892   [(parallel
13893      [(set (match_operand:DI 0 "register_operand" "")
13894            (minus:DI (const_int 63)
13895                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13896       (clobber (reg:CC FLAGS_REG))])
13897    (parallel
13898      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13899       (clobber (reg:CC FLAGS_REG))])]
13900   "TARGET_64BIT"
13901   "")
13902
13903 (define_insn "*bsr_rex64"
13904   [(set (match_operand:DI 0 "register_operand" "=r")
13905         (minus:DI (const_int 63)
13906                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13907    (clobber (reg:CC FLAGS_REG))]
13908   "TARGET_64BIT"
13909   "bsr{q}\t{%1, %0|%0, %1}"
13910   [(set_attr "prefix_0f" "1")])
13911 \f
13912 ;; Thread-local storage patterns for ELF.
13913 ;;
13914 ;; Note that these code sequences must appear exactly as shown
13915 ;; in order to allow linker relaxation.
13916
13917 (define_insn "*tls_global_dynamic_32_gnu"
13918   [(set (match_operand:SI 0 "register_operand" "=a")
13919         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13920                     (match_operand:SI 2 "tls_symbolic_operand" "")
13921                     (match_operand:SI 3 "call_insn_operand" "")]
13922                     UNSPEC_TLS_GD))
13923    (clobber (match_scratch:SI 4 "=d"))
13924    (clobber (match_scratch:SI 5 "=c"))
13925    (clobber (reg:CC FLAGS_REG))]
13926   "!TARGET_64BIT && TARGET_GNU_TLS"
13927   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13928   [(set_attr "type" "multi")
13929    (set_attr "length" "12")])
13930
13931 (define_insn "*tls_global_dynamic_32_sun"
13932   [(set (match_operand:SI 0 "register_operand" "=a")
13933         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13934                     (match_operand:SI 2 "tls_symbolic_operand" "")
13935                     (match_operand:SI 3 "call_insn_operand" "")]
13936                     UNSPEC_TLS_GD))
13937    (clobber (match_scratch:SI 4 "=d"))
13938    (clobber (match_scratch:SI 5 "=c"))
13939    (clobber (reg:CC FLAGS_REG))]
13940   "!TARGET_64BIT && TARGET_SUN_TLS"
13941   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13942         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13943   [(set_attr "type" "multi")
13944    (set_attr "length" "14")])
13945
13946 (define_expand "tls_global_dynamic_32"
13947   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13948                    (unspec:SI
13949                     [(match_dup 2)
13950                      (match_operand:SI 1 "tls_symbolic_operand" "")
13951                      (match_dup 3)]
13952                     UNSPEC_TLS_GD))
13953               (clobber (match_scratch:SI 4 ""))
13954               (clobber (match_scratch:SI 5 ""))
13955               (clobber (reg:CC FLAGS_REG))])]
13956   ""
13957 {
13958   if (flag_pic)
13959     operands[2] = pic_offset_table_rtx;
13960   else
13961     {
13962       operands[2] = gen_reg_rtx (Pmode);
13963       emit_insn (gen_set_got (operands[2]));
13964     }
13965   operands[3] = ix86_tls_get_addr ();
13966 })
13967
13968 (define_insn "*tls_global_dynamic_64"
13969   [(set (match_operand:DI 0 "register_operand" "=a")
13970         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13971                       (match_operand:DI 3 "" "")))
13972    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13973               UNSPEC_TLS_GD)]
13974   "TARGET_64BIT"
13975   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13976   [(set_attr "type" "multi")
13977    (set_attr "length" "16")])
13978
13979 (define_expand "tls_global_dynamic_64"
13980   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13981                    (call (mem:QI (match_dup 2)) (const_int 0)))
13982               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13983                          UNSPEC_TLS_GD)])]
13984   ""
13985 {
13986   operands[2] = ix86_tls_get_addr ();
13987 })
13988
13989 (define_insn "*tls_local_dynamic_base_32_gnu"
13990   [(set (match_operand:SI 0 "register_operand" "=a")
13991         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13992                     (match_operand:SI 2 "call_insn_operand" "")]
13993                    UNSPEC_TLS_LD_BASE))
13994    (clobber (match_scratch:SI 3 "=d"))
13995    (clobber (match_scratch:SI 4 "=c"))
13996    (clobber (reg:CC FLAGS_REG))]
13997   "!TARGET_64BIT && TARGET_GNU_TLS"
13998   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13999   [(set_attr "type" "multi")
14000    (set_attr "length" "11")])
14001
14002 (define_insn "*tls_local_dynamic_base_32_sun"
14003   [(set (match_operand:SI 0 "register_operand" "=a")
14004         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14005                     (match_operand:SI 2 "call_insn_operand" "")]
14006                    UNSPEC_TLS_LD_BASE))
14007    (clobber (match_scratch:SI 3 "=d"))
14008    (clobber (match_scratch:SI 4 "=c"))
14009    (clobber (reg:CC FLAGS_REG))]
14010   "!TARGET_64BIT && TARGET_SUN_TLS"
14011   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14012         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14013   [(set_attr "type" "multi")
14014    (set_attr "length" "13")])
14015
14016 (define_expand "tls_local_dynamic_base_32"
14017   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14018                    (unspec:SI [(match_dup 1) (match_dup 2)]
14019                               UNSPEC_TLS_LD_BASE))
14020               (clobber (match_scratch:SI 3 ""))
14021               (clobber (match_scratch:SI 4 ""))
14022               (clobber (reg:CC FLAGS_REG))])]
14023   ""
14024 {
14025   if (flag_pic)
14026     operands[1] = pic_offset_table_rtx;
14027   else
14028     {
14029       operands[1] = gen_reg_rtx (Pmode);
14030       emit_insn (gen_set_got (operands[1]));
14031     }
14032   operands[2] = ix86_tls_get_addr ();
14033 })
14034
14035 (define_insn "*tls_local_dynamic_base_64"
14036   [(set (match_operand:DI 0 "register_operand" "=a")
14037         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14038                       (match_operand:DI 2 "" "")))
14039    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14040   "TARGET_64BIT"
14041   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14042   [(set_attr "type" "multi")
14043    (set_attr "length" "12")])
14044
14045 (define_expand "tls_local_dynamic_base_64"
14046   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14047                    (call (mem:QI (match_dup 1)) (const_int 0)))
14048               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14049   ""
14050 {
14051   operands[1] = ix86_tls_get_addr ();
14052 })
14053
14054 ;; Local dynamic of a single variable is a lose.  Show combine how
14055 ;; to convert that back to global dynamic.
14056
14057 (define_insn_and_split "*tls_local_dynamic_32_once"
14058   [(set (match_operand:SI 0 "register_operand" "=a")
14059         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14060                              (match_operand:SI 2 "call_insn_operand" "")]
14061                             UNSPEC_TLS_LD_BASE)
14062                  (const:SI (unspec:SI
14063                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14064                             UNSPEC_DTPOFF))))
14065    (clobber (match_scratch:SI 4 "=d"))
14066    (clobber (match_scratch:SI 5 "=c"))
14067    (clobber (reg:CC FLAGS_REG))]
14068   ""
14069   "#"
14070   ""
14071   [(parallel [(set (match_dup 0)
14072                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14073                               UNSPEC_TLS_GD))
14074               (clobber (match_dup 4))
14075               (clobber (match_dup 5))
14076               (clobber (reg:CC FLAGS_REG))])]
14077   "")
14078
14079 ;; Load and add the thread base pointer from %gs:0.
14080
14081 (define_insn "*load_tp_si"
14082   [(set (match_operand:SI 0 "register_operand" "=r")
14083         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14084   "!TARGET_64BIT"
14085   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14086   [(set_attr "type" "imov")
14087    (set_attr "modrm" "0")
14088    (set_attr "length" "7")
14089    (set_attr "memory" "load")
14090    (set_attr "imm_disp" "false")])
14091
14092 (define_insn "*add_tp_si"
14093   [(set (match_operand:SI 0 "register_operand" "=r")
14094         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14095                  (match_operand:SI 1 "register_operand" "0")))
14096    (clobber (reg:CC FLAGS_REG))]
14097   "!TARGET_64BIT"
14098   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14099   [(set_attr "type" "alu")
14100    (set_attr "modrm" "0")
14101    (set_attr "length" "7")
14102    (set_attr "memory" "load")
14103    (set_attr "imm_disp" "false")])
14104
14105 (define_insn "*load_tp_di"
14106   [(set (match_operand:DI 0 "register_operand" "=r")
14107         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14108   "TARGET_64BIT"
14109   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14110   [(set_attr "type" "imov")
14111    (set_attr "modrm" "0")
14112    (set_attr "length" "7")
14113    (set_attr "memory" "load")
14114    (set_attr "imm_disp" "false")])
14115
14116 (define_insn "*add_tp_di"
14117   [(set (match_operand:DI 0 "register_operand" "=r")
14118         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14119                  (match_operand:DI 1 "register_operand" "0")))
14120    (clobber (reg:CC FLAGS_REG))]
14121   "TARGET_64BIT"
14122   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14123   [(set_attr "type" "alu")
14124    (set_attr "modrm" "0")
14125    (set_attr "length" "7")
14126    (set_attr "memory" "load")
14127    (set_attr "imm_disp" "false")])
14128 \f
14129 ;; These patterns match the binary 387 instructions for addM3, subM3,
14130 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14131 ;; SFmode.  The first is the normal insn, the second the same insn but
14132 ;; with one operand a conversion, and the third the same insn but with
14133 ;; the other operand a conversion.  The conversion may be SFmode or
14134 ;; SImode if the target mode DFmode, but only SImode if the target mode
14135 ;; is SFmode.
14136
14137 ;; Gcc is slightly more smart about handling normal two address instructions
14138 ;; so use special patterns for add and mull.
14139
14140 (define_insn "*fop_sf_comm_mixed"
14141   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14142         (match_operator:SF 3 "binary_fp_operator"
14143                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14144                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14145   "TARGET_MIX_SSE_I387
14146    && COMMUTATIVE_ARITH_P (operands[3])
14147    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14148   "* return output_387_binary_op (insn, operands);"
14149   [(set (attr "type") 
14150         (if_then_else (eq_attr "alternative" "1")
14151            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14152               (const_string "ssemul")
14153               (const_string "sseadd"))
14154            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14155               (const_string "fmul")
14156               (const_string "fop"))))
14157    (set_attr "mode" "SF")])
14158
14159 (define_insn "*fop_sf_comm_sse"
14160   [(set (match_operand:SF 0 "register_operand" "=x")
14161         (match_operator:SF 3 "binary_fp_operator"
14162                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14163                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14164   "TARGET_SSE_MATH
14165    && COMMUTATIVE_ARITH_P (operands[3])
14166    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14167   "* return output_387_binary_op (insn, operands);"
14168   [(set (attr "type") 
14169         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14170            (const_string "ssemul")
14171            (const_string "sseadd")))
14172    (set_attr "mode" "SF")])
14173
14174 (define_insn "*fop_sf_comm_i387"
14175   [(set (match_operand:SF 0 "register_operand" "=f")
14176         (match_operator:SF 3 "binary_fp_operator"
14177                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14178                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14179   "TARGET_80387
14180    && COMMUTATIVE_ARITH_P (operands[3])
14181    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14182   "* return output_387_binary_op (insn, operands);"
14183   [(set (attr "type") 
14184         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14185            (const_string "fmul")
14186            (const_string "fop")))
14187    (set_attr "mode" "SF")])
14188
14189 (define_insn "*fop_sf_1_mixed"
14190   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14191         (match_operator:SF 3 "binary_fp_operator"
14192                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14193                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14194   "TARGET_MIX_SSE_I387
14195    && !COMMUTATIVE_ARITH_P (operands[3])
14196    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14197   "* return output_387_binary_op (insn, operands);"
14198   [(set (attr "type") 
14199         (cond [(and (eq_attr "alternative" "2")
14200                     (match_operand:SF 3 "mult_operator" ""))
14201                  (const_string "ssemul")
14202                (and (eq_attr "alternative" "2")
14203                     (match_operand:SF 3 "div_operator" ""))
14204                  (const_string "ssediv")
14205                (eq_attr "alternative" "2")
14206                  (const_string "sseadd")
14207                (match_operand:SF 3 "mult_operator" "") 
14208                  (const_string "fmul")
14209                (match_operand:SF 3 "div_operator" "") 
14210                  (const_string "fdiv")
14211               ]
14212               (const_string "fop")))
14213    (set_attr "mode" "SF")])
14214
14215 (define_insn "*fop_sf_1_sse"
14216   [(set (match_operand:SF 0 "register_operand" "=x")
14217         (match_operator:SF 3 "binary_fp_operator"
14218                         [(match_operand:SF 1 "register_operand" "0")
14219                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14220   "TARGET_SSE_MATH
14221    && !COMMUTATIVE_ARITH_P (operands[3])"
14222   "* return output_387_binary_op (insn, operands);"
14223   [(set (attr "type") 
14224         (cond [(match_operand:SF 3 "mult_operator" "")
14225                  (const_string "ssemul")
14226                (match_operand:SF 3 "div_operator" "")
14227                  (const_string "ssediv")
14228               ]
14229               (const_string "sseadd")))
14230    (set_attr "mode" "SF")])
14231
14232 (define_insn "*fop_sf_1_i387"
14233   [(set (match_operand:SF 0 "register_operand" "=f,f")
14234         (match_operator:SF 3 "binary_fp_operator"
14235                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14236                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14237   "TARGET_80387
14238    && !COMMUTATIVE_ARITH_P (operands[3])
14239    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14240   "* return output_387_binary_op (insn, operands);"
14241   [(set (attr "type") 
14242         (cond [(match_operand:SF 3 "mult_operator" "") 
14243                  (const_string "fmul")
14244                (match_operand:SF 3 "div_operator" "") 
14245                  (const_string "fdiv")
14246               ]
14247               (const_string "fop")))
14248    (set_attr "mode" "SF")])
14249
14250
14251 ;; ??? Add SSE splitters for these!
14252 (define_insn "*fop_sf_2_i387"
14253   [(set (match_operand:SF 0 "register_operand" "=f,f")
14254         (match_operator:SF 3 "binary_fp_operator"
14255           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14256            (match_operand:SF 2 "register_operand" "0,0")]))]
14257   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14258   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14259   [(set (attr "type") 
14260         (cond [(match_operand:SF 3 "mult_operator" "") 
14261                  (const_string "fmul")
14262                (match_operand:SF 3 "div_operator" "") 
14263                  (const_string "fdiv")
14264               ]
14265               (const_string "fop")))
14266    (set_attr "fp_int_src" "true")
14267    (set_attr "mode" "SI")])
14268
14269 (define_insn "*fop_sf_3_i387"
14270   [(set (match_operand:SF 0 "register_operand" "=f,f")
14271         (match_operator:SF 3 "binary_fp_operator"
14272           [(match_operand:SF 1 "register_operand" "0,0")
14273            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14274   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14275   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14276   [(set (attr "type") 
14277         (cond [(match_operand:SF 3 "mult_operator" "") 
14278                  (const_string "fmul")
14279                (match_operand:SF 3 "div_operator" "") 
14280                  (const_string "fdiv")
14281               ]
14282               (const_string "fop")))
14283    (set_attr "fp_int_src" "true")
14284    (set_attr "mode" "SI")])
14285
14286 (define_insn "*fop_df_comm_mixed"
14287   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14288         (match_operator:DF 3 "binary_fp_operator"
14289                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14290                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14291   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14292    && COMMUTATIVE_ARITH_P (operands[3])
14293    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14294   "* return output_387_binary_op (insn, operands);"
14295   [(set (attr "type") 
14296         (if_then_else (eq_attr "alternative" "1")
14297            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14298               (const_string "ssemul")
14299               (const_string "sseadd"))
14300            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14301               (const_string "fmul")
14302               (const_string "fop"))))
14303    (set_attr "mode" "DF")])
14304
14305 (define_insn "*fop_df_comm_sse"
14306   [(set (match_operand:DF 0 "register_operand" "=Y")
14307         (match_operator:DF 3 "binary_fp_operator"
14308                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14309                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14310   "TARGET_SSE2 && TARGET_SSE_MATH
14311    && COMMUTATIVE_ARITH_P (operands[3])
14312    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14313   "* return output_387_binary_op (insn, operands);"
14314   [(set (attr "type") 
14315         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14316            (const_string "ssemul")
14317            (const_string "sseadd")))
14318    (set_attr "mode" "DF")])
14319
14320 (define_insn "*fop_df_comm_i387"
14321   [(set (match_operand:DF 0 "register_operand" "=f")
14322         (match_operator:DF 3 "binary_fp_operator"
14323                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14324                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14325   "TARGET_80387
14326    && COMMUTATIVE_ARITH_P (operands[3])
14327    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14328   "* return output_387_binary_op (insn, operands);"
14329   [(set (attr "type") 
14330         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14331            (const_string "fmul")
14332            (const_string "fop")))
14333    (set_attr "mode" "DF")])
14334
14335 (define_insn "*fop_df_1_mixed"
14336   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14337         (match_operator:DF 3 "binary_fp_operator"
14338                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14339                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14340   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14341    && !COMMUTATIVE_ARITH_P (operands[3])
14342    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14343   "* return output_387_binary_op (insn, operands);"
14344   [(set (attr "type") 
14345         (cond [(and (eq_attr "alternative" "2")
14346                     (match_operand:SF 3 "mult_operator" ""))
14347                  (const_string "ssemul")
14348                (and (eq_attr "alternative" "2")
14349                     (match_operand:SF 3 "div_operator" ""))
14350                  (const_string "ssediv")
14351                (eq_attr "alternative" "2")
14352                  (const_string "sseadd")
14353                (match_operand:DF 3 "mult_operator" "") 
14354                  (const_string "fmul")
14355                (match_operand:DF 3 "div_operator" "") 
14356                  (const_string "fdiv")
14357               ]
14358               (const_string "fop")))
14359    (set_attr "mode" "DF")])
14360
14361 (define_insn "*fop_df_1_sse"
14362   [(set (match_operand:DF 0 "register_operand" "=Y")
14363         (match_operator:DF 3 "binary_fp_operator"
14364                         [(match_operand:DF 1 "register_operand" "0")
14365                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14366   "TARGET_SSE2 && TARGET_SSE_MATH
14367    && !COMMUTATIVE_ARITH_P (operands[3])"
14368   "* return output_387_binary_op (insn, operands);"
14369   [(set_attr "mode" "DF")
14370    (set (attr "type") 
14371         (cond [(match_operand:SF 3 "mult_operator" "")
14372                  (const_string "ssemul")
14373                (match_operand:SF 3 "div_operator" "")
14374                  (const_string "ssediv")
14375               ]
14376               (const_string "sseadd")))])
14377
14378 (define_insn "*fop_df_1_i387"
14379   [(set (match_operand:DF 0 "register_operand" "=f,f")
14380         (match_operator:DF 3 "binary_fp_operator"
14381                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14382                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14383   "TARGET_80387
14384    && !COMMUTATIVE_ARITH_P (operands[3])
14385    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14386   "* return output_387_binary_op (insn, operands);"
14387   [(set (attr "type") 
14388         (cond [(match_operand:DF 3 "mult_operator" "") 
14389                  (const_string "fmul")
14390                (match_operand:DF 3 "div_operator" "")
14391                  (const_string "fdiv")
14392               ]
14393               (const_string "fop")))
14394    (set_attr "mode" "DF")])
14395
14396 ;; ??? Add SSE splitters for these!
14397 (define_insn "*fop_df_2_i387"
14398   [(set (match_operand:DF 0 "register_operand" "=f,f")
14399         (match_operator:DF 3 "binary_fp_operator"
14400            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14401             (match_operand:DF 2 "register_operand" "0,0")]))]
14402   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14403   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14404   [(set (attr "type") 
14405         (cond [(match_operand:DF 3 "mult_operator" "") 
14406                  (const_string "fmul")
14407                (match_operand:DF 3 "div_operator" "") 
14408                  (const_string "fdiv")
14409               ]
14410               (const_string "fop")))
14411    (set_attr "fp_int_src" "true")
14412    (set_attr "mode" "SI")])
14413
14414 (define_insn "*fop_df_3_i387"
14415   [(set (match_operand:DF 0 "register_operand" "=f,f")
14416         (match_operator:DF 3 "binary_fp_operator"
14417            [(match_operand:DF 1 "register_operand" "0,0")
14418             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14419   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14420   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14421   [(set (attr "type") 
14422         (cond [(match_operand:DF 3 "mult_operator" "") 
14423                  (const_string "fmul")
14424                (match_operand:DF 3 "div_operator" "") 
14425                  (const_string "fdiv")
14426               ]
14427               (const_string "fop")))
14428    (set_attr "fp_int_src" "true")
14429    (set_attr "mode" "SI")])
14430
14431 (define_insn "*fop_df_4_i387"
14432   [(set (match_operand:DF 0 "register_operand" "=f,f")
14433         (match_operator:DF 3 "binary_fp_operator"
14434            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14435             (match_operand:DF 2 "register_operand" "0,f")]))]
14436   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14437    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14438   "* return output_387_binary_op (insn, operands);"
14439   [(set (attr "type") 
14440         (cond [(match_operand:DF 3 "mult_operator" "") 
14441                  (const_string "fmul")
14442                (match_operand:DF 3 "div_operator" "") 
14443                  (const_string "fdiv")
14444               ]
14445               (const_string "fop")))
14446    (set_attr "mode" "SF")])
14447
14448 (define_insn "*fop_df_5_i387"
14449   [(set (match_operand:DF 0 "register_operand" "=f,f")
14450         (match_operator:DF 3 "binary_fp_operator"
14451           [(match_operand:DF 1 "register_operand" "0,f")
14452            (float_extend:DF
14453             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14454   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14455   "* return output_387_binary_op (insn, operands);"
14456   [(set (attr "type") 
14457         (cond [(match_operand:DF 3 "mult_operator" "") 
14458                  (const_string "fmul")
14459                (match_operand:DF 3 "div_operator" "") 
14460                  (const_string "fdiv")
14461               ]
14462               (const_string "fop")))
14463    (set_attr "mode" "SF")])
14464
14465 (define_insn "*fop_df_6_i387"
14466   [(set (match_operand:DF 0 "register_operand" "=f,f")
14467         (match_operator:DF 3 "binary_fp_operator"
14468           [(float_extend:DF
14469             (match_operand:SF 1 "register_operand" "0,f"))
14470            (float_extend:DF
14471             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14472   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14473   "* return output_387_binary_op (insn, operands);"
14474   [(set (attr "type") 
14475         (cond [(match_operand:DF 3 "mult_operator" "") 
14476                  (const_string "fmul")
14477                (match_operand:DF 3 "div_operator" "") 
14478                  (const_string "fdiv")
14479               ]
14480               (const_string "fop")))
14481    (set_attr "mode" "SF")])
14482
14483 (define_insn "*fop_xf_comm_i387"
14484   [(set (match_operand:XF 0 "register_operand" "=f")
14485         (match_operator:XF 3 "binary_fp_operator"
14486                         [(match_operand:XF 1 "register_operand" "%0")
14487                          (match_operand:XF 2 "register_operand" "f")]))]
14488   "TARGET_80387
14489    && COMMUTATIVE_ARITH_P (operands[3])"
14490   "* return output_387_binary_op (insn, operands);"
14491   [(set (attr "type") 
14492         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14493            (const_string "fmul")
14494            (const_string "fop")))
14495    (set_attr "mode" "XF")])
14496
14497 (define_insn "*fop_xf_1_i387"
14498   [(set (match_operand:XF 0 "register_operand" "=f,f")
14499         (match_operator:XF 3 "binary_fp_operator"
14500                         [(match_operand:XF 1 "register_operand" "0,f")
14501                          (match_operand:XF 2 "register_operand" "f,0")]))]
14502   "TARGET_80387
14503    && !COMMUTATIVE_ARITH_P (operands[3])"
14504   "* return output_387_binary_op (insn, operands);"
14505   [(set (attr "type") 
14506         (cond [(match_operand:XF 3 "mult_operator" "") 
14507                  (const_string "fmul")
14508                (match_operand:XF 3 "div_operator" "") 
14509                  (const_string "fdiv")
14510               ]
14511               (const_string "fop")))
14512    (set_attr "mode" "XF")])
14513
14514 (define_insn "*fop_xf_2_i387"
14515   [(set (match_operand:XF 0 "register_operand" "=f,f")
14516         (match_operator:XF 3 "binary_fp_operator"
14517            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14518             (match_operand:XF 2 "register_operand" "0,0")]))]
14519   "TARGET_80387 && TARGET_USE_FIOP"
14520   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14521   [(set (attr "type") 
14522         (cond [(match_operand:XF 3 "mult_operator" "") 
14523                  (const_string "fmul")
14524                (match_operand:XF 3 "div_operator" "") 
14525                  (const_string "fdiv")
14526               ]
14527               (const_string "fop")))
14528    (set_attr "fp_int_src" "true")
14529    (set_attr "mode" "SI")])
14530
14531 (define_insn "*fop_xf_3_i387"
14532   [(set (match_operand:XF 0 "register_operand" "=f,f")
14533         (match_operator:XF 3 "binary_fp_operator"
14534           [(match_operand:XF 1 "register_operand" "0,0")
14535            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14536   "TARGET_80387 && TARGET_USE_FIOP"
14537   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14538   [(set (attr "type") 
14539         (cond [(match_operand:XF 3 "mult_operator" "") 
14540                  (const_string "fmul")
14541                (match_operand:XF 3 "div_operator" "") 
14542                  (const_string "fdiv")
14543               ]
14544               (const_string "fop")))
14545    (set_attr "fp_int_src" "true")
14546    (set_attr "mode" "SI")])
14547
14548 (define_insn "*fop_xf_4_i387"
14549   [(set (match_operand:XF 0 "register_operand" "=f,f")
14550         (match_operator:XF 3 "binary_fp_operator"
14551            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14552             (match_operand:XF 2 "register_operand" "0,f")]))]
14553   "TARGET_80387"
14554   "* return output_387_binary_op (insn, operands);"
14555   [(set (attr "type") 
14556         (cond [(match_operand:XF 3 "mult_operator" "") 
14557                  (const_string "fmul")
14558                (match_operand:XF 3 "div_operator" "") 
14559                  (const_string "fdiv")
14560               ]
14561               (const_string "fop")))
14562    (set_attr "mode" "SF")])
14563
14564 (define_insn "*fop_xf_5_i387"
14565   [(set (match_operand:XF 0 "register_operand" "=f,f")
14566         (match_operator:XF 3 "binary_fp_operator"
14567           [(match_operand:XF 1 "register_operand" "0,f")
14568            (float_extend:XF
14569             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14570   "TARGET_80387"
14571   "* return output_387_binary_op (insn, operands);"
14572   [(set (attr "type") 
14573         (cond [(match_operand:XF 3 "mult_operator" "") 
14574                  (const_string "fmul")
14575                (match_operand:XF 3 "div_operator" "") 
14576                  (const_string "fdiv")
14577               ]
14578               (const_string "fop")))
14579    (set_attr "mode" "SF")])
14580
14581 (define_insn "*fop_xf_6_i387"
14582   [(set (match_operand:XF 0 "register_operand" "=f,f")
14583         (match_operator:XF 3 "binary_fp_operator"
14584           [(float_extend:XF
14585             (match_operand 1 "register_operand" "0,f"))
14586            (float_extend:XF
14587             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14588   "TARGET_80387"
14589   "* return output_387_binary_op (insn, operands);"
14590   [(set (attr "type") 
14591         (cond [(match_operand:XF 3 "mult_operator" "") 
14592                  (const_string "fmul")
14593                (match_operand:XF 3 "div_operator" "") 
14594                  (const_string "fdiv")
14595               ]
14596               (const_string "fop")))
14597    (set_attr "mode" "SF")])
14598
14599 (define_split
14600   [(set (match_operand 0 "register_operand" "")
14601         (match_operator 3 "binary_fp_operator"
14602            [(float (match_operand:SI 1 "register_operand" ""))
14603             (match_operand 2 "register_operand" "")]))]
14604   "TARGET_80387 && reload_completed
14605    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14606   [(const_int 0)]
14607
14608   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14609   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14610   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14611                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14612                                           GET_MODE (operands[3]),
14613                                           operands[4],
14614                                           operands[2])));
14615   ix86_free_from_memory (GET_MODE (operands[1]));
14616   DONE;
14617 })
14618
14619 (define_split
14620   [(set (match_operand 0 "register_operand" "")
14621         (match_operator 3 "binary_fp_operator"
14622            [(match_operand 1 "register_operand" "")
14623             (float (match_operand:SI 2 "register_operand" ""))]))]
14624   "TARGET_80387 && reload_completed
14625    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14626   [(const_int 0)]
14627 {
14628   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14629   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14630   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14631                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14632                                           GET_MODE (operands[3]),
14633                                           operands[1],
14634                                           operands[4])));
14635   ix86_free_from_memory (GET_MODE (operands[2]));
14636   DONE;
14637 })
14638 \f
14639 ;; FPU special functions.
14640
14641 (define_expand "sqrtsf2"
14642   [(set (match_operand:SF 0 "register_operand" "")
14643         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14644   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14645 {
14646   if (!TARGET_SSE_MATH)
14647     operands[1] = force_reg (SFmode, operands[1]);
14648 })
14649
14650 (define_insn "*sqrtsf2_mixed"
14651   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14652         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14653   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14654   "@
14655    fsqrt
14656    sqrtss\t{%1, %0|%0, %1}"
14657   [(set_attr "type" "fpspc,sse")
14658    (set_attr "mode" "SF,SF")
14659    (set_attr "athlon_decode" "direct,*")])
14660
14661 (define_insn "*sqrtsf2_sse"
14662   [(set (match_operand:SF 0 "register_operand" "=x")
14663         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14664   "TARGET_SSE_MATH"
14665   "sqrtss\t{%1, %0|%0, %1}"
14666   [(set_attr "type" "sse")
14667    (set_attr "mode" "SF")
14668    (set_attr "athlon_decode" "*")])
14669
14670 (define_insn "*sqrtsf2_i387"
14671   [(set (match_operand:SF 0 "register_operand" "=f")
14672         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14673   "TARGET_USE_FANCY_MATH_387"
14674   "fsqrt"
14675   [(set_attr "type" "fpspc")
14676    (set_attr "mode" "SF")
14677    (set_attr "athlon_decode" "direct")])
14678
14679 (define_expand "sqrtdf2"
14680   [(set (match_operand:DF 0 "register_operand" "")
14681         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14682   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14683 {
14684   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14685     operands[1] = force_reg (DFmode, operands[1]);
14686 })
14687
14688 (define_insn "*sqrtdf2_mixed"
14689   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14690         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14691   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14692   "@
14693    fsqrt
14694    sqrtsd\t{%1, %0|%0, %1}"
14695   [(set_attr "type" "fpspc,sse")
14696    (set_attr "mode" "DF,DF")
14697    (set_attr "athlon_decode" "direct,*")])
14698
14699 (define_insn "*sqrtdf2_sse"
14700   [(set (match_operand:DF 0 "register_operand" "=Y")
14701         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14702   "TARGET_SSE2 && TARGET_SSE_MATH"
14703   "sqrtsd\t{%1, %0|%0, %1}"
14704   [(set_attr "type" "sse")
14705    (set_attr "mode" "DF")
14706    (set_attr "athlon_decode" "*")])
14707
14708 (define_insn "*sqrtdf2_i387"
14709   [(set (match_operand:DF 0 "register_operand" "=f")
14710         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14711   "TARGET_USE_FANCY_MATH_387"
14712   "fsqrt"
14713   [(set_attr "type" "fpspc")
14714    (set_attr "mode" "DF")
14715    (set_attr "athlon_decode" "direct")])
14716
14717 (define_insn "*sqrtextendsfdf2_i387"
14718   [(set (match_operand:DF 0 "register_operand" "=f")
14719         (sqrt:DF (float_extend:DF
14720                   (match_operand:SF 1 "register_operand" "0"))))]
14721   "TARGET_USE_FANCY_MATH_387
14722    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14723   "fsqrt"
14724   [(set_attr "type" "fpspc")
14725    (set_attr "mode" "DF")
14726    (set_attr "athlon_decode" "direct")])
14727
14728 (define_insn "sqrtxf2"
14729   [(set (match_operand:XF 0 "register_operand" "=f")
14730         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14731   "TARGET_USE_FANCY_MATH_387 
14732    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14733   "fsqrt"
14734   [(set_attr "type" "fpspc")
14735    (set_attr "mode" "XF")
14736    (set_attr "athlon_decode" "direct")])
14737
14738 (define_insn "*sqrtextendsfxf2_i387"
14739   [(set (match_operand:XF 0 "register_operand" "=f")
14740         (sqrt:XF (float_extend:XF
14741                   (match_operand:SF 1 "register_operand" "0"))))]
14742   "TARGET_USE_FANCY_MATH_387"
14743   "fsqrt"
14744   [(set_attr "type" "fpspc")
14745    (set_attr "mode" "XF")
14746    (set_attr "athlon_decode" "direct")])
14747
14748 (define_insn "*sqrtextenddfxf2_i387"
14749   [(set (match_operand:XF 0 "register_operand" "=f")
14750         (sqrt:XF (float_extend:XF
14751                   (match_operand:DF 1 "register_operand" "0"))))]
14752   "TARGET_USE_FANCY_MATH_387"
14753   "fsqrt"
14754   [(set_attr "type" "fpspc")
14755    (set_attr "mode" "XF")
14756    (set_attr "athlon_decode" "direct")])
14757
14758 (define_insn "fpremxf4"
14759   [(set (match_operand:XF 0 "register_operand" "=f")
14760         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14761                     (match_operand:XF 3 "register_operand" "1")]
14762                    UNSPEC_FPREM_F))
14763    (set (match_operand:XF 1 "register_operand" "=u")
14764         (unspec:XF [(match_dup 2) (match_dup 3)]
14765                    UNSPEC_FPREM_U))
14766    (set (reg:CCFP FPSR_REG)
14767         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14768   "TARGET_USE_FANCY_MATH_387
14769    && flag_unsafe_math_optimizations"
14770   "fprem"
14771   [(set_attr "type" "fpspc")
14772    (set_attr "mode" "XF")])
14773
14774 (define_expand "fmodsf3"
14775   [(use (match_operand:SF 0 "register_operand" ""))
14776    (use (match_operand:SF 1 "register_operand" ""))
14777    (use (match_operand:SF 2 "register_operand" ""))]
14778   "TARGET_USE_FANCY_MATH_387
14779    && flag_unsafe_math_optimizations"
14780 {
14781   rtx label = gen_label_rtx ();
14782
14783   rtx op1 = gen_reg_rtx (XFmode);
14784   rtx op2 = gen_reg_rtx (XFmode);
14785
14786   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14787   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14788
14789   emit_label (label);
14790
14791   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14792   ix86_emit_fp_unordered_jump (label);
14793
14794   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14795   DONE;
14796 })
14797
14798 (define_expand "fmoddf3"
14799   [(use (match_operand:DF 0 "register_operand" ""))
14800    (use (match_operand:DF 1 "register_operand" ""))
14801    (use (match_operand:DF 2 "register_operand" ""))]
14802   "TARGET_USE_FANCY_MATH_387
14803    && flag_unsafe_math_optimizations"
14804 {
14805   rtx label = gen_label_rtx ();
14806
14807   rtx op1 = gen_reg_rtx (XFmode);
14808   rtx op2 = gen_reg_rtx (XFmode);
14809
14810   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14811   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14812
14813   emit_label (label);
14814
14815   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14816   ix86_emit_fp_unordered_jump (label);
14817
14818   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14819   DONE;
14820 })
14821
14822 (define_expand "fmodxf3"
14823   [(use (match_operand:XF 0 "register_operand" ""))
14824    (use (match_operand:XF 1 "register_operand" ""))
14825    (use (match_operand:XF 2 "register_operand" ""))]
14826   "TARGET_USE_FANCY_MATH_387
14827    && flag_unsafe_math_optimizations"
14828 {
14829   rtx label = gen_label_rtx ();
14830
14831   emit_label (label);
14832
14833   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14834                            operands[1], operands[2]));
14835   ix86_emit_fp_unordered_jump (label);
14836
14837   emit_move_insn (operands[0], operands[1]);
14838   DONE;
14839 })
14840
14841 (define_insn "fprem1xf4"
14842   [(set (match_operand:XF 0 "register_operand" "=f")
14843         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14844                     (match_operand:XF 3 "register_operand" "1")]
14845                    UNSPEC_FPREM1_F))
14846    (set (match_operand:XF 1 "register_operand" "=u")
14847         (unspec:XF [(match_dup 2) (match_dup 3)]
14848                    UNSPEC_FPREM1_U))
14849    (set (reg:CCFP FPSR_REG)
14850         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14851   "TARGET_USE_FANCY_MATH_387
14852    && flag_unsafe_math_optimizations"
14853   "fprem1"
14854   [(set_attr "type" "fpspc")
14855    (set_attr "mode" "XF")])
14856
14857 (define_expand "dremsf3"
14858   [(use (match_operand:SF 0 "register_operand" ""))
14859    (use (match_operand:SF 1 "register_operand" ""))
14860    (use (match_operand:SF 2 "register_operand" ""))]
14861   "TARGET_USE_FANCY_MATH_387
14862    && flag_unsafe_math_optimizations"
14863 {
14864   rtx label = gen_label_rtx ();
14865
14866   rtx op1 = gen_reg_rtx (XFmode);
14867   rtx op2 = gen_reg_rtx (XFmode);
14868
14869   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14870   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14871
14872   emit_label (label);
14873
14874   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14875   ix86_emit_fp_unordered_jump (label);
14876
14877   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14878   DONE;
14879 })
14880
14881 (define_expand "dremdf3"
14882   [(use (match_operand:DF 0 "register_operand" ""))
14883    (use (match_operand:DF 1 "register_operand" ""))
14884    (use (match_operand:DF 2 "register_operand" ""))]
14885   "TARGET_USE_FANCY_MATH_387
14886    && flag_unsafe_math_optimizations"
14887 {
14888   rtx label = gen_label_rtx ();
14889
14890   rtx op1 = gen_reg_rtx (XFmode);
14891   rtx op2 = gen_reg_rtx (XFmode);
14892
14893   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14894   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14895
14896   emit_label (label);
14897
14898   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14899   ix86_emit_fp_unordered_jump (label);
14900
14901   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14902   DONE;
14903 })
14904
14905 (define_expand "dremxf3"
14906   [(use (match_operand:XF 0 "register_operand" ""))
14907    (use (match_operand:XF 1 "register_operand" ""))
14908    (use (match_operand:XF 2 "register_operand" ""))]
14909   "TARGET_USE_FANCY_MATH_387
14910    && flag_unsafe_math_optimizations"
14911 {
14912   rtx label = gen_label_rtx ();
14913
14914   emit_label (label);
14915
14916   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14917                             operands[1], operands[2]));
14918   ix86_emit_fp_unordered_jump (label);
14919
14920   emit_move_insn (operands[0], operands[1]);
14921   DONE;
14922 })
14923
14924 (define_insn "*sindf2"
14925   [(set (match_operand:DF 0 "register_operand" "=f")
14926         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14927   "TARGET_USE_FANCY_MATH_387
14928    && flag_unsafe_math_optimizations"
14929   "fsin"
14930   [(set_attr "type" "fpspc")
14931    (set_attr "mode" "DF")])
14932
14933 (define_insn "*sinsf2"
14934   [(set (match_operand:SF 0 "register_operand" "=f")
14935         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14936   "TARGET_USE_FANCY_MATH_387
14937    && flag_unsafe_math_optimizations"
14938   "fsin"
14939   [(set_attr "type" "fpspc")
14940    (set_attr "mode" "SF")])
14941
14942 (define_insn "*sinextendsfdf2"
14943   [(set (match_operand:DF 0 "register_operand" "=f")
14944         (unspec:DF [(float_extend:DF
14945                      (match_operand:SF 1 "register_operand" "0"))]
14946                    UNSPEC_SIN))]
14947   "TARGET_USE_FANCY_MATH_387
14948    && flag_unsafe_math_optimizations"
14949   "fsin"
14950   [(set_attr "type" "fpspc")
14951    (set_attr "mode" "DF")])
14952
14953 (define_insn "*sinxf2"
14954   [(set (match_operand:XF 0 "register_operand" "=f")
14955         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14956   "TARGET_USE_FANCY_MATH_387
14957    && flag_unsafe_math_optimizations"
14958   "fsin"
14959   [(set_attr "type" "fpspc")
14960    (set_attr "mode" "XF")])
14961
14962 (define_insn "*cosdf2"
14963   [(set (match_operand:DF 0 "register_operand" "=f")
14964         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14965   "TARGET_USE_FANCY_MATH_387
14966    && flag_unsafe_math_optimizations"
14967   "fcos"
14968   [(set_attr "type" "fpspc")
14969    (set_attr "mode" "DF")])
14970
14971 (define_insn "*cossf2"
14972   [(set (match_operand:SF 0 "register_operand" "=f")
14973         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14974   "TARGET_USE_FANCY_MATH_387
14975    && flag_unsafe_math_optimizations"
14976   "fcos"
14977   [(set_attr "type" "fpspc")
14978    (set_attr "mode" "SF")])
14979
14980 (define_insn "*cosextendsfdf2"
14981   [(set (match_operand:DF 0 "register_operand" "=f")
14982         (unspec:DF [(float_extend:DF
14983                      (match_operand:SF 1 "register_operand" "0"))]
14984                    UNSPEC_COS))]
14985   "TARGET_USE_FANCY_MATH_387
14986    && flag_unsafe_math_optimizations"
14987   "fcos"
14988   [(set_attr "type" "fpspc")
14989    (set_attr "mode" "DF")])
14990
14991 (define_insn "*cosxf2"
14992   [(set (match_operand:XF 0 "register_operand" "=f")
14993         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14994   "TARGET_USE_FANCY_MATH_387
14995    && flag_unsafe_math_optimizations"
14996   "fcos"
14997   [(set_attr "type" "fpspc")
14998    (set_attr "mode" "XF")])
14999
15000 ;; With sincos pattern defined, sin and cos builtin function will be
15001 ;; expanded to sincos pattern with one of its outputs left unused. 
15002 ;; Cse pass  will detected, if two sincos patterns can be combined,
15003 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15004 ;; depending on the unused output.
15005
15006 (define_insn "sincosdf3"
15007   [(set (match_operand:DF 0 "register_operand" "=f")
15008         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15009                    UNSPEC_SINCOS_COS))
15010    (set (match_operand:DF 1 "register_operand" "=u")
15011         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15012   "TARGET_USE_FANCY_MATH_387
15013    && flag_unsafe_math_optimizations"
15014   "fsincos"
15015   [(set_attr "type" "fpspc")
15016    (set_attr "mode" "DF")])
15017
15018 (define_split
15019   [(set (match_operand:DF 0 "register_operand" "")
15020         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15021                    UNSPEC_SINCOS_COS))
15022    (set (match_operand:DF 1 "register_operand" "")
15023         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15024   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15025    && !reload_completed && !reload_in_progress"
15026   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15027   "")
15028
15029 (define_split
15030   [(set (match_operand:DF 0 "register_operand" "")
15031         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15032                    UNSPEC_SINCOS_COS))
15033    (set (match_operand:DF 1 "register_operand" "")
15034         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15035   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15036    && !reload_completed && !reload_in_progress"
15037   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15038   "")
15039
15040 (define_insn "sincossf3"
15041   [(set (match_operand:SF 0 "register_operand" "=f")
15042         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15043                    UNSPEC_SINCOS_COS))
15044    (set (match_operand:SF 1 "register_operand" "=u")
15045         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15046   "TARGET_USE_FANCY_MATH_387
15047    && flag_unsafe_math_optimizations"
15048   "fsincos"
15049   [(set_attr "type" "fpspc")
15050    (set_attr "mode" "SF")])
15051
15052 (define_split
15053   [(set (match_operand:SF 0 "register_operand" "")
15054         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15055                    UNSPEC_SINCOS_COS))
15056    (set (match_operand:SF 1 "register_operand" "")
15057         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15058   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15059    && !reload_completed && !reload_in_progress"
15060   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15061   "")
15062
15063 (define_split
15064   [(set (match_operand:SF 0 "register_operand" "")
15065         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15066                    UNSPEC_SINCOS_COS))
15067    (set (match_operand:SF 1 "register_operand" "")
15068         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15069   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15070    && !reload_completed && !reload_in_progress"
15071   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15072   "")
15073
15074 (define_insn "*sincosextendsfdf3"
15075   [(set (match_operand:DF 0 "register_operand" "=f")
15076         (unspec:DF [(float_extend:DF
15077                      (match_operand:SF 2 "register_operand" "0"))]
15078                    UNSPEC_SINCOS_COS))
15079    (set (match_operand:DF 1 "register_operand" "=u")
15080         (unspec:DF [(float_extend:DF
15081                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15082   "TARGET_USE_FANCY_MATH_387
15083    && flag_unsafe_math_optimizations"
15084   "fsincos"
15085   [(set_attr "type" "fpspc")
15086    (set_attr "mode" "DF")])
15087
15088 (define_split
15089   [(set (match_operand:DF 0 "register_operand" "")
15090         (unspec:DF [(float_extend:DF
15091                      (match_operand:SF 2 "register_operand" ""))]
15092                    UNSPEC_SINCOS_COS))
15093    (set (match_operand:DF 1 "register_operand" "")
15094         (unspec:DF [(float_extend:DF
15095                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15096   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15097    && !reload_completed && !reload_in_progress"
15098   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15099                                    (match_dup 2))] UNSPEC_SIN))]
15100   "")
15101
15102 (define_split
15103   [(set (match_operand:DF 0 "register_operand" "")
15104         (unspec:DF [(float_extend:DF
15105                      (match_operand:SF 2 "register_operand" ""))]
15106                    UNSPEC_SINCOS_COS))
15107    (set (match_operand:DF 1 "register_operand" "")
15108         (unspec:DF [(float_extend:DF
15109                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15110   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15111    && !reload_completed && !reload_in_progress"
15112   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15113                                    (match_dup 2))] UNSPEC_COS))]
15114   "")
15115
15116 (define_insn "sincosxf3"
15117   [(set (match_operand:XF 0 "register_operand" "=f")
15118         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15119                    UNSPEC_SINCOS_COS))
15120    (set (match_operand:XF 1 "register_operand" "=u")
15121         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15122   "TARGET_USE_FANCY_MATH_387
15123    && flag_unsafe_math_optimizations"
15124   "fsincos"
15125   [(set_attr "type" "fpspc")
15126    (set_attr "mode" "XF")])
15127
15128 (define_split
15129   [(set (match_operand:XF 0 "register_operand" "")
15130         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15131                    UNSPEC_SINCOS_COS))
15132    (set (match_operand:XF 1 "register_operand" "")
15133         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15134   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15135    && !reload_completed && !reload_in_progress"
15136   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15137   "")
15138
15139 (define_split
15140   [(set (match_operand:XF 0 "register_operand" "")
15141         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15142                    UNSPEC_SINCOS_COS))
15143    (set (match_operand:XF 1 "register_operand" "")
15144         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15145   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15146    && !reload_completed && !reload_in_progress"
15147   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15148   "")
15149
15150 (define_insn "*tandf3_1"
15151   [(set (match_operand:DF 0 "register_operand" "=f")
15152         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15153                    UNSPEC_TAN_ONE))
15154    (set (match_operand:DF 1 "register_operand" "=u")
15155         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15156   "TARGET_USE_FANCY_MATH_387
15157    && flag_unsafe_math_optimizations"
15158   "fptan"
15159   [(set_attr "type" "fpspc")
15160    (set_attr "mode" "DF")])
15161
15162 ;; optimize sequence: fptan
15163 ;;                    fstp    %st(0)
15164 ;;                    fld1
15165 ;; into fptan insn.
15166
15167 (define_peephole2
15168   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15169                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15170                              UNSPEC_TAN_ONE))
15171              (set (match_operand:DF 1 "register_operand" "")
15172                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15173    (set (match_dup 0)
15174         (match_operand:DF 3 "immediate_operand" ""))]
15175   "standard_80387_constant_p (operands[3]) == 2"
15176   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15177              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15178   "")
15179
15180 (define_expand "tandf2"
15181   [(parallel [(set (match_dup 2)
15182                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15183                               UNSPEC_TAN_ONE))
15184               (set (match_operand:DF 0 "register_operand" "")
15185                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15186   "TARGET_USE_FANCY_MATH_387
15187    && flag_unsafe_math_optimizations"
15188 {
15189   operands[2] = gen_reg_rtx (DFmode);
15190 })
15191
15192 (define_insn "*tansf3_1"
15193   [(set (match_operand:SF 0 "register_operand" "=f")
15194         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15195                    UNSPEC_TAN_ONE))
15196    (set (match_operand:SF 1 "register_operand" "=u")
15197         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15198   "TARGET_USE_FANCY_MATH_387
15199    && flag_unsafe_math_optimizations"
15200   "fptan"
15201   [(set_attr "type" "fpspc")
15202    (set_attr "mode" "SF")])
15203
15204 ;; optimize sequence: fptan
15205 ;;                    fstp    %st(0)
15206 ;;                    fld1
15207 ;; into fptan insn.
15208
15209 (define_peephole2
15210   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15211                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15212                              UNSPEC_TAN_ONE))
15213              (set (match_operand:SF 1 "register_operand" "")
15214                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15215    (set (match_dup 0)
15216         (match_operand:SF 3 "immediate_operand" ""))]
15217   "standard_80387_constant_p (operands[3]) == 2"
15218   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15219              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15220   "")
15221
15222 (define_expand "tansf2"
15223   [(parallel [(set (match_dup 2)
15224                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15225                               UNSPEC_TAN_ONE))
15226               (set (match_operand:SF 0 "register_operand" "")
15227                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15228   "TARGET_USE_FANCY_MATH_387
15229    && flag_unsafe_math_optimizations"
15230 {
15231   operands[2] = gen_reg_rtx (SFmode);
15232 })
15233
15234 (define_insn "*tanxf3_1"
15235   [(set (match_operand:XF 0 "register_operand" "=f")
15236         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15237                    UNSPEC_TAN_ONE))
15238    (set (match_operand:XF 1 "register_operand" "=u")
15239         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15240   "TARGET_USE_FANCY_MATH_387
15241    && flag_unsafe_math_optimizations"
15242   "fptan"
15243   [(set_attr "type" "fpspc")
15244    (set_attr "mode" "XF")])
15245
15246 ;; optimize sequence: fptan
15247 ;;                    fstp    %st(0)
15248 ;;                    fld1
15249 ;; into fptan insn.
15250
15251 (define_peephole2
15252   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15253                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15254                              UNSPEC_TAN_ONE))
15255              (set (match_operand:XF 1 "register_operand" "")
15256                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15257    (set (match_dup 0)
15258         (match_operand:XF 3 "immediate_operand" ""))]
15259   "standard_80387_constant_p (operands[3]) == 2"
15260   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15261              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15262   "")
15263
15264 (define_expand "tanxf2"
15265   [(parallel [(set (match_dup 2)
15266                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15267                               UNSPEC_TAN_ONE))
15268               (set (match_operand:XF 0 "register_operand" "")
15269                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15270   "TARGET_USE_FANCY_MATH_387
15271    && flag_unsafe_math_optimizations"
15272 {
15273   operands[2] = gen_reg_rtx (XFmode);
15274 })
15275
15276 (define_insn "atan2df3_1"
15277   [(set (match_operand:DF 0 "register_operand" "=f")
15278         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15279                     (match_operand:DF 1 "register_operand" "u")]
15280                    UNSPEC_FPATAN))
15281    (clobber (match_scratch:DF 3 "=1"))]
15282   "TARGET_USE_FANCY_MATH_387
15283    && flag_unsafe_math_optimizations"
15284   "fpatan"
15285   [(set_attr "type" "fpspc")
15286    (set_attr "mode" "DF")])
15287
15288 (define_expand "atan2df3"
15289   [(use (match_operand:DF 0 "register_operand" "=f"))
15290    (use (match_operand:DF 2 "register_operand" "0"))
15291    (use (match_operand:DF 1 "register_operand" "u"))]
15292   "TARGET_USE_FANCY_MATH_387
15293    && flag_unsafe_math_optimizations"
15294 {
15295   rtx copy = gen_reg_rtx (DFmode);
15296   emit_move_insn (copy, operands[1]);
15297   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15298   DONE;
15299 })
15300
15301 (define_expand "atandf2"
15302   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15303                    (unspec:DF [(match_dup 2)
15304                                (match_operand:DF 1 "register_operand" "")]
15305                     UNSPEC_FPATAN))
15306               (clobber (match_scratch:DF 3 ""))])]
15307   "TARGET_USE_FANCY_MATH_387
15308    && flag_unsafe_math_optimizations"
15309 {
15310   operands[2] = gen_reg_rtx (DFmode);
15311   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15312 })
15313
15314 (define_insn "atan2sf3_1"
15315   [(set (match_operand:SF 0 "register_operand" "=f")
15316         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15317                     (match_operand:SF 1 "register_operand" "u")]
15318                    UNSPEC_FPATAN))
15319    (clobber (match_scratch:SF 3 "=1"))]
15320   "TARGET_USE_FANCY_MATH_387
15321    && flag_unsafe_math_optimizations"
15322   "fpatan"
15323   [(set_attr "type" "fpspc")
15324    (set_attr "mode" "SF")])
15325
15326 (define_expand "atan2sf3"
15327   [(use (match_operand:SF 0 "register_operand" "=f"))
15328    (use (match_operand:SF 2 "register_operand" "0"))
15329    (use (match_operand:SF 1 "register_operand" "u"))]
15330   "TARGET_USE_FANCY_MATH_387
15331    && flag_unsafe_math_optimizations"
15332 {
15333   rtx copy = gen_reg_rtx (SFmode);
15334   emit_move_insn (copy, operands[1]);
15335   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15336   DONE;
15337 })
15338
15339 (define_expand "atansf2"
15340   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15341                    (unspec:SF [(match_dup 2)
15342                                (match_operand:SF 1 "register_operand" "")]
15343                     UNSPEC_FPATAN))
15344               (clobber (match_scratch:SF 3 ""))])]
15345   "TARGET_USE_FANCY_MATH_387
15346    && flag_unsafe_math_optimizations"
15347 {
15348   operands[2] = gen_reg_rtx (SFmode);
15349   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15350 })
15351
15352 (define_insn "atan2xf3_1"
15353   [(set (match_operand:XF 0 "register_operand" "=f")
15354         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15355                     (match_operand:XF 1 "register_operand" "u")]
15356                    UNSPEC_FPATAN))
15357    (clobber (match_scratch:XF 3 "=1"))]
15358   "TARGET_USE_FANCY_MATH_387
15359    && flag_unsafe_math_optimizations"
15360   "fpatan"
15361   [(set_attr "type" "fpspc")
15362    (set_attr "mode" "XF")])
15363
15364 (define_expand "atan2xf3"
15365   [(use (match_operand:XF 0 "register_operand" "=f"))
15366    (use (match_operand:XF 2 "register_operand" "0"))
15367    (use (match_operand:XF 1 "register_operand" "u"))]
15368   "TARGET_USE_FANCY_MATH_387
15369    && flag_unsafe_math_optimizations"
15370 {
15371   rtx copy = gen_reg_rtx (XFmode);
15372   emit_move_insn (copy, operands[1]);
15373   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15374   DONE;
15375 })
15376
15377 (define_expand "atanxf2"
15378   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15379                    (unspec:XF [(match_dup 2)
15380                                (match_operand:XF 1 "register_operand" "")]
15381                     UNSPEC_FPATAN))
15382               (clobber (match_scratch:XF 3 ""))])]
15383   "TARGET_USE_FANCY_MATH_387
15384    && flag_unsafe_math_optimizations"
15385 {
15386   operands[2] = gen_reg_rtx (XFmode);
15387   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15388 })
15389
15390 (define_expand "asindf2"
15391   [(set (match_dup 2)
15392         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15393    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15394    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15395    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15396    (parallel [(set (match_dup 7)
15397                    (unspec:XF [(match_dup 6) (match_dup 2)]
15398                               UNSPEC_FPATAN))
15399               (clobber (match_scratch:XF 8 ""))])
15400    (set (match_operand:DF 0 "register_operand" "")
15401         (float_truncate:DF (match_dup 7)))]
15402   "TARGET_USE_FANCY_MATH_387
15403    && flag_unsafe_math_optimizations"
15404 {
15405   int i;
15406
15407   for (i=2; i<8; i++)
15408     operands[i] = gen_reg_rtx (XFmode);
15409
15410   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15411 })
15412
15413 (define_expand "asinsf2"
15414   [(set (match_dup 2)
15415         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15416    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15417    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15418    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15419    (parallel [(set (match_dup 7)
15420                    (unspec:XF [(match_dup 6) (match_dup 2)]
15421                               UNSPEC_FPATAN))
15422               (clobber (match_scratch:XF 8 ""))])
15423    (set (match_operand:SF 0 "register_operand" "")
15424         (float_truncate:SF (match_dup 7)))]
15425   "TARGET_USE_FANCY_MATH_387
15426    && flag_unsafe_math_optimizations"
15427 {
15428   int i;
15429
15430   for (i=2; i<8; i++)
15431     operands[i] = gen_reg_rtx (XFmode);
15432
15433   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15434 })
15435
15436 (define_expand "asinxf2"
15437   [(set (match_dup 2)
15438         (mult:XF (match_operand:XF 1 "register_operand" "")
15439                  (match_dup 1)))
15440    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15441    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15442    (parallel [(set (match_operand:XF 0 "register_operand" "")
15443                    (unspec:XF [(match_dup 5) (match_dup 1)]
15444                               UNSPEC_FPATAN))
15445               (clobber (match_scratch:XF 6 ""))])]
15446   "TARGET_USE_FANCY_MATH_387
15447    && flag_unsafe_math_optimizations"
15448 {
15449   int i;
15450
15451   for (i=2; i<6; i++)
15452     operands[i] = gen_reg_rtx (XFmode);
15453
15454   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15455 })
15456
15457 (define_expand "acosdf2"
15458   [(set (match_dup 2)
15459         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15460    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15461    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15462    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15463    (parallel [(set (match_dup 7)
15464                    (unspec:XF [(match_dup 2) (match_dup 6)]
15465                               UNSPEC_FPATAN))
15466               (clobber (match_scratch:XF 8 ""))])
15467    (set (match_operand:DF 0 "register_operand" "")
15468         (float_truncate:DF (match_dup 7)))]
15469   "TARGET_USE_FANCY_MATH_387
15470    && flag_unsafe_math_optimizations"
15471 {
15472   int i;
15473
15474   for (i=2; i<8; i++)
15475     operands[i] = gen_reg_rtx (XFmode);
15476
15477   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15478 })
15479
15480 (define_expand "acossf2"
15481   [(set (match_dup 2)
15482         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15483    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15484    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15485    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15486    (parallel [(set (match_dup 7)
15487                    (unspec:XF [(match_dup 2) (match_dup 6)]
15488                               UNSPEC_FPATAN))
15489               (clobber (match_scratch:XF 8 ""))])
15490    (set (match_operand:SF 0 "register_operand" "")
15491         (float_truncate:SF (match_dup 7)))]
15492   "TARGET_USE_FANCY_MATH_387
15493    && flag_unsafe_math_optimizations"
15494 {
15495   int i;
15496
15497   for (i=2; i<8; i++)
15498     operands[i] = gen_reg_rtx (XFmode);
15499
15500   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15501 })
15502
15503 (define_expand "acosxf2"
15504   [(set (match_dup 2)
15505         (mult:XF (match_operand:XF 1 "register_operand" "")
15506                  (match_dup 1)))
15507    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15508    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15509    (parallel [(set (match_operand:XF 0 "register_operand" "")
15510                    (unspec:XF [(match_dup 1) (match_dup 5)]
15511                               UNSPEC_FPATAN))
15512               (clobber (match_scratch:XF 6 ""))])]
15513   "TARGET_USE_FANCY_MATH_387
15514    && flag_unsafe_math_optimizations"
15515 {
15516   int i;
15517
15518   for (i=2; i<6; i++)
15519     operands[i] = gen_reg_rtx (XFmode);
15520
15521   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15522 })
15523
15524 (define_insn "fyl2x_xf3"
15525   [(set (match_operand:XF 0 "register_operand" "=f")
15526         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15527                     (match_operand:XF 1 "register_operand" "u")]
15528                    UNSPEC_FYL2X))
15529    (clobber (match_scratch:XF 3 "=1"))]
15530   "TARGET_USE_FANCY_MATH_387
15531    && flag_unsafe_math_optimizations"
15532   "fyl2x"
15533   [(set_attr "type" "fpspc")
15534    (set_attr "mode" "XF")])
15535
15536 (define_expand "logsf2"
15537   [(set (match_dup 2)
15538         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15539    (parallel [(set (match_dup 4)
15540                    (unspec:XF [(match_dup 2)
15541                                (match_dup 3)] UNSPEC_FYL2X))
15542               (clobber (match_scratch:XF 5 ""))])
15543    (set (match_operand:SF 0 "register_operand" "")
15544         (float_truncate:SF (match_dup 4)))]
15545   "TARGET_USE_FANCY_MATH_387
15546    && flag_unsafe_math_optimizations"
15547 {
15548   rtx temp;
15549
15550   operands[2] = gen_reg_rtx (XFmode);
15551   operands[3] = gen_reg_rtx (XFmode);
15552   operands[4] = gen_reg_rtx (XFmode);
15553
15554   temp = standard_80387_constant_rtx (4); /* fldln2 */
15555   emit_move_insn (operands[3], temp);
15556 })
15557
15558 (define_expand "logdf2"
15559   [(set (match_dup 2)
15560         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15561    (parallel [(set (match_dup 4)
15562                    (unspec:XF [(match_dup 2)
15563                                (match_dup 3)] UNSPEC_FYL2X))
15564               (clobber (match_scratch:XF 5 ""))])
15565    (set (match_operand:DF 0 "register_operand" "")
15566         (float_truncate:DF (match_dup 4)))]
15567   "TARGET_USE_FANCY_MATH_387
15568    && flag_unsafe_math_optimizations"
15569 {
15570   rtx temp;
15571
15572   operands[2] = gen_reg_rtx (XFmode);
15573   operands[3] = gen_reg_rtx (XFmode);
15574   operands[4] = gen_reg_rtx (XFmode);
15575
15576   temp = standard_80387_constant_rtx (4); /* fldln2 */
15577   emit_move_insn (operands[3], temp);
15578 })
15579
15580 (define_expand "logxf2"
15581   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15582                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15583                                (match_dup 2)] UNSPEC_FYL2X))
15584               (clobber (match_scratch:XF 3 ""))])]
15585   "TARGET_USE_FANCY_MATH_387
15586    && flag_unsafe_math_optimizations"
15587 {
15588   rtx temp;
15589
15590   operands[2] = gen_reg_rtx (XFmode);
15591   temp = standard_80387_constant_rtx (4); /* fldln2 */
15592   emit_move_insn (operands[2], temp);
15593 })
15594
15595 (define_expand "log10sf2"
15596   [(set (match_dup 2)
15597         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15598    (parallel [(set (match_dup 4)
15599                    (unspec:XF [(match_dup 2)
15600                                (match_dup 3)] UNSPEC_FYL2X))
15601               (clobber (match_scratch:XF 5 ""))])
15602    (set (match_operand:SF 0 "register_operand" "")
15603         (float_truncate:SF (match_dup 4)))]
15604   "TARGET_USE_FANCY_MATH_387
15605    && flag_unsafe_math_optimizations"
15606 {
15607   rtx temp;
15608
15609   operands[2] = gen_reg_rtx (XFmode);
15610   operands[3] = gen_reg_rtx (XFmode);
15611   operands[4] = gen_reg_rtx (XFmode);
15612
15613   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15614   emit_move_insn (operands[3], temp);
15615 })
15616
15617 (define_expand "log10df2"
15618   [(set (match_dup 2)
15619         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15620    (parallel [(set (match_dup 4)
15621                    (unspec:XF [(match_dup 2)
15622                                (match_dup 3)] UNSPEC_FYL2X))
15623               (clobber (match_scratch:XF 5 ""))])
15624    (set (match_operand:DF 0 "register_operand" "")
15625         (float_truncate:DF (match_dup 4)))]
15626   "TARGET_USE_FANCY_MATH_387
15627    && flag_unsafe_math_optimizations"
15628 {
15629   rtx temp;
15630
15631   operands[2] = gen_reg_rtx (XFmode);
15632   operands[3] = gen_reg_rtx (XFmode);
15633   operands[4] = gen_reg_rtx (XFmode);
15634
15635   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15636   emit_move_insn (operands[3], temp);
15637 })
15638
15639 (define_expand "log10xf2"
15640   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15641                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15642                                (match_dup 2)] UNSPEC_FYL2X))
15643               (clobber (match_scratch:XF 3 ""))])]
15644   "TARGET_USE_FANCY_MATH_387
15645    && flag_unsafe_math_optimizations"
15646 {
15647   rtx temp;
15648
15649   operands[2] = gen_reg_rtx (XFmode);
15650   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15651   emit_move_insn (operands[2], temp);
15652 })
15653
15654 (define_expand "log2sf2"
15655   [(set (match_dup 2)
15656         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15657    (parallel [(set (match_dup 4)
15658                    (unspec:XF [(match_dup 2)
15659                                (match_dup 3)] UNSPEC_FYL2X))
15660               (clobber (match_scratch:XF 5 ""))])
15661    (set (match_operand:SF 0 "register_operand" "")
15662         (float_truncate:SF (match_dup 4)))]
15663   "TARGET_USE_FANCY_MATH_387
15664    && flag_unsafe_math_optimizations"
15665 {
15666   operands[2] = gen_reg_rtx (XFmode);
15667   operands[3] = gen_reg_rtx (XFmode);
15668   operands[4] = gen_reg_rtx (XFmode);
15669
15670   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15671 })
15672
15673 (define_expand "log2df2"
15674   [(set (match_dup 2)
15675         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15676    (parallel [(set (match_dup 4)
15677                    (unspec:XF [(match_dup 2)
15678                                (match_dup 3)] UNSPEC_FYL2X))
15679               (clobber (match_scratch:XF 5 ""))])
15680    (set (match_operand:DF 0 "register_operand" "")
15681         (float_truncate:DF (match_dup 4)))]
15682   "TARGET_USE_FANCY_MATH_387
15683    && flag_unsafe_math_optimizations"
15684 {
15685   operands[2] = gen_reg_rtx (XFmode);
15686   operands[3] = gen_reg_rtx (XFmode);
15687   operands[4] = gen_reg_rtx (XFmode);
15688
15689   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15690 })
15691
15692 (define_expand "log2xf2"
15693   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15694                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15695                                (match_dup 2)] UNSPEC_FYL2X))
15696               (clobber (match_scratch:XF 3 ""))])]
15697   "TARGET_USE_FANCY_MATH_387
15698    && flag_unsafe_math_optimizations"
15699 {
15700   operands[2] = gen_reg_rtx (XFmode);
15701   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15702 })
15703
15704 (define_insn "fyl2xp1_xf3"
15705   [(set (match_operand:XF 0 "register_operand" "=f")
15706         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15707                     (match_operand:XF 1 "register_operand" "u")]
15708                    UNSPEC_FYL2XP1))
15709    (clobber (match_scratch:XF 3 "=1"))]
15710   "TARGET_USE_FANCY_MATH_387
15711    && flag_unsafe_math_optimizations"
15712   "fyl2xp1"
15713   [(set_attr "type" "fpspc")
15714    (set_attr "mode" "XF")])
15715
15716 (define_expand "log1psf2"
15717   [(use (match_operand:XF 0 "register_operand" ""))
15718    (use (match_operand:XF 1 "register_operand" ""))]
15719   "TARGET_USE_FANCY_MATH_387
15720    && flag_unsafe_math_optimizations"
15721 {
15722   rtx op0 = gen_reg_rtx (XFmode);
15723   rtx op1 = gen_reg_rtx (XFmode);
15724
15725   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15726   ix86_emit_i387_log1p (op0, op1);
15727   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15728   DONE;
15729 })
15730
15731 (define_expand "log1pdf2"
15732   [(use (match_operand:XF 0 "register_operand" ""))
15733    (use (match_operand:XF 1 "register_operand" ""))]
15734   "TARGET_USE_FANCY_MATH_387
15735    && flag_unsafe_math_optimizations"
15736 {
15737   rtx op0 = gen_reg_rtx (XFmode);
15738   rtx op1 = gen_reg_rtx (XFmode);
15739
15740   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15741   ix86_emit_i387_log1p (op0, op1);
15742   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15743   DONE;
15744 })
15745
15746 (define_expand "log1pxf2"
15747   [(use (match_operand:XF 0 "register_operand" ""))
15748    (use (match_operand:XF 1 "register_operand" ""))]
15749   "TARGET_USE_FANCY_MATH_387
15750    && flag_unsafe_math_optimizations"
15751 {
15752   ix86_emit_i387_log1p (operands[0], operands[1]);
15753   DONE;
15754 })
15755
15756 (define_insn "*fxtractxf3"
15757   [(set (match_operand:XF 0 "register_operand" "=f")
15758         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15759                    UNSPEC_XTRACT_FRACT))
15760    (set (match_operand:XF 1 "register_operand" "=u")
15761         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15762   "TARGET_USE_FANCY_MATH_387
15763    && flag_unsafe_math_optimizations"
15764   "fxtract"
15765   [(set_attr "type" "fpspc")
15766    (set_attr "mode" "XF")])
15767
15768 (define_expand "logbsf2"
15769   [(set (match_dup 2)
15770         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15771    (parallel [(set (match_dup 3)
15772                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15773               (set (match_dup 4)
15774                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15775    (set (match_operand:SF 0 "register_operand" "")
15776         (float_truncate:SF (match_dup 4)))]
15777   "TARGET_USE_FANCY_MATH_387
15778    && flag_unsafe_math_optimizations"
15779 {
15780   operands[2] = gen_reg_rtx (XFmode);
15781   operands[3] = gen_reg_rtx (XFmode);
15782   operands[4] = gen_reg_rtx (XFmode);
15783 })
15784
15785 (define_expand "logbdf2"
15786   [(set (match_dup 2)
15787         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15788    (parallel [(set (match_dup 3)
15789                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15790               (set (match_dup 4)
15791                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15792    (set (match_operand:DF 0 "register_operand" "")
15793         (float_truncate:DF (match_dup 4)))]
15794   "TARGET_USE_FANCY_MATH_387
15795    && flag_unsafe_math_optimizations"
15796 {
15797   operands[2] = gen_reg_rtx (XFmode);
15798   operands[3] = gen_reg_rtx (XFmode);
15799   operands[4] = gen_reg_rtx (XFmode);
15800 })
15801
15802 (define_expand "logbxf2"
15803   [(parallel [(set (match_dup 2)
15804                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15805                               UNSPEC_XTRACT_FRACT))
15806               (set (match_operand:XF 0 "register_operand" "")
15807                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15808   "TARGET_USE_FANCY_MATH_387
15809    && flag_unsafe_math_optimizations"
15810 {
15811   operands[2] = gen_reg_rtx (XFmode);
15812 })
15813
15814 (define_expand "ilogbsi2"
15815   [(parallel [(set (match_dup 2)
15816                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15817                               UNSPEC_XTRACT_FRACT))
15818               (set (match_operand:XF 3 "register_operand" "")
15819                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15820    (parallel [(set (match_operand:SI 0 "register_operand" "")
15821                    (fix:SI (match_dup 3)))
15822               (clobber (reg:CC FLAGS_REG))])]
15823   "TARGET_USE_FANCY_MATH_387
15824    && flag_unsafe_math_optimizations"
15825 {
15826   operands[2] = gen_reg_rtx (XFmode);
15827   operands[3] = gen_reg_rtx (XFmode);
15828 })
15829
15830 (define_insn "*f2xm1xf2"
15831   [(set (match_operand:XF 0 "register_operand" "=f")
15832         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15833          UNSPEC_F2XM1))]
15834   "TARGET_USE_FANCY_MATH_387
15835    && flag_unsafe_math_optimizations"
15836   "f2xm1"
15837   [(set_attr "type" "fpspc")
15838    (set_attr "mode" "XF")])
15839
15840 (define_insn "*fscalexf4"
15841   [(set (match_operand:XF 0 "register_operand" "=f")
15842         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15843                     (match_operand:XF 3 "register_operand" "1")]
15844                    UNSPEC_FSCALE_FRACT))
15845    (set (match_operand:XF 1 "register_operand" "=u")
15846         (unspec:XF [(match_dup 2) (match_dup 3)]
15847                    UNSPEC_FSCALE_EXP))]
15848   "TARGET_USE_FANCY_MATH_387
15849    && flag_unsafe_math_optimizations"
15850   "fscale"
15851   [(set_attr "type" "fpspc")
15852    (set_attr "mode" "XF")])
15853
15854 (define_expand "expsf2"
15855   [(set (match_dup 2)
15856         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15857    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15858    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15859    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15860    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15861    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15862    (parallel [(set (match_dup 10)
15863                    (unspec:XF [(match_dup 9) (match_dup 5)]
15864                               UNSPEC_FSCALE_FRACT))
15865               (set (match_dup 11)
15866                    (unspec:XF [(match_dup 9) (match_dup 5)]
15867                               UNSPEC_FSCALE_EXP))])
15868    (set (match_operand:SF 0 "register_operand" "")
15869         (float_truncate:SF (match_dup 10)))]
15870   "TARGET_USE_FANCY_MATH_387
15871    && flag_unsafe_math_optimizations"
15872 {
15873   rtx temp;
15874   int i;
15875
15876   for (i=2; i<12; i++)
15877     operands[i] = gen_reg_rtx (XFmode);
15878   temp = standard_80387_constant_rtx (5); /* fldl2e */
15879   emit_move_insn (operands[3], temp);
15880   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15881 })
15882
15883 (define_expand "expdf2"
15884   [(set (match_dup 2)
15885         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15886    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15887    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15888    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15889    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15890    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15891    (parallel [(set (match_dup 10)
15892                    (unspec:XF [(match_dup 9) (match_dup 5)]
15893                               UNSPEC_FSCALE_FRACT))
15894               (set (match_dup 11)
15895                    (unspec:XF [(match_dup 9) (match_dup 5)]
15896                               UNSPEC_FSCALE_EXP))])
15897    (set (match_operand:DF 0 "register_operand" "")
15898         (float_truncate:DF (match_dup 10)))]
15899   "TARGET_USE_FANCY_MATH_387
15900    && flag_unsafe_math_optimizations"
15901 {
15902   rtx temp;
15903   int i;
15904
15905   for (i=2; i<12; i++)
15906     operands[i] = gen_reg_rtx (XFmode);
15907   temp = standard_80387_constant_rtx (5); /* fldl2e */
15908   emit_move_insn (operands[3], temp);
15909   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15910 })
15911
15912 (define_expand "expxf2"
15913   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15914                                (match_dup 2)))
15915    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15916    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15917    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15918    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15919    (parallel [(set (match_operand:XF 0 "register_operand" "")
15920                    (unspec:XF [(match_dup 8) (match_dup 4)]
15921                               UNSPEC_FSCALE_FRACT))
15922               (set (match_dup 9)
15923                    (unspec:XF [(match_dup 8) (match_dup 4)]
15924                               UNSPEC_FSCALE_EXP))])]
15925   "TARGET_USE_FANCY_MATH_387
15926    && flag_unsafe_math_optimizations"
15927 {
15928   rtx temp;
15929   int i;
15930
15931   for (i=2; i<10; i++)
15932     operands[i] = gen_reg_rtx (XFmode);
15933   temp = standard_80387_constant_rtx (5); /* fldl2e */
15934   emit_move_insn (operands[2], temp);
15935   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15936 })
15937
15938 (define_expand "exp10sf2"
15939   [(set (match_dup 2)
15940         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15941    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15942    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15943    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15944    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15945    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15946    (parallel [(set (match_dup 10)
15947                    (unspec:XF [(match_dup 9) (match_dup 5)]
15948                               UNSPEC_FSCALE_FRACT))
15949               (set (match_dup 11)
15950                    (unspec:XF [(match_dup 9) (match_dup 5)]
15951                               UNSPEC_FSCALE_EXP))])
15952    (set (match_operand:SF 0 "register_operand" "")
15953         (float_truncate:SF (match_dup 10)))]
15954   "TARGET_USE_FANCY_MATH_387
15955    && flag_unsafe_math_optimizations"
15956 {
15957   rtx temp;
15958   int i;
15959
15960   for (i=2; i<12; i++)
15961     operands[i] = gen_reg_rtx (XFmode);
15962   temp = standard_80387_constant_rtx (6); /* fldl2t */
15963   emit_move_insn (operands[3], temp);
15964   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15965 })
15966
15967 (define_expand "exp10df2"
15968   [(set (match_dup 2)
15969         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15970    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15971    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15972    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15973    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15974    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15975    (parallel [(set (match_dup 10)
15976                    (unspec:XF [(match_dup 9) (match_dup 5)]
15977                               UNSPEC_FSCALE_FRACT))
15978               (set (match_dup 11)
15979                    (unspec:XF [(match_dup 9) (match_dup 5)]
15980                               UNSPEC_FSCALE_EXP))])
15981    (set (match_operand:DF 0 "register_operand" "")
15982         (float_truncate:DF (match_dup 10)))]
15983   "TARGET_USE_FANCY_MATH_387
15984    && flag_unsafe_math_optimizations"
15985 {
15986   rtx temp;
15987   int i;
15988
15989   for (i=2; i<12; i++)
15990     operands[i] = gen_reg_rtx (XFmode);
15991   temp = standard_80387_constant_rtx (6); /* fldl2t */
15992   emit_move_insn (operands[3], temp);
15993   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15994 })
15995
15996 (define_expand "exp10xf2"
15997   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15998                                (match_dup 2)))
15999    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16000    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16001    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16002    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16003    (parallel [(set (match_operand:XF 0 "register_operand" "")
16004                    (unspec:XF [(match_dup 8) (match_dup 4)]
16005                               UNSPEC_FSCALE_FRACT))
16006               (set (match_dup 9)
16007                    (unspec:XF [(match_dup 8) (match_dup 4)]
16008                               UNSPEC_FSCALE_EXP))])]
16009   "TARGET_USE_FANCY_MATH_387
16010    && flag_unsafe_math_optimizations"
16011 {
16012   rtx temp;
16013   int i;
16014
16015   for (i=2; i<10; i++)
16016     operands[i] = gen_reg_rtx (XFmode);
16017   temp = standard_80387_constant_rtx (6); /* fldl2t */
16018   emit_move_insn (operands[2], temp);
16019   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16020 })
16021
16022 (define_expand "exp2sf2"
16023   [(set (match_dup 2)
16024         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16025    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16026    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16027    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16028    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16029    (parallel [(set (match_dup 8)
16030                    (unspec:XF [(match_dup 7) (match_dup 3)]
16031                               UNSPEC_FSCALE_FRACT))
16032               (set (match_dup 9)
16033                    (unspec:XF [(match_dup 7) (match_dup 3)]
16034                               UNSPEC_FSCALE_EXP))])
16035    (set (match_operand:SF 0 "register_operand" "")
16036         (float_truncate:SF (match_dup 8)))]
16037   "TARGET_USE_FANCY_MATH_387
16038    && flag_unsafe_math_optimizations"
16039 {
16040   int i;
16041
16042   for (i=2; i<10; i++)
16043     operands[i] = gen_reg_rtx (XFmode);
16044   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16045 })
16046
16047 (define_expand "exp2df2"
16048   [(set (match_dup 2)
16049         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16050    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16051    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16052    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16053    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16054    (parallel [(set (match_dup 8)
16055                    (unspec:XF [(match_dup 7) (match_dup 3)]
16056                               UNSPEC_FSCALE_FRACT))
16057               (set (match_dup 9)
16058                    (unspec:XF [(match_dup 7) (match_dup 3)]
16059                               UNSPEC_FSCALE_EXP))])
16060    (set (match_operand:DF 0 "register_operand" "")
16061         (float_truncate:DF (match_dup 8)))]
16062   "TARGET_USE_FANCY_MATH_387
16063    && flag_unsafe_math_optimizations"
16064 {
16065   int i;
16066
16067   for (i=2; i<10; i++)
16068     operands[i] = gen_reg_rtx (XFmode);
16069   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16070 })
16071
16072 (define_expand "exp2xf2"
16073   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16074    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16075    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16076    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16077    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16078    (parallel [(set (match_operand:XF 0 "register_operand" "")
16079                    (unspec:XF [(match_dup 7) (match_dup 3)]
16080                               UNSPEC_FSCALE_FRACT))
16081               (set (match_dup 8)
16082                    (unspec:XF [(match_dup 7) (match_dup 3)]
16083                               UNSPEC_FSCALE_EXP))])]
16084   "TARGET_USE_FANCY_MATH_387
16085    && flag_unsafe_math_optimizations"
16086 {
16087   int i;
16088
16089   for (i=2; i<9; i++)
16090     operands[i] = gen_reg_rtx (XFmode);
16091   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16092 })
16093
16094 (define_expand "expm1df2"
16095   [(set (match_dup 2)
16096         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16097    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16098    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16099    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16100    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16101    (parallel [(set (match_dup 8)
16102                    (unspec:XF [(match_dup 7) (match_dup 5)]
16103                               UNSPEC_FSCALE_FRACT))
16104                    (set (match_dup 9)
16105                    (unspec:XF [(match_dup 7) (match_dup 5)]
16106                               UNSPEC_FSCALE_EXP))])
16107    (parallel [(set (match_dup 11)
16108                    (unspec:XF [(match_dup 10) (match_dup 9)]
16109                               UNSPEC_FSCALE_FRACT))
16110               (set (match_dup 12)
16111                    (unspec:XF [(match_dup 10) (match_dup 9)]
16112                               UNSPEC_FSCALE_EXP))])
16113    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16114    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16115    (set (match_operand:DF 0 "register_operand" "")
16116         (float_truncate:DF (match_dup 14)))]
16117   "TARGET_USE_FANCY_MATH_387
16118    && flag_unsafe_math_optimizations"
16119 {
16120   rtx temp;
16121   int i;
16122
16123   for (i=2; i<15; i++)
16124     operands[i] = gen_reg_rtx (XFmode);
16125   temp = standard_80387_constant_rtx (5); /* fldl2e */
16126   emit_move_insn (operands[3], temp);
16127   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16128 })
16129
16130 (define_expand "expm1sf2"
16131   [(set (match_dup 2)
16132         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16133    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16134    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16135    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16136    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16137    (parallel [(set (match_dup 8)
16138                    (unspec:XF [(match_dup 7) (match_dup 5)]
16139                               UNSPEC_FSCALE_FRACT))
16140                    (set (match_dup 9)
16141                    (unspec:XF [(match_dup 7) (match_dup 5)]
16142                               UNSPEC_FSCALE_EXP))])
16143    (parallel [(set (match_dup 11)
16144                    (unspec:XF [(match_dup 10) (match_dup 9)]
16145                               UNSPEC_FSCALE_FRACT))
16146               (set (match_dup 12)
16147                    (unspec:XF [(match_dup 10) (match_dup 9)]
16148                               UNSPEC_FSCALE_EXP))])
16149    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16150    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16151    (set (match_operand:SF 0 "register_operand" "")
16152         (float_truncate:SF (match_dup 14)))]
16153   "TARGET_USE_FANCY_MATH_387
16154    && flag_unsafe_math_optimizations"
16155 {
16156   rtx temp;
16157   int i;
16158
16159   for (i=2; i<15; i++)
16160     operands[i] = gen_reg_rtx (XFmode);
16161   temp = standard_80387_constant_rtx (5); /* fldl2e */
16162   emit_move_insn (operands[3], temp);
16163   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16164 })
16165
16166 (define_expand "expm1xf2"
16167   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16168                                (match_dup 2)))
16169    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16170    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16171    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16172    (parallel [(set (match_dup 7)
16173                    (unspec:XF [(match_dup 6) (match_dup 4)]
16174                               UNSPEC_FSCALE_FRACT))
16175                    (set (match_dup 8)
16176                    (unspec:XF [(match_dup 6) (match_dup 4)]
16177                               UNSPEC_FSCALE_EXP))])
16178    (parallel [(set (match_dup 10)
16179                    (unspec:XF [(match_dup 9) (match_dup 8)]
16180                               UNSPEC_FSCALE_FRACT))
16181               (set (match_dup 11)
16182                    (unspec:XF [(match_dup 9) (match_dup 8)]
16183                               UNSPEC_FSCALE_EXP))])
16184    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16185    (set (match_operand:XF 0 "register_operand" "")
16186         (plus:XF (match_dup 12) (match_dup 7)))]
16187   "TARGET_USE_FANCY_MATH_387
16188    && flag_unsafe_math_optimizations"
16189 {
16190   rtx temp;
16191   int i;
16192
16193   for (i=2; i<13; i++)
16194     operands[i] = gen_reg_rtx (XFmode);
16195   temp = standard_80387_constant_rtx (5); /* fldl2e */
16196   emit_move_insn (operands[2], temp);
16197   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16198 })
16199 \f
16200
16201 (define_insn "frndintxf2"
16202   [(set (match_operand:XF 0 "register_operand" "=f")
16203         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16204          UNSPEC_FRNDINT))]
16205   "TARGET_USE_FANCY_MATH_387
16206    && flag_unsafe_math_optimizations"
16207   "frndint"
16208   [(set_attr "type" "fpspc")
16209    (set_attr "mode" "XF")])
16210
16211 (define_expand "rintdf2"
16212   [(use (match_operand:DF 0 "register_operand" ""))
16213    (use (match_operand:DF 1 "register_operand" ""))]
16214   "TARGET_USE_FANCY_MATH_387
16215    && flag_unsafe_math_optimizations"
16216 {
16217   rtx op0 = gen_reg_rtx (XFmode);
16218   rtx op1 = gen_reg_rtx (XFmode);
16219
16220   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16221   emit_insn (gen_frndintxf2 (op0, op1));
16222
16223   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16224   DONE;
16225 })
16226
16227 (define_expand "rintsf2"
16228   [(use (match_operand:SF 0 "register_operand" ""))
16229    (use (match_operand:SF 1 "register_operand" ""))]
16230   "TARGET_USE_FANCY_MATH_387
16231    && flag_unsafe_math_optimizations"
16232 {
16233   rtx op0 = gen_reg_rtx (XFmode);
16234   rtx op1 = gen_reg_rtx (XFmode);
16235
16236   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16237   emit_insn (gen_frndintxf2 (op0, op1));
16238
16239   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16240   DONE;
16241 })
16242
16243 (define_expand "rintxf2"
16244   [(use (match_operand:XF 0 "register_operand" ""))
16245    (use (match_operand:XF 1 "register_operand" ""))]
16246   "TARGET_USE_FANCY_MATH_387
16247    && flag_unsafe_math_optimizations"
16248 {
16249   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16250   DONE;
16251 })
16252
16253 (define_insn "frndintxf2_floor"
16254   [(set (match_operand:XF 0 "register_operand" "=f")
16255         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16256          UNSPEC_FRNDINT_FLOOR))
16257    (use (match_operand:HI 2 "memory_operand" "m"))
16258    (use (match_operand:HI 3 "memory_operand" "m"))]
16259   "TARGET_USE_FANCY_MATH_387
16260    && flag_unsafe_math_optimizations"
16261   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16262   [(set_attr "type" "frndint")
16263    (set_attr "i387_cw" "floor")
16264    (set_attr "mode" "XF")])
16265
16266 (define_expand "floordf2"
16267   [(use (match_operand:DF 0 "register_operand" ""))
16268    (use (match_operand:DF 1 "register_operand" ""))]
16269   "TARGET_USE_FANCY_MATH_387
16270    && flag_unsafe_math_optimizations"
16271 {
16272   rtx op0 = gen_reg_rtx (XFmode);
16273   rtx op1 = gen_reg_rtx (XFmode);
16274   rtx op2 = assign_386_stack_local (HImode, 1);
16275   rtx op3 = assign_386_stack_local (HImode, 2);
16276         
16277   ix86_optimize_mode_switching = 1;
16278
16279   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16280   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16281
16282   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16283   DONE;
16284 })
16285
16286 (define_expand "floorsf2"
16287   [(use (match_operand:SF 0 "register_operand" ""))
16288    (use (match_operand:SF 1 "register_operand" ""))]
16289   "TARGET_USE_FANCY_MATH_387
16290    && flag_unsafe_math_optimizations"
16291 {
16292   rtx op0 = gen_reg_rtx (XFmode);
16293   rtx op1 = gen_reg_rtx (XFmode);
16294   rtx op2 = assign_386_stack_local (HImode, 1);
16295   rtx op3 = assign_386_stack_local (HImode, 2);
16296         
16297   ix86_optimize_mode_switching = 1;
16298
16299   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16300   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16301
16302   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16303   DONE;
16304 })
16305
16306 (define_expand "floorxf2"
16307   [(use (match_operand:XF 0 "register_operand" ""))
16308    (use (match_operand:XF 1 "register_operand" ""))]
16309   "TARGET_USE_FANCY_MATH_387
16310    && flag_unsafe_math_optimizations"
16311 {
16312   rtx op2 = assign_386_stack_local (HImode, 1);
16313   rtx op3 = assign_386_stack_local (HImode, 2);
16314         
16315   ix86_optimize_mode_switching = 1;
16316
16317   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16318   DONE;
16319 })
16320
16321 (define_insn "frndintxf2_ceil"
16322   [(set (match_operand:XF 0 "register_operand" "=f")
16323         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16324          UNSPEC_FRNDINT_CEIL))
16325    (use (match_operand:HI 2 "memory_operand" "m"))
16326    (use (match_operand:HI 3 "memory_operand" "m"))]
16327   "TARGET_USE_FANCY_MATH_387
16328    && flag_unsafe_math_optimizations"
16329   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16330   [(set_attr "type" "frndint")
16331    (set_attr "i387_cw" "ceil")
16332    (set_attr "mode" "XF")])
16333
16334 (define_expand "ceildf2"
16335   [(use (match_operand:DF 0 "register_operand" ""))
16336    (use (match_operand:DF 1 "register_operand" ""))]
16337   "TARGET_USE_FANCY_MATH_387
16338    && flag_unsafe_math_optimizations"
16339 {
16340   rtx op0 = gen_reg_rtx (XFmode);
16341   rtx op1 = gen_reg_rtx (XFmode);
16342   rtx op2 = assign_386_stack_local (HImode, 1);
16343   rtx op3 = assign_386_stack_local (HImode, 2);
16344         
16345   ix86_optimize_mode_switching = 1;
16346
16347   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16348   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16349
16350   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16351   DONE;
16352 })
16353
16354 (define_expand "ceilsf2"
16355   [(use (match_operand:SF 0 "register_operand" ""))
16356    (use (match_operand:SF 1 "register_operand" ""))]
16357   "TARGET_USE_FANCY_MATH_387
16358    && flag_unsafe_math_optimizations"
16359 {
16360   rtx op0 = gen_reg_rtx (XFmode);
16361   rtx op1 = gen_reg_rtx (XFmode);
16362   rtx op2 = assign_386_stack_local (HImode, 1);
16363   rtx op3 = assign_386_stack_local (HImode, 2);
16364         
16365   ix86_optimize_mode_switching = 1;
16366
16367   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16368   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16369
16370   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16371   DONE;
16372 })
16373
16374 (define_expand "ceilxf2"
16375   [(use (match_operand:XF 0 "register_operand" ""))
16376    (use (match_operand:XF 1 "register_operand" ""))]
16377   "TARGET_USE_FANCY_MATH_387
16378    && flag_unsafe_math_optimizations"
16379 {
16380   rtx op2 = assign_386_stack_local (HImode, 1);
16381   rtx op3 = assign_386_stack_local (HImode, 2);
16382         
16383   ix86_optimize_mode_switching = 1;
16384
16385   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16386   DONE;
16387 })
16388
16389 (define_insn "frndintxf2_trunc"
16390   [(set (match_operand:XF 0 "register_operand" "=f")
16391         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16392          UNSPEC_FRNDINT_TRUNC))
16393    (use (match_operand:HI 2 "memory_operand" "m"))
16394    (use (match_operand:HI 3 "memory_operand" "m"))]
16395   "TARGET_USE_FANCY_MATH_387
16396    && flag_unsafe_math_optimizations"
16397   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16398   [(set_attr "type" "frndint")
16399    (set_attr "i387_cw" "trunc")
16400    (set_attr "mode" "XF")])
16401
16402 (define_expand "btruncdf2"
16403   [(use (match_operand:DF 0 "register_operand" ""))
16404    (use (match_operand:DF 1 "register_operand" ""))]
16405   "TARGET_USE_FANCY_MATH_387
16406    && flag_unsafe_math_optimizations"
16407 {
16408   rtx op0 = gen_reg_rtx (XFmode);
16409   rtx op1 = gen_reg_rtx (XFmode);
16410   rtx op2 = assign_386_stack_local (HImode, 1);
16411   rtx op3 = assign_386_stack_local (HImode, 2);
16412         
16413   ix86_optimize_mode_switching = 1;
16414
16415   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16416   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16417
16418   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16419   DONE;
16420 })
16421
16422 (define_expand "btruncsf2"
16423   [(use (match_operand:SF 0 "register_operand" ""))
16424    (use (match_operand:SF 1 "register_operand" ""))]
16425   "TARGET_USE_FANCY_MATH_387
16426    && flag_unsafe_math_optimizations"
16427 {
16428   rtx op0 = gen_reg_rtx (XFmode);
16429   rtx op1 = gen_reg_rtx (XFmode);
16430   rtx op2 = assign_386_stack_local (HImode, 1);
16431   rtx op3 = assign_386_stack_local (HImode, 2);
16432         
16433   ix86_optimize_mode_switching = 1;
16434
16435   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16436   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16437
16438   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16439   DONE;
16440 })
16441
16442 (define_expand "btruncxf2"
16443   [(use (match_operand:XF 0 "register_operand" ""))
16444    (use (match_operand:XF 1 "register_operand" ""))]
16445   "TARGET_USE_FANCY_MATH_387
16446    && flag_unsafe_math_optimizations"
16447 {
16448   rtx op2 = assign_386_stack_local (HImode, 1);
16449   rtx op3 = assign_386_stack_local (HImode, 2);
16450         
16451   ix86_optimize_mode_switching = 1;
16452
16453   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16454   DONE;
16455 })
16456
16457 (define_insn "frndintxf2_mask_pm"
16458   [(set (match_operand:XF 0 "register_operand" "=f")
16459         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16460          UNSPEC_FRNDINT_MASK_PM))
16461    (use (match_operand:HI 2 "memory_operand" "m"))
16462    (use (match_operand:HI 3 "memory_operand" "m"))]
16463   "TARGET_USE_FANCY_MATH_387
16464    && flag_unsafe_math_optimizations"
16465   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16466   [(set_attr "type" "frndint")
16467    (set_attr "i387_cw" "mask_pm")
16468    (set_attr "mode" "XF")])
16469
16470 (define_expand "nearbyintdf2"
16471   [(use (match_operand:DF 0 "register_operand" ""))
16472    (use (match_operand:DF 1 "register_operand" ""))]
16473   "TARGET_USE_FANCY_MATH_387
16474    && flag_unsafe_math_optimizations"
16475 {
16476   rtx op0 = gen_reg_rtx (XFmode);
16477   rtx op1 = gen_reg_rtx (XFmode);
16478   rtx op2 = assign_386_stack_local (HImode, 1);
16479   rtx op3 = assign_386_stack_local (HImode, 2);
16480         
16481   ix86_optimize_mode_switching = 1;
16482
16483   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16484   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16485
16486   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16487   DONE;
16488 })
16489
16490 (define_expand "nearbyintsf2"
16491   [(use (match_operand:SF 0 "register_operand" ""))
16492    (use (match_operand:SF 1 "register_operand" ""))]
16493   "TARGET_USE_FANCY_MATH_387
16494    && flag_unsafe_math_optimizations"
16495 {
16496   rtx op0 = gen_reg_rtx (XFmode);
16497   rtx op1 = gen_reg_rtx (XFmode);
16498   rtx op2 = assign_386_stack_local (HImode, 1);
16499   rtx op3 = assign_386_stack_local (HImode, 2);
16500         
16501   ix86_optimize_mode_switching = 1;
16502
16503   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16504   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16505
16506   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16507   DONE;
16508 })
16509
16510 (define_expand "nearbyintxf2"
16511   [(use (match_operand:XF 0 "register_operand" ""))
16512    (use (match_operand:XF 1 "register_operand" ""))]
16513   "TARGET_USE_FANCY_MATH_387
16514    && flag_unsafe_math_optimizations"
16515 {
16516   rtx op2 = assign_386_stack_local (HImode, 1);
16517   rtx op3 = assign_386_stack_local (HImode, 2);
16518         
16519   ix86_optimize_mode_switching = 1;
16520
16521   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16522                                      op2, op3));
16523   DONE;
16524 })
16525
16526 \f
16527 ;; Block operation instructions
16528
16529 (define_insn "cld"
16530  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16531  ""
16532  "cld"
16533   [(set_attr "type" "cld")])
16534
16535 (define_expand "movmemsi"
16536   [(use (match_operand:BLK 0 "memory_operand" ""))
16537    (use (match_operand:BLK 1 "memory_operand" ""))
16538    (use (match_operand:SI 2 "nonmemory_operand" ""))
16539    (use (match_operand:SI 3 "const_int_operand" ""))]
16540   "! optimize_size"
16541 {
16542  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16543    DONE;
16544  else
16545    FAIL;
16546 })
16547
16548 (define_expand "movmemdi"
16549   [(use (match_operand:BLK 0 "memory_operand" ""))
16550    (use (match_operand:BLK 1 "memory_operand" ""))
16551    (use (match_operand:DI 2 "nonmemory_operand" ""))
16552    (use (match_operand:DI 3 "const_int_operand" ""))]
16553   "TARGET_64BIT"
16554 {
16555  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16556    DONE;
16557  else
16558    FAIL;
16559 })
16560
16561 ;; Most CPUs don't like single string operations
16562 ;; Handle this case here to simplify previous expander.
16563
16564 (define_expand "strmov"
16565   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16566    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16567    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16568               (clobber (reg:CC FLAGS_REG))])
16569    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16570               (clobber (reg:CC FLAGS_REG))])]
16571   ""
16572 {
16573   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16574
16575   /* If .md ever supports :P for Pmode, these can be directly
16576      in the pattern above.  */
16577   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16578   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16579
16580   if (TARGET_SINGLE_STRINGOP || optimize_size)
16581     {
16582       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16583                                       operands[2], operands[3],
16584                                       operands[5], operands[6]));
16585       DONE;
16586     }
16587
16588   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16589 })
16590
16591 (define_expand "strmov_singleop"
16592   [(parallel [(set (match_operand 1 "memory_operand" "")
16593                    (match_operand 3 "memory_operand" ""))
16594               (set (match_operand 0 "register_operand" "")
16595                    (match_operand 4 "" ""))
16596               (set (match_operand 2 "register_operand" "")
16597                    (match_operand 5 "" ""))
16598               (use (reg:SI DIRFLAG_REG))])]
16599   "TARGET_SINGLE_STRINGOP || optimize_size"
16600   "")
16601
16602 (define_insn "*strmovdi_rex_1"
16603   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16604         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16605    (set (match_operand:DI 0 "register_operand" "=D")
16606         (plus:DI (match_dup 2)
16607                  (const_int 8)))
16608    (set (match_operand:DI 1 "register_operand" "=S")
16609         (plus:DI (match_dup 3)
16610                  (const_int 8)))
16611    (use (reg:SI DIRFLAG_REG))]
16612   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16613   "movsq"
16614   [(set_attr "type" "str")
16615    (set_attr "mode" "DI")
16616    (set_attr "memory" "both")])
16617
16618 (define_insn "*strmovsi_1"
16619   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16620         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16621    (set (match_operand:SI 0 "register_operand" "=D")
16622         (plus:SI (match_dup 2)
16623                  (const_int 4)))
16624    (set (match_operand:SI 1 "register_operand" "=S")
16625         (plus:SI (match_dup 3)
16626                  (const_int 4)))
16627    (use (reg:SI DIRFLAG_REG))]
16628   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16629   "{movsl|movsd}"
16630   [(set_attr "type" "str")
16631    (set_attr "mode" "SI")
16632    (set_attr "memory" "both")])
16633
16634 (define_insn "*strmovsi_rex_1"
16635   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16636         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16637    (set (match_operand:DI 0 "register_operand" "=D")
16638         (plus:DI (match_dup 2)
16639                  (const_int 4)))
16640    (set (match_operand:DI 1 "register_operand" "=S")
16641         (plus:DI (match_dup 3)
16642                  (const_int 4)))
16643    (use (reg:SI DIRFLAG_REG))]
16644   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16645   "{movsl|movsd}"
16646   [(set_attr "type" "str")
16647    (set_attr "mode" "SI")
16648    (set_attr "memory" "both")])
16649
16650 (define_insn "*strmovhi_1"
16651   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16652         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16653    (set (match_operand:SI 0 "register_operand" "=D")
16654         (plus:SI (match_dup 2)
16655                  (const_int 2)))
16656    (set (match_operand:SI 1 "register_operand" "=S")
16657         (plus:SI (match_dup 3)
16658                  (const_int 2)))
16659    (use (reg:SI DIRFLAG_REG))]
16660   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16661   "movsw"
16662   [(set_attr "type" "str")
16663    (set_attr "memory" "both")
16664    (set_attr "mode" "HI")])
16665
16666 (define_insn "*strmovhi_rex_1"
16667   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16668         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16669    (set (match_operand:DI 0 "register_operand" "=D")
16670         (plus:DI (match_dup 2)
16671                  (const_int 2)))
16672    (set (match_operand:DI 1 "register_operand" "=S")
16673         (plus:DI (match_dup 3)
16674                  (const_int 2)))
16675    (use (reg:SI DIRFLAG_REG))]
16676   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16677   "movsw"
16678   [(set_attr "type" "str")
16679    (set_attr "memory" "both")
16680    (set_attr "mode" "HI")])
16681
16682 (define_insn "*strmovqi_1"
16683   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16684         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16685    (set (match_operand:SI 0 "register_operand" "=D")
16686         (plus:SI (match_dup 2)
16687                  (const_int 1)))
16688    (set (match_operand:SI 1 "register_operand" "=S")
16689         (plus:SI (match_dup 3)
16690                  (const_int 1)))
16691    (use (reg:SI DIRFLAG_REG))]
16692   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16693   "movsb"
16694   [(set_attr "type" "str")
16695    (set_attr "memory" "both")
16696    (set_attr "mode" "QI")])
16697
16698 (define_insn "*strmovqi_rex_1"
16699   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16700         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16701    (set (match_operand:DI 0 "register_operand" "=D")
16702         (plus:DI (match_dup 2)
16703                  (const_int 1)))
16704    (set (match_operand:DI 1 "register_operand" "=S")
16705         (plus:DI (match_dup 3)
16706                  (const_int 1)))
16707    (use (reg:SI DIRFLAG_REG))]
16708   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16709   "movsb"
16710   [(set_attr "type" "str")
16711    (set_attr "memory" "both")
16712    (set_attr "mode" "QI")])
16713
16714 (define_expand "rep_mov"
16715   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16716               (set (match_operand 0 "register_operand" "")
16717                    (match_operand 5 "" ""))
16718               (set (match_operand 2 "register_operand" "")
16719                    (match_operand 6 "" ""))
16720               (set (match_operand 1 "memory_operand" "")
16721                    (match_operand 3 "memory_operand" ""))
16722               (use (match_dup 4))
16723               (use (reg:SI DIRFLAG_REG))])]
16724   ""
16725   "")
16726
16727 (define_insn "*rep_movdi_rex64"
16728   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16729    (set (match_operand:DI 0 "register_operand" "=D") 
16730         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16731                             (const_int 3))
16732                  (match_operand:DI 3 "register_operand" "0")))
16733    (set (match_operand:DI 1 "register_operand" "=S") 
16734         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16735                  (match_operand:DI 4 "register_operand" "1")))
16736    (set (mem:BLK (match_dup 3))
16737         (mem:BLK (match_dup 4)))
16738    (use (match_dup 5))
16739    (use (reg:SI DIRFLAG_REG))]
16740   "TARGET_64BIT"
16741   "{rep\;movsq|rep movsq}"
16742   [(set_attr "type" "str")
16743    (set_attr "prefix_rep" "1")
16744    (set_attr "memory" "both")
16745    (set_attr "mode" "DI")])
16746
16747 (define_insn "*rep_movsi"
16748   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16749    (set (match_operand:SI 0 "register_operand" "=D") 
16750         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16751                             (const_int 2))
16752                  (match_operand:SI 3 "register_operand" "0")))
16753    (set (match_operand:SI 1 "register_operand" "=S") 
16754         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16755                  (match_operand:SI 4 "register_operand" "1")))
16756    (set (mem:BLK (match_dup 3))
16757         (mem:BLK (match_dup 4)))
16758    (use (match_dup 5))
16759    (use (reg:SI DIRFLAG_REG))]
16760   "!TARGET_64BIT"
16761   "{rep\;movsl|rep movsd}"
16762   [(set_attr "type" "str")
16763    (set_attr "prefix_rep" "1")
16764    (set_attr "memory" "both")
16765    (set_attr "mode" "SI")])
16766
16767 (define_insn "*rep_movsi_rex64"
16768   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16769    (set (match_operand:DI 0 "register_operand" "=D") 
16770         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16771                             (const_int 2))
16772                  (match_operand:DI 3 "register_operand" "0")))
16773    (set (match_operand:DI 1 "register_operand" "=S") 
16774         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16775                  (match_operand:DI 4 "register_operand" "1")))
16776    (set (mem:BLK (match_dup 3))
16777         (mem:BLK (match_dup 4)))
16778    (use (match_dup 5))
16779    (use (reg:SI DIRFLAG_REG))]
16780   "TARGET_64BIT"
16781   "{rep\;movsl|rep movsd}"
16782   [(set_attr "type" "str")
16783    (set_attr "prefix_rep" "1")
16784    (set_attr "memory" "both")
16785    (set_attr "mode" "SI")])
16786
16787 (define_insn "*rep_movqi"
16788   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16789    (set (match_operand:SI 0 "register_operand" "=D") 
16790         (plus:SI (match_operand:SI 3 "register_operand" "0")
16791                  (match_operand:SI 5 "register_operand" "2")))
16792    (set (match_operand:SI 1 "register_operand" "=S") 
16793         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16794    (set (mem:BLK (match_dup 3))
16795         (mem:BLK (match_dup 4)))
16796    (use (match_dup 5))
16797    (use (reg:SI DIRFLAG_REG))]
16798   "!TARGET_64BIT"
16799   "{rep\;movsb|rep movsb}"
16800   [(set_attr "type" "str")
16801    (set_attr "prefix_rep" "1")
16802    (set_attr "memory" "both")
16803    (set_attr "mode" "SI")])
16804
16805 (define_insn "*rep_movqi_rex64"
16806   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16807    (set (match_operand:DI 0 "register_operand" "=D") 
16808         (plus:DI (match_operand:DI 3 "register_operand" "0")
16809                  (match_operand:DI 5 "register_operand" "2")))
16810    (set (match_operand:DI 1 "register_operand" "=S") 
16811         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16812    (set (mem:BLK (match_dup 3))
16813         (mem:BLK (match_dup 4)))
16814    (use (match_dup 5))
16815    (use (reg:SI DIRFLAG_REG))]
16816   "TARGET_64BIT"
16817   "{rep\;movsb|rep movsb}"
16818   [(set_attr "type" "str")
16819    (set_attr "prefix_rep" "1")
16820    (set_attr "memory" "both")
16821    (set_attr "mode" "SI")])
16822
16823 (define_expand "clrmemsi"
16824    [(use (match_operand:BLK 0 "memory_operand" ""))
16825     (use (match_operand:SI 1 "nonmemory_operand" ""))
16826     (use (match_operand 2 "const_int_operand" ""))]
16827   ""
16828 {
16829  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16830    DONE;
16831  else
16832    FAIL;
16833 })
16834
16835 (define_expand "clrmemdi"
16836    [(use (match_operand:BLK 0 "memory_operand" ""))
16837     (use (match_operand:DI 1 "nonmemory_operand" ""))
16838     (use (match_operand 2 "const_int_operand" ""))]
16839   "TARGET_64BIT"
16840 {
16841  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16842    DONE;
16843  else
16844    FAIL;
16845 })
16846
16847 ;; Most CPUs don't like single string operations
16848 ;; Handle this case here to simplify previous expander.
16849
16850 (define_expand "strset"
16851   [(set (match_operand 1 "memory_operand" "")
16852         (match_operand 2 "register_operand" ""))
16853    (parallel [(set (match_operand 0 "register_operand" "")
16854                    (match_dup 3))
16855               (clobber (reg:CC FLAGS_REG))])]
16856   ""
16857 {
16858   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16859     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16860
16861   /* If .md ever supports :P for Pmode, this can be directly
16862      in the pattern above.  */
16863   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16864                               GEN_INT (GET_MODE_SIZE (GET_MODE
16865                                                       (operands[2]))));
16866   if (TARGET_SINGLE_STRINGOP || optimize_size)
16867     {
16868       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16869                                       operands[3]));
16870       DONE;
16871     }
16872 })
16873
16874 (define_expand "strset_singleop"
16875   [(parallel [(set (match_operand 1 "memory_operand" "")
16876                    (match_operand 2 "register_operand" ""))
16877               (set (match_operand 0 "register_operand" "")
16878                    (match_operand 3 "" ""))
16879               (use (reg:SI DIRFLAG_REG))])]
16880   "TARGET_SINGLE_STRINGOP || optimize_size"
16881   "")
16882
16883 (define_insn "*strsetdi_rex_1"
16884   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16885         (match_operand:DI 2 "register_operand" "a"))
16886    (set (match_operand:DI 0 "register_operand" "=D")
16887         (plus:DI (match_dup 1)
16888                  (const_int 8)))
16889    (use (reg:SI DIRFLAG_REG))]
16890   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16891   "stosq"
16892   [(set_attr "type" "str")
16893    (set_attr "memory" "store")
16894    (set_attr "mode" "DI")])
16895
16896 (define_insn "*strsetsi_1"
16897   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16898         (match_operand:SI 2 "register_operand" "a"))
16899    (set (match_operand:SI 0 "register_operand" "=D")
16900         (plus:SI (match_dup 1)
16901                  (const_int 4)))
16902    (use (reg:SI DIRFLAG_REG))]
16903   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16904   "{stosl|stosd}"
16905   [(set_attr "type" "str")
16906    (set_attr "memory" "store")
16907    (set_attr "mode" "SI")])
16908
16909 (define_insn "*strsetsi_rex_1"
16910   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16911         (match_operand:SI 2 "register_operand" "a"))
16912    (set (match_operand:DI 0 "register_operand" "=D")
16913         (plus:DI (match_dup 1)
16914                  (const_int 4)))
16915    (use (reg:SI DIRFLAG_REG))]
16916   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16917   "{stosl|stosd}"
16918   [(set_attr "type" "str")
16919    (set_attr "memory" "store")
16920    (set_attr "mode" "SI")])
16921
16922 (define_insn "*strsethi_1"
16923   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16924         (match_operand:HI 2 "register_operand" "a"))
16925    (set (match_operand:SI 0 "register_operand" "=D")
16926         (plus:SI (match_dup 1)
16927                  (const_int 2)))
16928    (use (reg:SI DIRFLAG_REG))]
16929   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16930   "stosw"
16931   [(set_attr "type" "str")
16932    (set_attr "memory" "store")
16933    (set_attr "mode" "HI")])
16934
16935 (define_insn "*strsethi_rex_1"
16936   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16937         (match_operand:HI 2 "register_operand" "a"))
16938    (set (match_operand:DI 0 "register_operand" "=D")
16939         (plus:DI (match_dup 1)
16940                  (const_int 2)))
16941    (use (reg:SI DIRFLAG_REG))]
16942   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16943   "stosw"
16944   [(set_attr "type" "str")
16945    (set_attr "memory" "store")
16946    (set_attr "mode" "HI")])
16947
16948 (define_insn "*strsetqi_1"
16949   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16950         (match_operand:QI 2 "register_operand" "a"))
16951    (set (match_operand:SI 0 "register_operand" "=D")
16952         (plus:SI (match_dup 1)
16953                  (const_int 1)))
16954    (use (reg:SI DIRFLAG_REG))]
16955   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16956   "stosb"
16957   [(set_attr "type" "str")
16958    (set_attr "memory" "store")
16959    (set_attr "mode" "QI")])
16960
16961 (define_insn "*strsetqi_rex_1"
16962   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16963         (match_operand:QI 2 "register_operand" "a"))
16964    (set (match_operand:DI 0 "register_operand" "=D")
16965         (plus:DI (match_dup 1)
16966                  (const_int 1)))
16967    (use (reg:SI DIRFLAG_REG))]
16968   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16969   "stosb"
16970   [(set_attr "type" "str")
16971    (set_attr "memory" "store")
16972    (set_attr "mode" "QI")])
16973
16974 (define_expand "rep_stos"
16975   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16976               (set (match_operand 0 "register_operand" "")
16977                    (match_operand 4 "" ""))
16978               (set (match_operand 2 "memory_operand" "") (const_int 0))
16979               (use (match_operand 3 "register_operand" ""))
16980               (use (match_dup 1))
16981               (use (reg:SI DIRFLAG_REG))])]
16982   ""
16983   "")
16984
16985 (define_insn "*rep_stosdi_rex64"
16986   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16987    (set (match_operand:DI 0 "register_operand" "=D") 
16988         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16989                             (const_int 3))
16990                  (match_operand:DI 3 "register_operand" "0")))
16991    (set (mem:BLK (match_dup 3))
16992         (const_int 0))
16993    (use (match_operand:DI 2 "register_operand" "a"))
16994    (use (match_dup 4))
16995    (use (reg:SI DIRFLAG_REG))]
16996   "TARGET_64BIT"
16997   "{rep\;stosq|rep stosq}"
16998   [(set_attr "type" "str")
16999    (set_attr "prefix_rep" "1")
17000    (set_attr "memory" "store")
17001    (set_attr "mode" "DI")])
17002
17003 (define_insn "*rep_stossi"
17004   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17005    (set (match_operand:SI 0 "register_operand" "=D") 
17006         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17007                             (const_int 2))
17008                  (match_operand:SI 3 "register_operand" "0")))
17009    (set (mem:BLK (match_dup 3))
17010         (const_int 0))
17011    (use (match_operand:SI 2 "register_operand" "a"))
17012    (use (match_dup 4))
17013    (use (reg:SI DIRFLAG_REG))]
17014   "!TARGET_64BIT"
17015   "{rep\;stosl|rep stosd}"
17016   [(set_attr "type" "str")
17017    (set_attr "prefix_rep" "1")
17018    (set_attr "memory" "store")
17019    (set_attr "mode" "SI")])
17020
17021 (define_insn "*rep_stossi_rex64"
17022   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17023    (set (match_operand:DI 0 "register_operand" "=D") 
17024         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17025                             (const_int 2))
17026                  (match_operand:DI 3 "register_operand" "0")))
17027    (set (mem:BLK (match_dup 3))
17028         (const_int 0))
17029    (use (match_operand:SI 2 "register_operand" "a"))
17030    (use (match_dup 4))
17031    (use (reg:SI DIRFLAG_REG))]
17032   "TARGET_64BIT"
17033   "{rep\;stosl|rep stosd}"
17034   [(set_attr "type" "str")
17035    (set_attr "prefix_rep" "1")
17036    (set_attr "memory" "store")
17037    (set_attr "mode" "SI")])
17038
17039 (define_insn "*rep_stosqi"
17040   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17041    (set (match_operand:SI 0 "register_operand" "=D") 
17042         (plus:SI (match_operand:SI 3 "register_operand" "0")
17043                  (match_operand:SI 4 "register_operand" "1")))
17044    (set (mem:BLK (match_dup 3))
17045         (const_int 0))
17046    (use (match_operand:QI 2 "register_operand" "a"))
17047    (use (match_dup 4))
17048    (use (reg:SI DIRFLAG_REG))]
17049   "!TARGET_64BIT"
17050   "{rep\;stosb|rep stosb}"
17051   [(set_attr "type" "str")
17052    (set_attr "prefix_rep" "1")
17053    (set_attr "memory" "store")
17054    (set_attr "mode" "QI")])
17055
17056 (define_insn "*rep_stosqi_rex64"
17057   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17058    (set (match_operand:DI 0 "register_operand" "=D") 
17059         (plus:DI (match_operand:DI 3 "register_operand" "0")
17060                  (match_operand:DI 4 "register_operand" "1")))
17061    (set (mem:BLK (match_dup 3))
17062         (const_int 0))
17063    (use (match_operand:QI 2 "register_operand" "a"))
17064    (use (match_dup 4))
17065    (use (reg:SI DIRFLAG_REG))]
17066   "TARGET_64BIT"
17067   "{rep\;stosb|rep stosb}"
17068   [(set_attr "type" "str")
17069    (set_attr "prefix_rep" "1")
17070    (set_attr "memory" "store")
17071    (set_attr "mode" "QI")])
17072
17073 (define_expand "cmpstrsi"
17074   [(set (match_operand:SI 0 "register_operand" "")
17075         (compare:SI (match_operand:BLK 1 "general_operand" "")
17076                     (match_operand:BLK 2 "general_operand" "")))
17077    (use (match_operand 3 "general_operand" ""))
17078    (use (match_operand 4 "immediate_operand" ""))]
17079   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17080 {
17081   rtx addr1, addr2, out, outlow, count, countreg, align;
17082
17083   /* Can't use this if the user has appropriated esi or edi.  */
17084   if (global_regs[4] || global_regs[5])
17085     FAIL;
17086
17087   out = operands[0];
17088   if (GET_CODE (out) != REG)
17089     out = gen_reg_rtx (SImode);
17090
17091   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17092   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17093   if (addr1 != XEXP (operands[1], 0))
17094     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17095   if (addr2 != XEXP (operands[2], 0))
17096     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17097
17098   count = operands[3];
17099   countreg = ix86_zero_extend_to_Pmode (count);
17100
17101   /* %%% Iff we are testing strict equality, we can use known alignment
17102      to good advantage.  This may be possible with combine, particularly
17103      once cc0 is dead.  */
17104   align = operands[4];
17105
17106   emit_insn (gen_cld ());
17107   if (GET_CODE (count) == CONST_INT)
17108     {
17109       if (INTVAL (count) == 0)
17110         {
17111           emit_move_insn (operands[0], const0_rtx);
17112           DONE;
17113         }
17114       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17115                                     operands[1], operands[2]));
17116     }
17117   else
17118     {
17119       if (TARGET_64BIT)
17120         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17121       else
17122         emit_insn (gen_cmpsi_1 (countreg, countreg));
17123       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17124                                  operands[1], operands[2]));
17125     }
17126
17127   outlow = gen_lowpart (QImode, out);
17128   emit_insn (gen_cmpintqi (outlow));
17129   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17130
17131   if (operands[0] != out)
17132     emit_move_insn (operands[0], out);
17133
17134   DONE;
17135 })
17136
17137 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17138
17139 (define_expand "cmpintqi"
17140   [(set (match_dup 1)
17141         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17142    (set (match_dup 2)
17143         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17144    (parallel [(set (match_operand:QI 0 "register_operand" "")
17145                    (minus:QI (match_dup 1)
17146                              (match_dup 2)))
17147               (clobber (reg:CC FLAGS_REG))])]
17148   ""
17149   "operands[1] = gen_reg_rtx (QImode);
17150    operands[2] = gen_reg_rtx (QImode);")
17151
17152 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17153 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17154
17155 (define_expand "cmpstrqi_nz_1"
17156   [(parallel [(set (reg:CC FLAGS_REG)
17157                    (compare:CC (match_operand 4 "memory_operand" "")
17158                                (match_operand 5 "memory_operand" "")))
17159               (use (match_operand 2 "register_operand" ""))
17160               (use (match_operand:SI 3 "immediate_operand" ""))
17161               (use (reg:SI DIRFLAG_REG))
17162               (clobber (match_operand 0 "register_operand" ""))
17163               (clobber (match_operand 1 "register_operand" ""))
17164               (clobber (match_dup 2))])]
17165   ""
17166   "")
17167
17168 (define_insn "*cmpstrqi_nz_1"
17169   [(set (reg:CC FLAGS_REG)
17170         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17171                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17172    (use (match_operand:SI 6 "register_operand" "2"))
17173    (use (match_operand:SI 3 "immediate_operand" "i"))
17174    (use (reg:SI DIRFLAG_REG))
17175    (clobber (match_operand:SI 0 "register_operand" "=S"))
17176    (clobber (match_operand:SI 1 "register_operand" "=D"))
17177    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17178   "!TARGET_64BIT"
17179   "repz{\;| }cmpsb"
17180   [(set_attr "type" "str")
17181    (set_attr "mode" "QI")
17182    (set_attr "prefix_rep" "1")])
17183
17184 (define_insn "*cmpstrqi_nz_rex_1"
17185   [(set (reg:CC FLAGS_REG)
17186         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17187                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17188    (use (match_operand:DI 6 "register_operand" "2"))
17189    (use (match_operand:SI 3 "immediate_operand" "i"))
17190    (use (reg:SI DIRFLAG_REG))
17191    (clobber (match_operand:DI 0 "register_operand" "=S"))
17192    (clobber (match_operand:DI 1 "register_operand" "=D"))
17193    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17194   "TARGET_64BIT"
17195   "repz{\;| }cmpsb"
17196   [(set_attr "type" "str")
17197    (set_attr "mode" "QI")
17198    (set_attr "prefix_rep" "1")])
17199
17200 ;; The same, but the count is not known to not be zero.
17201
17202 (define_expand "cmpstrqi_1"
17203   [(parallel [(set (reg:CC FLAGS_REG)
17204                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17205                                      (const_int 0))
17206                   (compare:CC (match_operand 4 "memory_operand" "")
17207                               (match_operand 5 "memory_operand" ""))
17208                   (const_int 0)))
17209               (use (match_operand:SI 3 "immediate_operand" ""))
17210               (use (reg:CC FLAGS_REG))
17211               (use (reg:SI DIRFLAG_REG))
17212               (clobber (match_operand 0 "register_operand" ""))
17213               (clobber (match_operand 1 "register_operand" ""))
17214               (clobber (match_dup 2))])]
17215   ""
17216   "")
17217
17218 (define_insn "*cmpstrqi_1"
17219   [(set (reg:CC FLAGS_REG)
17220         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17221                              (const_int 0))
17222           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17223                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17224           (const_int 0)))
17225    (use (match_operand:SI 3 "immediate_operand" "i"))
17226    (use (reg:CC FLAGS_REG))
17227    (use (reg:SI DIRFLAG_REG))
17228    (clobber (match_operand:SI 0 "register_operand" "=S"))
17229    (clobber (match_operand:SI 1 "register_operand" "=D"))
17230    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17231   "!TARGET_64BIT"
17232   "repz{\;| }cmpsb"
17233   [(set_attr "type" "str")
17234    (set_attr "mode" "QI")
17235    (set_attr "prefix_rep" "1")])
17236
17237 (define_insn "*cmpstrqi_rex_1"
17238   [(set (reg:CC FLAGS_REG)
17239         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17240                              (const_int 0))
17241           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17242                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17243           (const_int 0)))
17244    (use (match_operand:SI 3 "immediate_operand" "i"))
17245    (use (reg:CC FLAGS_REG))
17246    (use (reg:SI DIRFLAG_REG))
17247    (clobber (match_operand:DI 0 "register_operand" "=S"))
17248    (clobber (match_operand:DI 1 "register_operand" "=D"))
17249    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17250   "TARGET_64BIT"
17251   "repz{\;| }cmpsb"
17252   [(set_attr "type" "str")
17253    (set_attr "mode" "QI")
17254    (set_attr "prefix_rep" "1")])
17255
17256 (define_expand "strlensi"
17257   [(set (match_operand:SI 0 "register_operand" "")
17258         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17259                     (match_operand:QI 2 "immediate_operand" "")
17260                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17261   ""
17262 {
17263  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17264    DONE;
17265  else
17266    FAIL;
17267 })
17268
17269 (define_expand "strlendi"
17270   [(set (match_operand:DI 0 "register_operand" "")
17271         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17272                     (match_operand:QI 2 "immediate_operand" "")
17273                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17274   ""
17275 {
17276  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17277    DONE;
17278  else
17279    FAIL;
17280 })
17281
17282 (define_expand "strlenqi_1"
17283   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17284               (use (reg:SI DIRFLAG_REG))
17285               (clobber (match_operand 1 "register_operand" ""))
17286               (clobber (reg:CC FLAGS_REG))])]
17287   ""
17288   "")
17289
17290 (define_insn "*strlenqi_1"
17291   [(set (match_operand:SI 0 "register_operand" "=&c")
17292         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17293                     (match_operand:QI 2 "register_operand" "a")
17294                     (match_operand:SI 3 "immediate_operand" "i")
17295                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17296    (use (reg:SI DIRFLAG_REG))
17297    (clobber (match_operand:SI 1 "register_operand" "=D"))
17298    (clobber (reg:CC FLAGS_REG))]
17299   "!TARGET_64BIT"
17300   "repnz{\;| }scasb"
17301   [(set_attr "type" "str")
17302    (set_attr "mode" "QI")
17303    (set_attr "prefix_rep" "1")])
17304
17305 (define_insn "*strlenqi_rex_1"
17306   [(set (match_operand:DI 0 "register_operand" "=&c")
17307         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17308                     (match_operand:QI 2 "register_operand" "a")
17309                     (match_operand:DI 3 "immediate_operand" "i")
17310                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17311    (use (reg:SI DIRFLAG_REG))
17312    (clobber (match_operand:DI 1 "register_operand" "=D"))
17313    (clobber (reg:CC FLAGS_REG))]
17314   "TARGET_64BIT"
17315   "repnz{\;| }scasb"
17316   [(set_attr "type" "str")
17317    (set_attr "mode" "QI")
17318    (set_attr "prefix_rep" "1")])
17319
17320 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17321 ;; handled in combine, but it is not currently up to the task.
17322 ;; When used for their truth value, the cmpstr* expanders generate
17323 ;; code like this:
17324 ;;
17325 ;;   repz cmpsb
17326 ;;   seta       %al
17327 ;;   setb       %dl
17328 ;;   cmpb       %al, %dl
17329 ;;   jcc        label
17330 ;;
17331 ;; The intermediate three instructions are unnecessary.
17332
17333 ;; This one handles cmpstr*_nz_1...
17334 (define_peephole2
17335   [(parallel[
17336      (set (reg:CC FLAGS_REG)
17337           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17338                       (mem:BLK (match_operand 5 "register_operand" ""))))
17339      (use (match_operand 6 "register_operand" ""))
17340      (use (match_operand:SI 3 "immediate_operand" ""))
17341      (use (reg:SI DIRFLAG_REG))
17342      (clobber (match_operand 0 "register_operand" ""))
17343      (clobber (match_operand 1 "register_operand" ""))
17344      (clobber (match_operand 2 "register_operand" ""))])
17345    (set (match_operand:QI 7 "register_operand" "")
17346         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17347    (set (match_operand:QI 8 "register_operand" "")
17348         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17349    (set (reg FLAGS_REG)
17350         (compare (match_dup 7) (match_dup 8)))
17351   ]
17352   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17353   [(parallel[
17354      (set (reg:CC FLAGS_REG)
17355           (compare:CC (mem:BLK (match_dup 4))
17356                       (mem:BLK (match_dup 5))))
17357      (use (match_dup 6))
17358      (use (match_dup 3))
17359      (use (reg:SI DIRFLAG_REG))
17360      (clobber (match_dup 0))
17361      (clobber (match_dup 1))
17362      (clobber (match_dup 2))])]
17363   "")
17364
17365 ;; ...and this one handles cmpstr*_1.
17366 (define_peephole2
17367   [(parallel[
17368      (set (reg:CC FLAGS_REG)
17369           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17370                                (const_int 0))
17371             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17372                         (mem:BLK (match_operand 5 "register_operand" "")))
17373             (const_int 0)))
17374      (use (match_operand:SI 3 "immediate_operand" ""))
17375      (use (reg:CC FLAGS_REG))
17376      (use (reg:SI DIRFLAG_REG))
17377      (clobber (match_operand 0 "register_operand" ""))
17378      (clobber (match_operand 1 "register_operand" ""))
17379      (clobber (match_operand 2 "register_operand" ""))])
17380    (set (match_operand:QI 7 "register_operand" "")
17381         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17382    (set (match_operand:QI 8 "register_operand" "")
17383         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17384    (set (reg FLAGS_REG)
17385         (compare (match_dup 7) (match_dup 8)))
17386   ]
17387   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17388   [(parallel[
17389      (set (reg:CC FLAGS_REG)
17390           (if_then_else:CC (ne (match_dup 6)
17391                                (const_int 0))
17392             (compare:CC (mem:BLK (match_dup 4))
17393                         (mem:BLK (match_dup 5)))
17394             (const_int 0)))
17395      (use (match_dup 3))
17396      (use (reg:CC FLAGS_REG))
17397      (use (reg:SI DIRFLAG_REG))
17398      (clobber (match_dup 0))
17399      (clobber (match_dup 1))
17400      (clobber (match_dup 2))])]
17401   "")
17402
17403
17404 \f
17405 ;; Conditional move instructions.
17406
17407 (define_expand "movdicc"
17408   [(set (match_operand:DI 0 "register_operand" "")
17409         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17410                          (match_operand:DI 2 "general_operand" "")
17411                          (match_operand:DI 3 "general_operand" "")))]
17412   "TARGET_64BIT"
17413   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17414
17415 (define_insn "x86_movdicc_0_m1_rex64"
17416   [(set (match_operand:DI 0 "register_operand" "=r")
17417         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17418           (const_int -1)
17419           (const_int 0)))
17420    (clobber (reg:CC FLAGS_REG))]
17421   "TARGET_64BIT"
17422   "sbb{q}\t%0, %0"
17423   ; Since we don't have the proper number of operands for an alu insn,
17424   ; fill in all the blanks.
17425   [(set_attr "type" "alu")
17426    (set_attr "pent_pair" "pu")
17427    (set_attr "memory" "none")
17428    (set_attr "imm_disp" "false")
17429    (set_attr "mode" "DI")
17430    (set_attr "length_immediate" "0")])
17431
17432 (define_insn "movdicc_c_rex64"
17433   [(set (match_operand:DI 0 "register_operand" "=r,r")
17434         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17435                                 [(reg FLAGS_REG) (const_int 0)])
17436                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17437                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17438   "TARGET_64BIT && TARGET_CMOVE
17439    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17440   "@
17441    cmov%O2%C1\t{%2, %0|%0, %2}
17442    cmov%O2%c1\t{%3, %0|%0, %3}"
17443   [(set_attr "type" "icmov")
17444    (set_attr "mode" "DI")])
17445
17446 (define_expand "movsicc"
17447   [(set (match_operand:SI 0 "register_operand" "")
17448         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17449                          (match_operand:SI 2 "general_operand" "")
17450                          (match_operand:SI 3 "general_operand" "")))]
17451   ""
17452   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17453
17454 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17455 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17456 ;; So just document what we're doing explicitly.
17457
17458 (define_insn "x86_movsicc_0_m1"
17459   [(set (match_operand:SI 0 "register_operand" "=r")
17460         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17461           (const_int -1)
17462           (const_int 0)))
17463    (clobber (reg:CC FLAGS_REG))]
17464   ""
17465   "sbb{l}\t%0, %0"
17466   ; Since we don't have the proper number of operands for an alu insn,
17467   ; fill in all the blanks.
17468   [(set_attr "type" "alu")
17469    (set_attr "pent_pair" "pu")
17470    (set_attr "memory" "none")
17471    (set_attr "imm_disp" "false")
17472    (set_attr "mode" "SI")
17473    (set_attr "length_immediate" "0")])
17474
17475 (define_insn "*movsicc_noc"
17476   [(set (match_operand:SI 0 "register_operand" "=r,r")
17477         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17478                                 [(reg FLAGS_REG) (const_int 0)])
17479                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17480                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17481   "TARGET_CMOVE
17482    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17483   "@
17484    cmov%O2%C1\t{%2, %0|%0, %2}
17485    cmov%O2%c1\t{%3, %0|%0, %3}"
17486   [(set_attr "type" "icmov")
17487    (set_attr "mode" "SI")])
17488
17489 (define_expand "movhicc"
17490   [(set (match_operand:HI 0 "register_operand" "")
17491         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17492                          (match_operand:HI 2 "general_operand" "")
17493                          (match_operand:HI 3 "general_operand" "")))]
17494   "TARGET_HIMODE_MATH"
17495   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17496
17497 (define_insn "*movhicc_noc"
17498   [(set (match_operand:HI 0 "register_operand" "=r,r")
17499         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17500                                 [(reg FLAGS_REG) (const_int 0)])
17501                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17502                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17503   "TARGET_CMOVE
17504    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17505   "@
17506    cmov%O2%C1\t{%2, %0|%0, %2}
17507    cmov%O2%c1\t{%3, %0|%0, %3}"
17508   [(set_attr "type" "icmov")
17509    (set_attr "mode" "HI")])
17510
17511 (define_expand "movqicc"
17512   [(set (match_operand:QI 0 "register_operand" "")
17513         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17514                          (match_operand:QI 2 "general_operand" "")
17515                          (match_operand:QI 3 "general_operand" "")))]
17516   "TARGET_QIMODE_MATH"
17517   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17518
17519 (define_insn_and_split "*movqicc_noc"
17520   [(set (match_operand:QI 0 "register_operand" "=r,r")
17521         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17522                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17523                       (match_operand:QI 2 "register_operand" "r,0")
17524                       (match_operand:QI 3 "register_operand" "0,r")))]
17525   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17526   "#"
17527   "&& reload_completed"
17528   [(set (match_dup 0)
17529         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17530                       (match_dup 2)
17531                       (match_dup 3)))]
17532   "operands[0] = gen_lowpart (SImode, operands[0]);
17533    operands[2] = gen_lowpart (SImode, operands[2]);
17534    operands[3] = gen_lowpart (SImode, operands[3]);"
17535   [(set_attr "type" "icmov")
17536    (set_attr "mode" "SI")])
17537
17538 (define_expand "movsfcc"
17539   [(set (match_operand:SF 0 "register_operand" "")
17540         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17541                          (match_operand:SF 2 "register_operand" "")
17542                          (match_operand:SF 3 "register_operand" "")))]
17543   "TARGET_CMOVE"
17544   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17545
17546 (define_insn "*movsfcc_1"
17547   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17548         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17549                                 [(reg FLAGS_REG) (const_int 0)])
17550                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17551                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17552   "TARGET_CMOVE
17553    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17554   "@
17555    fcmov%F1\t{%2, %0|%0, %2}
17556    fcmov%f1\t{%3, %0|%0, %3}
17557    cmov%O2%C1\t{%2, %0|%0, %2}
17558    cmov%O2%c1\t{%3, %0|%0, %3}"
17559   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17560    (set_attr "mode" "SF,SF,SI,SI")])
17561
17562 (define_expand "movdfcc"
17563   [(set (match_operand:DF 0 "register_operand" "")
17564         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17565                          (match_operand:DF 2 "register_operand" "")
17566                          (match_operand:DF 3 "register_operand" "")))]
17567   "TARGET_CMOVE"
17568   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17569
17570 (define_insn "*movdfcc_1"
17571   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17572         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17573                                 [(reg FLAGS_REG) (const_int 0)])
17574                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17575                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17576   "!TARGET_64BIT && TARGET_CMOVE
17577    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17578   "@
17579    fcmov%F1\t{%2, %0|%0, %2}
17580    fcmov%f1\t{%3, %0|%0, %3}
17581    #
17582    #"
17583   [(set_attr "type" "fcmov,fcmov,multi,multi")
17584    (set_attr "mode" "DF")])
17585
17586 (define_insn "*movdfcc_1_rex64"
17587   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17588         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17589                                 [(reg FLAGS_REG) (const_int 0)])
17590                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17591                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17592   "TARGET_64BIT && TARGET_CMOVE
17593    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17594   "@
17595    fcmov%F1\t{%2, %0|%0, %2}
17596    fcmov%f1\t{%3, %0|%0, %3}
17597    cmov%O2%C1\t{%2, %0|%0, %2}
17598    cmov%O2%c1\t{%3, %0|%0, %3}"
17599   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17600    (set_attr "mode" "DF")])
17601
17602 (define_split
17603   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17604         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17605                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17606                       (match_operand:DF 2 "nonimmediate_operand" "")
17607                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17608   "!TARGET_64BIT && reload_completed"
17609   [(set (match_dup 2)
17610         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17611                       (match_dup 5)
17612                       (match_dup 7)))
17613    (set (match_dup 3)
17614         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17615                       (match_dup 6)
17616                       (match_dup 8)))]
17617   "split_di (operands+2, 1, operands+5, operands+6);
17618    split_di (operands+3, 1, operands+7, operands+8);
17619    split_di (operands, 1, operands+2, operands+3);")
17620
17621 (define_expand "movxfcc"
17622   [(set (match_operand:XF 0 "register_operand" "")
17623         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17624                          (match_operand:XF 2 "register_operand" "")
17625                          (match_operand:XF 3 "register_operand" "")))]
17626   "TARGET_CMOVE"
17627   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17628
17629 (define_insn "*movxfcc_1"
17630   [(set (match_operand:XF 0 "register_operand" "=f,f")
17631         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17632                                 [(reg FLAGS_REG) (const_int 0)])
17633                       (match_operand:XF 2 "register_operand" "f,0")
17634                       (match_operand:XF 3 "register_operand" "0,f")))]
17635   "TARGET_CMOVE"
17636   "@
17637    fcmov%F1\t{%2, %0|%0, %2}
17638    fcmov%f1\t{%3, %0|%0, %3}"
17639   [(set_attr "type" "fcmov")
17640    (set_attr "mode" "XF")])
17641
17642 (define_expand "minsf3"
17643   [(parallel [
17644      (set (match_operand:SF 0 "register_operand" "")
17645           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17646                                (match_operand:SF 2 "nonimmediate_operand" ""))
17647                            (match_dup 1)
17648                            (match_dup 2)))
17649      (clobber (reg:CC FLAGS_REG))])]
17650   "TARGET_SSE"
17651   "")
17652
17653 (define_insn "*minsf"
17654   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17655         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17656                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17657                          (match_dup 1)
17658                          (match_dup 2)))
17659    (clobber (reg:CC FLAGS_REG))]
17660   "TARGET_SSE && TARGET_IEEE_FP"
17661   "#")
17662
17663 (define_insn "*minsf_nonieee"
17664   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17665         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17666                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17667                          (match_dup 1)
17668                          (match_dup 2)))
17669    (clobber (reg:CC FLAGS_REG))]
17670   "TARGET_SSE && !TARGET_IEEE_FP
17671    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17672   "#")
17673
17674 (define_split
17675   [(set (match_operand:SF 0 "register_operand" "")
17676         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17677                              (match_operand:SF 2 "nonimmediate_operand" ""))
17678                          (match_operand:SF 3 "register_operand" "")
17679                          (match_operand:SF 4 "nonimmediate_operand" "")))
17680    (clobber (reg:CC FLAGS_REG))]
17681   "SSE_REG_P (operands[0]) && reload_completed
17682    && ((operands_match_p (operands[1], operands[3])
17683         && operands_match_p (operands[2], operands[4]))
17684        || (operands_match_p (operands[1], operands[4])
17685            && operands_match_p (operands[2], operands[3])))"
17686   [(set (match_dup 0)
17687         (if_then_else:SF (lt (match_dup 1)
17688                              (match_dup 2))
17689                          (match_dup 1)
17690                          (match_dup 2)))])
17691
17692 ;; Conditional addition patterns
17693 (define_expand "addqicc"
17694   [(match_operand:QI 0 "register_operand" "")
17695    (match_operand 1 "comparison_operator" "")
17696    (match_operand:QI 2 "register_operand" "")
17697    (match_operand:QI 3 "const_int_operand" "")]
17698   ""
17699   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17700
17701 (define_expand "addhicc"
17702   [(match_operand:HI 0 "register_operand" "")
17703    (match_operand 1 "comparison_operator" "")
17704    (match_operand:HI 2 "register_operand" "")
17705    (match_operand:HI 3 "const_int_operand" "")]
17706   ""
17707   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17708
17709 (define_expand "addsicc"
17710   [(match_operand:SI 0 "register_operand" "")
17711    (match_operand 1 "comparison_operator" "")
17712    (match_operand:SI 2 "register_operand" "")
17713    (match_operand:SI 3 "const_int_operand" "")]
17714   ""
17715   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17716
17717 (define_expand "adddicc"
17718   [(match_operand:DI 0 "register_operand" "")
17719    (match_operand 1 "comparison_operator" "")
17720    (match_operand:DI 2 "register_operand" "")
17721    (match_operand:DI 3 "const_int_operand" "")]
17722   "TARGET_64BIT"
17723   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17724
17725 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17726
17727 (define_split
17728   [(set (match_operand:SF 0 "fp_register_operand" "")
17729         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17730                              (match_operand:SF 2 "register_operand" ""))
17731                          (match_operand:SF 3 "register_operand" "")
17732                          (match_operand:SF 4 "register_operand" "")))
17733    (clobber (reg:CC FLAGS_REG))]
17734   "reload_completed
17735    && ((operands_match_p (operands[1], operands[3])
17736         && operands_match_p (operands[2], operands[4]))
17737        || (operands_match_p (operands[1], operands[4])
17738            && operands_match_p (operands[2], operands[3])))"
17739   [(set (reg:CCFP FLAGS_REG)
17740         (compare:CCFP (match_dup 2)
17741                       (match_dup 1)))
17742    (set (match_dup 0)
17743         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17744                          (match_dup 1)
17745                          (match_dup 2)))])
17746
17747 (define_insn "*minsf_sse"
17748   [(set (match_operand:SF 0 "register_operand" "=x")
17749         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17750                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17751                          (match_dup 1)
17752                          (match_dup 2)))]
17753   "TARGET_SSE && reload_completed"
17754   "minss\t{%2, %0|%0, %2}"
17755   [(set_attr "type" "sse")
17756    (set_attr "mode" "SF")])
17757
17758 (define_expand "mindf3"
17759   [(parallel [
17760      (set (match_operand:DF 0 "register_operand" "")
17761           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17762                                (match_operand:DF 2 "nonimmediate_operand" ""))
17763                            (match_dup 1)
17764                            (match_dup 2)))
17765      (clobber (reg:CC FLAGS_REG))])]
17766   "TARGET_SSE2 && TARGET_SSE_MATH"
17767   "#")
17768
17769 (define_insn "*mindf"
17770   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17771         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17772                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17773                          (match_dup 1)
17774                          (match_dup 2)))
17775    (clobber (reg:CC FLAGS_REG))]
17776   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17777   "#")
17778
17779 (define_insn "*mindf_nonieee"
17780   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17781         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17782                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17783                          (match_dup 1)
17784                          (match_dup 2)))
17785    (clobber (reg:CC FLAGS_REG))]
17786   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17787    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17788   "#")
17789
17790 (define_split
17791   [(set (match_operand:DF 0 "register_operand" "")
17792         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17793                              (match_operand:DF 2 "nonimmediate_operand" ""))
17794                          (match_operand:DF 3 "register_operand" "")
17795                          (match_operand:DF 4 "nonimmediate_operand" "")))
17796    (clobber (reg:CC FLAGS_REG))]
17797   "SSE_REG_P (operands[0]) && reload_completed
17798    && ((operands_match_p (operands[1], operands[3])
17799         && operands_match_p (operands[2], operands[4]))
17800        || (operands_match_p (operands[1], operands[4])
17801            && operands_match_p (operands[2], operands[3])))"
17802   [(set (match_dup 0)
17803         (if_then_else:DF (lt (match_dup 1)
17804                              (match_dup 2))
17805                          (match_dup 1)
17806                          (match_dup 2)))])
17807
17808 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17809 (define_split
17810   [(set (match_operand:DF 0 "fp_register_operand" "")
17811         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17812                              (match_operand:DF 2 "register_operand" ""))
17813                          (match_operand:DF 3 "register_operand" "")
17814                          (match_operand:DF 4 "register_operand" "")))
17815    (clobber (reg:CC FLAGS_REG))]
17816   "reload_completed
17817    && ((operands_match_p (operands[1], operands[3])
17818         && operands_match_p (operands[2], operands[4]))
17819        || (operands_match_p (operands[1], operands[4])
17820            && operands_match_p (operands[2], operands[3])))"
17821   [(set (reg:CCFP FLAGS_REG)
17822         (compare:CCFP (match_dup 2)
17823                       (match_dup 1)))
17824    (set (match_dup 0)
17825         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17826                          (match_dup 1)
17827                          (match_dup 2)))])
17828
17829 (define_insn "*mindf_sse"
17830   [(set (match_operand:DF 0 "register_operand" "=Y")
17831         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17832                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17833                          (match_dup 1)
17834                          (match_dup 2)))]
17835   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17836   "minsd\t{%2, %0|%0, %2}"
17837   [(set_attr "type" "sse")
17838    (set_attr "mode" "DF")])
17839
17840 (define_expand "maxsf3"
17841   [(parallel [
17842      (set (match_operand:SF 0 "register_operand" "")
17843           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17844                                (match_operand:SF 2 "nonimmediate_operand" ""))
17845                            (match_dup 1)
17846                            (match_dup 2)))
17847      (clobber (reg:CC FLAGS_REG))])]
17848   "TARGET_SSE"
17849   "#")
17850
17851 (define_insn "*maxsf"
17852   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17853         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17854                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17855                          (match_dup 1)
17856                          (match_dup 2)))
17857    (clobber (reg:CC FLAGS_REG))]
17858   "TARGET_SSE && TARGET_IEEE_FP"
17859   "#")
17860
17861 (define_insn "*maxsf_nonieee"
17862   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17863         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17864                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17865                          (match_dup 1)
17866                          (match_dup 2)))
17867    (clobber (reg:CC FLAGS_REG))]
17868   "TARGET_SSE && !TARGET_IEEE_FP
17869    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17870   "#")
17871
17872 (define_split
17873   [(set (match_operand:SF 0 "register_operand" "")
17874         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17875                              (match_operand:SF 2 "nonimmediate_operand" ""))
17876                          (match_operand:SF 3 "register_operand" "")
17877                          (match_operand:SF 4 "nonimmediate_operand" "")))
17878    (clobber (reg:CC FLAGS_REG))]
17879   "SSE_REG_P (operands[0]) && reload_completed
17880    && ((operands_match_p (operands[1], operands[3])
17881         && operands_match_p (operands[2], operands[4]))
17882        || (operands_match_p (operands[1], operands[4])
17883            && operands_match_p (operands[2], operands[3])))"
17884   [(set (match_dup 0)
17885         (if_then_else:SF (gt (match_dup 1)
17886                              (match_dup 2))
17887                          (match_dup 1)
17888                          (match_dup 2)))])
17889
17890 (define_split
17891   [(set (match_operand:SF 0 "fp_register_operand" "")
17892         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17893                              (match_operand:SF 2 "register_operand" ""))
17894                          (match_operand:SF 3 "register_operand" "")
17895                          (match_operand:SF 4 "register_operand" "")))
17896    (clobber (reg:CC FLAGS_REG))]
17897   "reload_completed
17898    && ((operands_match_p (operands[1], operands[3])
17899         && operands_match_p (operands[2], operands[4]))
17900        || (operands_match_p (operands[1], operands[4])
17901            && operands_match_p (operands[2], operands[3])))"
17902   [(set (reg:CCFP FLAGS_REG)
17903         (compare:CCFP (match_dup 1)
17904                       (match_dup 2)))
17905    (set (match_dup 0)
17906         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17907                          (match_dup 1)
17908                          (match_dup 2)))])
17909
17910 (define_insn "*maxsf_sse"
17911   [(set (match_operand:SF 0 "register_operand" "=x")
17912         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17913                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17914                          (match_dup 1)
17915                          (match_dup 2)))]
17916   "TARGET_SSE && reload_completed"
17917   "maxss\t{%2, %0|%0, %2}"
17918   [(set_attr "type" "sse")
17919    (set_attr "mode" "SF")])
17920
17921 (define_expand "maxdf3"
17922   [(parallel [
17923      (set (match_operand:DF 0 "register_operand" "")
17924           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17925                                (match_operand:DF 2 "nonimmediate_operand" ""))
17926                            (match_dup 1)
17927                            (match_dup 2)))
17928      (clobber (reg:CC FLAGS_REG))])]
17929   "TARGET_SSE2 && TARGET_SSE_MATH"
17930   "#")
17931
17932 (define_insn "*maxdf"
17933   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17934         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17935                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17936                          (match_dup 1)
17937                          (match_dup 2)))
17938    (clobber (reg:CC FLAGS_REG))]
17939   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17940   "#")
17941
17942 (define_insn "*maxdf_nonieee"
17943   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17944         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17945                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17946                          (match_dup 1)
17947                          (match_dup 2)))
17948    (clobber (reg:CC FLAGS_REG))]
17949   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17950    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17951   "#")
17952
17953 (define_split
17954   [(set (match_operand:DF 0 "register_operand" "")
17955         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17956                              (match_operand:DF 2 "nonimmediate_operand" ""))
17957                          (match_operand:DF 3 "register_operand" "")
17958                          (match_operand:DF 4 "nonimmediate_operand" "")))
17959    (clobber (reg:CC FLAGS_REG))]
17960   "SSE_REG_P (operands[0]) && reload_completed
17961    && ((operands_match_p (operands[1], operands[3])
17962         && operands_match_p (operands[2], operands[4]))
17963        || (operands_match_p (operands[1], operands[4])
17964            && operands_match_p (operands[2], operands[3])))"
17965   [(set (match_dup 0)
17966         (if_then_else:DF (gt (match_dup 1)
17967                              (match_dup 2))
17968                          (match_dup 1)
17969                          (match_dup 2)))])
17970
17971 (define_split
17972   [(set (match_operand:DF 0 "fp_register_operand" "")
17973         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17974                              (match_operand:DF 2 "register_operand" ""))
17975                          (match_operand:DF 3 "register_operand" "")
17976                          (match_operand:DF 4 "register_operand" "")))
17977    (clobber (reg:CC FLAGS_REG))]
17978   "reload_completed
17979    && ((operands_match_p (operands[1], operands[3])
17980         && operands_match_p (operands[2], operands[4]))
17981        || (operands_match_p (operands[1], operands[4])
17982            && operands_match_p (operands[2], operands[3])))"
17983   [(set (reg:CCFP FLAGS_REG)
17984         (compare:CCFP (match_dup 1)
17985                       (match_dup 2)))
17986    (set (match_dup 0)
17987         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17988                          (match_dup 1)
17989                          (match_dup 2)))])
17990
17991 (define_insn "*maxdf_sse"
17992   [(set (match_operand:DF 0 "register_operand" "=Y")
17993         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17994                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17995                          (match_dup 1)
17996                          (match_dup 2)))]
17997   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17998   "maxsd\t{%2, %0|%0, %2}"
17999   [(set_attr "type" "sse")
18000    (set_attr "mode" "DF")])
18001 \f
18002 ;; Misc patterns (?)
18003
18004 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18005 ;; Otherwise there will be nothing to keep
18006 ;; 
18007 ;; [(set (reg ebp) (reg esp))]
18008 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18009 ;;  (clobber (eflags)]
18010 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18011 ;;
18012 ;; in proper program order.
18013 (define_insn "pro_epilogue_adjust_stack_1"
18014   [(set (match_operand:SI 0 "register_operand" "=r,r")
18015         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18016                  (match_operand:SI 2 "immediate_operand" "i,i")))
18017    (clobber (reg:CC FLAGS_REG))
18018    (clobber (mem:BLK (scratch)))]
18019   "!TARGET_64BIT"
18020 {
18021   switch (get_attr_type (insn))
18022     {
18023     case TYPE_IMOV:
18024       return "mov{l}\t{%1, %0|%0, %1}";
18025
18026     case TYPE_ALU:
18027       if (GET_CODE (operands[2]) == CONST_INT
18028           && (INTVAL (operands[2]) == 128
18029               || (INTVAL (operands[2]) < 0
18030                   && INTVAL (operands[2]) != -128)))
18031         {
18032           operands[2] = GEN_INT (-INTVAL (operands[2]));
18033           return "sub{l}\t{%2, %0|%0, %2}";
18034         }
18035       return "add{l}\t{%2, %0|%0, %2}";
18036
18037     case TYPE_LEA:
18038       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18039       return "lea{l}\t{%a2, %0|%0, %a2}";
18040
18041     default:
18042       abort ();
18043     }
18044 }
18045   [(set (attr "type")
18046         (cond [(eq_attr "alternative" "0")
18047                  (const_string "alu")
18048                (match_operand:SI 2 "const0_operand" "")
18049                  (const_string "imov")
18050               ]
18051               (const_string "lea")))
18052    (set_attr "mode" "SI")])
18053
18054 (define_insn "pro_epilogue_adjust_stack_rex64"
18055   [(set (match_operand:DI 0 "register_operand" "=r,r")
18056         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18057                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18058    (clobber (reg:CC FLAGS_REG))
18059    (clobber (mem:BLK (scratch)))]
18060   "TARGET_64BIT"
18061 {
18062   switch (get_attr_type (insn))
18063     {
18064     case TYPE_IMOV:
18065       return "mov{q}\t{%1, %0|%0, %1}";
18066
18067     case TYPE_ALU:
18068       if (GET_CODE (operands[2]) == CONST_INT
18069           /* Avoid overflows.  */
18070           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18071           && (INTVAL (operands[2]) == 128
18072               || (INTVAL (operands[2]) < 0
18073                   && INTVAL (operands[2]) != -128)))
18074         {
18075           operands[2] = GEN_INT (-INTVAL (operands[2]));
18076           return "sub{q}\t{%2, %0|%0, %2}";
18077         }
18078       return "add{q}\t{%2, %0|%0, %2}";
18079
18080     case TYPE_LEA:
18081       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18082       return "lea{q}\t{%a2, %0|%0, %a2}";
18083
18084     default:
18085       abort ();
18086     }
18087 }
18088   [(set (attr "type")
18089         (cond [(eq_attr "alternative" "0")
18090                  (const_string "alu")
18091                (match_operand:DI 2 "const0_operand" "")
18092                  (const_string "imov")
18093               ]
18094               (const_string "lea")))
18095    (set_attr "mode" "DI")])
18096
18097 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18098   [(set (match_operand:DI 0 "register_operand" "=r,r")
18099         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18100                  (match_operand:DI 3 "immediate_operand" "i,i")))
18101    (use (match_operand:DI 2 "register_operand" "r,r"))
18102    (clobber (reg:CC FLAGS_REG))
18103    (clobber (mem:BLK (scratch)))]
18104   "TARGET_64BIT"
18105 {
18106   switch (get_attr_type (insn))
18107     {
18108     case TYPE_ALU:
18109       return "add{q}\t{%2, %0|%0, %2}";
18110
18111     case TYPE_LEA:
18112       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18113       return "lea{q}\t{%a2, %0|%0, %a2}";
18114
18115     default:
18116       abort ();
18117     }
18118 }
18119   [(set_attr "type" "alu,lea")
18120    (set_attr "mode" "DI")])
18121
18122 ;; Placeholder for the conditional moves.  This one is split either to SSE
18123 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18124 ;; fact is that compares supported by the cmp??ss instructions are exactly
18125 ;; swapped of those supported by cmove sequence.
18126 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18127 ;; supported by i387 comparisons and we do need to emit two conditional moves
18128 ;; in tandem.
18129
18130 (define_insn "sse_movsfcc"
18131   [(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")
18132         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18133                         [(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")
18134                          (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")])
18135                       (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")
18136                       (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")))
18137    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18138    (clobber (reg:CC FLAGS_REG))]
18139   "TARGET_SSE
18140    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18141    /* Avoid combine from being smart and converting min/max
18142       instruction patterns into conditional moves.  */
18143    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18144         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18145        || !rtx_equal_p (operands[4], operands[2])
18146        || !rtx_equal_p (operands[5], operands[3]))
18147    && (!TARGET_IEEE_FP
18148        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18149   "#")
18150
18151 (define_insn "sse_movsfcc_eq"
18152   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18153         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18154                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18155                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18156                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18157    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18158    (clobber (reg:CC FLAGS_REG))]
18159   "TARGET_SSE
18160    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18161   "#")
18162
18163 (define_insn "sse_movdfcc"
18164   [(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")
18165         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18166                         [(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")
18167                          (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")])
18168                       (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")
18169                       (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")))
18170    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18171    (clobber (reg:CC FLAGS_REG))]
18172   "TARGET_SSE2
18173    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18174    /* Avoid combine from being smart and converting min/max
18175       instruction patterns into conditional moves.  */
18176    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18177         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18178        || !rtx_equal_p (operands[4], operands[2])
18179        || !rtx_equal_p (operands[5], operands[3]))
18180    && (!TARGET_IEEE_FP
18181        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18182   "#")
18183
18184 (define_insn "sse_movdfcc_eq"
18185   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18186         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18187                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18188                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18189                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18190    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18191    (clobber (reg:CC FLAGS_REG))]
18192   "TARGET_SSE
18193    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18194   "#")
18195
18196 ;; For non-sse moves just expand the usual cmove sequence.
18197 (define_split
18198   [(set (match_operand 0 "register_operand" "")
18199         (if_then_else (match_operator 1 "comparison_operator"
18200                         [(match_operand 4 "nonimmediate_operand" "")
18201                          (match_operand 5 "register_operand" "")])
18202                       (match_operand 2 "nonimmediate_operand" "")
18203                       (match_operand 3 "nonimmediate_operand" "")))
18204    (clobber (match_operand 6 "" ""))
18205    (clobber (reg:CC FLAGS_REG))]
18206   "!SSE_REG_P (operands[0]) && reload_completed
18207    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18208   [(const_int 0)]
18209 {
18210    ix86_compare_op0 = operands[5];
18211    ix86_compare_op1 = operands[4];
18212    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18213                                  VOIDmode, operands[5], operands[4]);
18214    ix86_expand_fp_movcc (operands);
18215    DONE;
18216 })
18217
18218 ;; Split SSE based conditional move into sequence:
18219 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18220 ;; and   op2, op0   -  zero op2 if comparison was false
18221 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18222 ;; or    op2, op0   -  get the nonzero one into the result.
18223 (define_split
18224   [(set (match_operand:SF 0 "register_operand" "")
18225         (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18226                            [(match_operand:SF 4 "register_operand" "")
18227                             (match_operand:SF 5 "nonimmediate_operand" "")])
18228                          (match_operand:SF 2 "register_operand" "")
18229                          (match_operand:SF 3 "register_operand" "")))
18230    (clobber (match_operand 6 "" ""))
18231    (clobber (reg:CC FLAGS_REG))]
18232   "SSE_REG_P (operands[0]) && reload_completed"
18233   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18234    (set (match_dup 2) (and:V4SF (match_dup 2)
18235                                 (match_dup 8)))
18236    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18237                                           (match_dup 3)))
18238    (set (match_dup 0) (ior:V4SF (match_dup 6)
18239                                 (match_dup 7)))]
18240 {
18241   /* If op2 == op3, op3 would be clobbered before it is used.  */
18242   if (operands_match_p (operands[2], operands[3]))
18243     {
18244       emit_move_insn (operands[0], operands[2]);
18245       DONE;
18246     }
18247
18248   PUT_MODE (operands[1], GET_MODE (operands[0]));
18249   if (operands_match_p (operands[0], operands[4]))
18250     operands[6] = operands[4], operands[7] = operands[2];
18251   else
18252     operands[6] = operands[2], operands[7] = operands[4];
18253   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18254   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18255   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18256   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18257   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18258   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18259 })
18260
18261 (define_split
18262   [(set (match_operand:DF 0 "register_operand" "")
18263         (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18264                            [(match_operand:DF 4 "register_operand" "")
18265                             (match_operand:DF 5 "nonimmediate_operand" "")])
18266                          (match_operand:DF 2 "register_operand" "")
18267                          (match_operand:DF 3 "register_operand" "")))
18268    (clobber (match_operand 6 "" ""))
18269    (clobber (reg:CC FLAGS_REG))]
18270   "SSE_REG_P (operands[0]) && reload_completed"
18271   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18272    (set (match_dup 2) (and:V2DF (match_dup 2)
18273                                 (match_dup 8)))
18274    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18275                                           (match_dup 3)))
18276    (set (match_dup 0) (ior:V2DF (match_dup 6)
18277                                 (match_dup 7)))]
18278 {
18279   if (GET_MODE (operands[2]) == DFmode
18280       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18281     {
18282       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18283       emit_insn (gen_sse2_unpcklpd (op, op, op));
18284       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18285       emit_insn (gen_sse2_unpcklpd (op, op, op));
18286     }
18287
18288   /* If op2 == op3, op3 would be clobbered before it is used.  */
18289   if (operands_match_p (operands[2], operands[3]))
18290     {
18291       emit_move_insn (operands[0], operands[2]);
18292       DONE;
18293     }
18294
18295   PUT_MODE (operands[1], GET_MODE (operands[0]));
18296   if (operands_match_p (operands[0], operands[4]))
18297     operands[6] = operands[4], operands[7] = operands[2];
18298   else
18299     operands[6] = operands[2], operands[7] = operands[4];
18300   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18301   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18302   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18303   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18304   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18305   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18306 })
18307
18308 ;; Special case of conditional move we can handle effectively.
18309 ;; Do not brother with the integer/floating point case, since these are
18310 ;; bot considerably slower, unlike in the generic case.
18311 (define_insn "*sse_movsfcc_const0_1"
18312   [(set (match_operand:SF 0 "register_operand" "=&x")
18313         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18314                         [(match_operand:SF 4 "register_operand" "0")
18315                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18316                       (match_operand:SF 2 "register_operand" "x")
18317                       (match_operand:SF 3 "const0_operand" "X")))]
18318   "TARGET_SSE"
18319   "#")
18320
18321 (define_insn "*sse_movsfcc_const0_2"
18322   [(set (match_operand:SF 0 "register_operand" "=&x")
18323         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18324                         [(match_operand:SF 4 "register_operand" "0")
18325                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18326                       (match_operand:SF 2 "const0_operand" "X")
18327                       (match_operand:SF 3 "register_operand" "x")))]
18328   "TARGET_SSE"
18329   "#")
18330
18331 (define_insn "*sse_movsfcc_const0_3"
18332   [(set (match_operand:SF 0 "register_operand" "=&x")
18333         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18334                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18335                          (match_operand:SF 5 "register_operand" "0")])
18336                       (match_operand:SF 2 "register_operand" "x")
18337                       (match_operand:SF 3 "const0_operand" "X")))]
18338   "TARGET_SSE"
18339   "#")
18340
18341 (define_insn "*sse_movsfcc_const0_4"
18342   [(set (match_operand:SF 0 "register_operand" "=&x")
18343         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18344                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18345                          (match_operand:SF 5 "register_operand" "0")])
18346                       (match_operand:SF 2 "const0_operand" "X")
18347                       (match_operand:SF 3 "register_operand" "x")))]
18348   "TARGET_SSE"
18349   "#")
18350
18351 (define_insn "*sse_movdfcc_const0_1"
18352   [(set (match_operand:DF 0 "register_operand" "=&Y")
18353         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18354                         [(match_operand:DF 4 "register_operand" "0")
18355                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18356                       (match_operand:DF 2 "register_operand" "Y")
18357                       (match_operand:DF 3 "const0_operand" "X")))]
18358   "TARGET_SSE2"
18359   "#")
18360
18361 (define_insn "*sse_movdfcc_const0_2"
18362   [(set (match_operand:DF 0 "register_operand" "=&Y")
18363         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18364                         [(match_operand:DF 4 "register_operand" "0")
18365                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18366                       (match_operand:DF 2 "const0_operand" "X")
18367                       (match_operand:DF 3 "register_operand" "Y")))]
18368   "TARGET_SSE2"
18369   "#")
18370
18371 (define_insn "*sse_movdfcc_const0_3"
18372   [(set (match_operand:DF 0 "register_operand" "=&Y")
18373         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18374                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18375                          (match_operand:DF 5 "register_operand" "0")])
18376                       (match_operand:DF 2 "register_operand" "Y")
18377                       (match_operand:DF 3 "const0_operand" "X")))]
18378   "TARGET_SSE2"
18379   "#")
18380
18381 (define_insn "*sse_movdfcc_const0_4"
18382   [(set (match_operand:DF 0 "register_operand" "=&Y")
18383         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18384                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18385                          (match_operand:DF 5 "register_operand" "0")])
18386                       (match_operand:DF 2 "const0_operand" "X")
18387                       (match_operand:DF 3 "register_operand" "Y")))]
18388   "TARGET_SSE2"
18389   "#")
18390
18391 (define_split
18392   [(set (match_operand:SF 0 "register_operand" "")
18393         (if_then_else:SF (match_operator 1 "comparison_operator"
18394                            [(match_operand:SF 4 "nonimmediate_operand" "")
18395                             (match_operand:SF 5 "nonimmediate_operand" "")])
18396                          (match_operand:SF 2 "nonmemory_operand" "")
18397                          (match_operand:SF 3 "nonmemory_operand" "")))]
18398   "SSE_REG_P (operands[0]) && reload_completed
18399    && (const0_operand (operands[2], GET_MODE (operands[0]))
18400        || const0_operand (operands[3], GET_MODE (operands[0])))"
18401   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18402    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18403 {
18404   PUT_MODE (operands[1], GET_MODE (operands[0]));
18405   if (!sse_comparison_operator (operands[1], VOIDmode)
18406       || !rtx_equal_p (operands[0], operands[4]))
18407     {
18408       rtx tmp = operands[5];
18409       operands[5] = operands[4];
18410       operands[4] = tmp;
18411       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18412     }
18413   if (!rtx_equal_p (operands[0], operands[4]))
18414     abort ();
18415   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18416   if (const0_operand (operands[2], GET_MODE (operands[2])))
18417     {
18418       operands[7] = operands[3];
18419       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18420     }
18421   else
18422     {
18423       operands[7] = operands[2];
18424       operands[6] = operands[8];
18425     }
18426   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18427 })
18428
18429 (define_split
18430   [(set (match_operand:DF 0 "register_operand" "")
18431         (if_then_else:DF (match_operator 1 "comparison_operator"
18432                            [(match_operand:DF 4 "nonimmediate_operand" "")
18433                             (match_operand:DF 5 "nonimmediate_operand" "")])
18434                          (match_operand:DF 2 "nonmemory_operand" "")
18435                          (match_operand:DF 3 "nonmemory_operand" "")))]
18436   "SSE_REG_P (operands[0]) && reload_completed
18437    && (const0_operand (operands[2], GET_MODE (operands[0]))
18438        || const0_operand (operands[3], GET_MODE (operands[0])))"
18439   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18440    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18441 {
18442   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18443       && GET_MODE (operands[2]) == DFmode)
18444     {
18445       if (REG_P (operands[2]))
18446         {
18447           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18448           emit_insn (gen_sse2_unpcklpd (op, op, op));
18449         }
18450       if (REG_P (operands[3]))
18451         {
18452           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18453           emit_insn (gen_sse2_unpcklpd (op, op, op));
18454         }
18455     }
18456   PUT_MODE (operands[1], GET_MODE (operands[0]));
18457   if (!sse_comparison_operator (operands[1], VOIDmode)
18458       || !rtx_equal_p (operands[0], operands[4]))
18459     {
18460       rtx tmp = operands[5];
18461       operands[5] = operands[4];
18462       operands[4] = tmp;
18463       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18464     }
18465   if (!rtx_equal_p (operands[0], operands[4]))
18466     abort ();
18467   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18468   if (const0_operand (operands[2], GET_MODE (operands[2])))
18469     {
18470       operands[7] = operands[3];
18471       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18472     }
18473   else
18474     {
18475       operands[7] = operands[2];
18476       operands[6] = operands[8];
18477     }
18478   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18479 })
18480
18481 (define_expand "allocate_stack_worker"
18482   [(match_operand:SI 0 "register_operand" "")]
18483   "TARGET_STACK_PROBE"
18484 {
18485   if (reload_completed)
18486     {
18487       if (TARGET_64BIT)
18488         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18489       else
18490         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18491     }
18492   else
18493     {
18494       if (TARGET_64BIT)
18495         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18496       else
18497         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18498     }
18499   DONE;
18500 })
18501
18502 (define_insn "allocate_stack_worker_1"
18503   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18504     UNSPECV_STACK_PROBE)
18505    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18506    (clobber (match_scratch:SI 1 "=0"))
18507    (clobber (reg:CC FLAGS_REG))]
18508   "!TARGET_64BIT && TARGET_STACK_PROBE"
18509   "call\t__alloca"
18510   [(set_attr "type" "multi")
18511    (set_attr "length" "5")])
18512
18513 (define_expand "allocate_stack_worker_postreload"
18514   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18515                                     UNSPECV_STACK_PROBE)
18516               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18517               (clobber (match_dup 0))
18518               (clobber (reg:CC FLAGS_REG))])]
18519   ""
18520   "")
18521
18522 (define_insn "allocate_stack_worker_rex64"
18523   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18524     UNSPECV_STACK_PROBE)
18525    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18526    (clobber (match_scratch:DI 1 "=0"))
18527    (clobber (reg:CC FLAGS_REG))]
18528   "TARGET_64BIT && TARGET_STACK_PROBE"
18529   "call\t__alloca"
18530   [(set_attr "type" "multi")
18531    (set_attr "length" "5")])
18532
18533 (define_expand "allocate_stack_worker_rex64_postreload"
18534   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18535                                     UNSPECV_STACK_PROBE)
18536               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18537               (clobber (match_dup 0))
18538               (clobber (reg:CC FLAGS_REG))])]
18539   ""
18540   "")
18541
18542 (define_expand "allocate_stack"
18543   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18544                    (minus:SI (reg:SI SP_REG)
18545                              (match_operand:SI 1 "general_operand" "")))
18546               (clobber (reg:CC FLAGS_REG))])
18547    (parallel [(set (reg:SI SP_REG)
18548                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18549               (clobber (reg:CC FLAGS_REG))])]
18550   "TARGET_STACK_PROBE"
18551 {
18552 #ifdef CHECK_STACK_LIMIT
18553   if (GET_CODE (operands[1]) == CONST_INT
18554       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18555     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18556                            operands[1]));
18557   else 
18558 #endif
18559     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18560                                                             operands[1])));
18561
18562   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18563   DONE;
18564 })
18565
18566 (define_expand "builtin_setjmp_receiver"
18567   [(label_ref (match_operand 0 "" ""))]
18568   "!TARGET_64BIT && flag_pic"
18569 {
18570   emit_insn (gen_set_got (pic_offset_table_rtx));
18571   DONE;
18572 })
18573 \f
18574 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18575
18576 (define_split
18577   [(set (match_operand 0 "register_operand" "")
18578         (match_operator 3 "promotable_binary_operator"
18579            [(match_operand 1 "register_operand" "")
18580             (match_operand 2 "aligned_operand" "")]))
18581    (clobber (reg:CC FLAGS_REG))]
18582   "! TARGET_PARTIAL_REG_STALL && reload_completed
18583    && ((GET_MODE (operands[0]) == HImode 
18584         && ((!optimize_size && !TARGET_FAST_PREFIX)
18585             || GET_CODE (operands[2]) != CONST_INT
18586             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18587        || (GET_MODE (operands[0]) == QImode 
18588            && (TARGET_PROMOTE_QImode || optimize_size)))"
18589   [(parallel [(set (match_dup 0)
18590                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18591               (clobber (reg:CC FLAGS_REG))])]
18592   "operands[0] = gen_lowpart (SImode, operands[0]);
18593    operands[1] = gen_lowpart (SImode, operands[1]);
18594    if (GET_CODE (operands[3]) != ASHIFT)
18595      operands[2] = gen_lowpart (SImode, operands[2]);
18596    PUT_MODE (operands[3], SImode);")
18597
18598 ; Promote the QImode tests, as i386 has encoding of the AND
18599 ; instruction with 32-bit sign-extended immediate and thus the
18600 ; instruction size is unchanged, except in the %eax case for
18601 ; which it is increased by one byte, hence the ! optimize_size.
18602 (define_split
18603   [(set (match_operand 0 "flags_reg_operand" "")
18604         (match_operator 2 "compare_operator"
18605           [(and (match_operand 3 "aligned_operand" "")
18606                 (match_operand 4 "const_int_operand" ""))
18607            (const_int 0)]))
18608    (set (match_operand 1 "register_operand" "")
18609         (and (match_dup 3) (match_dup 4)))]
18610   "! TARGET_PARTIAL_REG_STALL && reload_completed
18611    /* Ensure that the operand will remain sign-extended immediate.  */
18612    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18613    && ! optimize_size
18614    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18615        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18616   [(parallel [(set (match_dup 0)
18617                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18618                                     (const_int 0)]))
18619               (set (match_dup 1)
18620                    (and:SI (match_dup 3) (match_dup 4)))])]
18621 {
18622   operands[4]
18623     = gen_int_mode (INTVAL (operands[4])
18624                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18625   operands[1] = gen_lowpart (SImode, operands[1]);
18626   operands[3] = gen_lowpart (SImode, operands[3]);
18627 })
18628
18629 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18630 ; the TEST instruction with 32-bit sign-extended immediate and thus
18631 ; the instruction size would at least double, which is not what we
18632 ; want even with ! optimize_size.
18633 (define_split
18634   [(set (match_operand 0 "flags_reg_operand" "")
18635         (match_operator 1 "compare_operator"
18636           [(and (match_operand:HI 2 "aligned_operand" "")
18637                 (match_operand:HI 3 "const_int_operand" ""))
18638            (const_int 0)]))]
18639   "! TARGET_PARTIAL_REG_STALL && reload_completed
18640    /* Ensure that the operand will remain sign-extended immediate.  */
18641    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18642    && ! TARGET_FAST_PREFIX
18643    && ! optimize_size"
18644   [(set (match_dup 0)
18645         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18646                          (const_int 0)]))]
18647 {
18648   operands[3]
18649     = gen_int_mode (INTVAL (operands[3])
18650                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18651   operands[2] = gen_lowpart (SImode, operands[2]);
18652 })
18653
18654 (define_split
18655   [(set (match_operand 0 "register_operand" "")
18656         (neg (match_operand 1 "register_operand" "")))
18657    (clobber (reg:CC FLAGS_REG))]
18658   "! TARGET_PARTIAL_REG_STALL && reload_completed
18659    && (GET_MODE (operands[0]) == HImode
18660        || (GET_MODE (operands[0]) == QImode 
18661            && (TARGET_PROMOTE_QImode || optimize_size)))"
18662   [(parallel [(set (match_dup 0)
18663                    (neg:SI (match_dup 1)))
18664               (clobber (reg:CC FLAGS_REG))])]
18665   "operands[0] = gen_lowpart (SImode, operands[0]);
18666    operands[1] = gen_lowpart (SImode, operands[1]);")
18667
18668 (define_split
18669   [(set (match_operand 0 "register_operand" "")
18670         (not (match_operand 1 "register_operand" "")))]
18671   "! TARGET_PARTIAL_REG_STALL && reload_completed
18672    && (GET_MODE (operands[0]) == HImode
18673        || (GET_MODE (operands[0]) == QImode 
18674            && (TARGET_PROMOTE_QImode || optimize_size)))"
18675   [(set (match_dup 0)
18676         (not:SI (match_dup 1)))]
18677   "operands[0] = gen_lowpart (SImode, operands[0]);
18678    operands[1] = gen_lowpart (SImode, operands[1]);")
18679
18680 (define_split 
18681   [(set (match_operand 0 "register_operand" "")
18682         (if_then_else (match_operator 1 "comparison_operator" 
18683                                 [(reg FLAGS_REG) (const_int 0)])
18684                       (match_operand 2 "register_operand" "")
18685                       (match_operand 3 "register_operand" "")))]
18686   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18687    && (GET_MODE (operands[0]) == HImode
18688        || (GET_MODE (operands[0]) == QImode 
18689            && (TARGET_PROMOTE_QImode || optimize_size)))"
18690   [(set (match_dup 0)
18691         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18692   "operands[0] = gen_lowpart (SImode, operands[0]);
18693    operands[2] = gen_lowpart (SImode, operands[2]);
18694    operands[3] = gen_lowpart (SImode, operands[3]);")
18695                         
18696 \f
18697 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18698 ;; transform a complex memory operation into two memory to register operations.
18699
18700 ;; Don't push memory operands
18701 (define_peephole2
18702   [(set (match_operand:SI 0 "push_operand" "")
18703         (match_operand:SI 1 "memory_operand" ""))
18704    (match_scratch:SI 2 "r")]
18705   "! optimize_size && ! TARGET_PUSH_MEMORY"
18706   [(set (match_dup 2) (match_dup 1))
18707    (set (match_dup 0) (match_dup 2))]
18708   "")
18709
18710 (define_peephole2
18711   [(set (match_operand:DI 0 "push_operand" "")
18712         (match_operand:DI 1 "memory_operand" ""))
18713    (match_scratch:DI 2 "r")]
18714   "! optimize_size && ! TARGET_PUSH_MEMORY"
18715   [(set (match_dup 2) (match_dup 1))
18716    (set (match_dup 0) (match_dup 2))]
18717   "")
18718
18719 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18720 ;; SImode pushes.
18721 (define_peephole2
18722   [(set (match_operand:SF 0 "push_operand" "")
18723         (match_operand:SF 1 "memory_operand" ""))
18724    (match_scratch:SF 2 "r")]
18725   "! optimize_size && ! TARGET_PUSH_MEMORY"
18726   [(set (match_dup 2) (match_dup 1))
18727    (set (match_dup 0) (match_dup 2))]
18728   "")
18729
18730 (define_peephole2
18731   [(set (match_operand:HI 0 "push_operand" "")
18732         (match_operand:HI 1 "memory_operand" ""))
18733    (match_scratch:HI 2 "r")]
18734   "! optimize_size && ! TARGET_PUSH_MEMORY"
18735   [(set (match_dup 2) (match_dup 1))
18736    (set (match_dup 0) (match_dup 2))]
18737   "")
18738
18739 (define_peephole2
18740   [(set (match_operand:QI 0 "push_operand" "")
18741         (match_operand:QI 1 "memory_operand" ""))
18742    (match_scratch:QI 2 "q")]
18743   "! optimize_size && ! TARGET_PUSH_MEMORY"
18744   [(set (match_dup 2) (match_dup 1))
18745    (set (match_dup 0) (match_dup 2))]
18746   "")
18747
18748 ;; Don't move an immediate directly to memory when the instruction
18749 ;; gets too big.
18750 (define_peephole2
18751   [(match_scratch:SI 1 "r")
18752    (set (match_operand:SI 0 "memory_operand" "")
18753         (const_int 0))]
18754   "! optimize_size
18755    && ! TARGET_USE_MOV0
18756    && TARGET_SPLIT_LONG_MOVES
18757    && get_attr_length (insn) >= ix86_cost->large_insn
18758    && peep2_regno_dead_p (0, FLAGS_REG)"
18759   [(parallel [(set (match_dup 1) (const_int 0))
18760               (clobber (reg:CC FLAGS_REG))])
18761    (set (match_dup 0) (match_dup 1))]
18762   "")
18763
18764 (define_peephole2
18765   [(match_scratch:HI 1 "r")
18766    (set (match_operand:HI 0 "memory_operand" "")
18767         (const_int 0))]
18768   "! optimize_size
18769    && ! TARGET_USE_MOV0
18770    && TARGET_SPLIT_LONG_MOVES
18771    && get_attr_length (insn) >= ix86_cost->large_insn
18772    && peep2_regno_dead_p (0, FLAGS_REG)"
18773   [(parallel [(set (match_dup 2) (const_int 0))
18774               (clobber (reg:CC FLAGS_REG))])
18775    (set (match_dup 0) (match_dup 1))]
18776   "operands[2] = gen_lowpart (SImode, operands[1]);")
18777
18778 (define_peephole2
18779   [(match_scratch:QI 1 "q")
18780    (set (match_operand:QI 0 "memory_operand" "")
18781         (const_int 0))]
18782   "! optimize_size
18783    && ! TARGET_USE_MOV0
18784    && TARGET_SPLIT_LONG_MOVES
18785    && get_attr_length (insn) >= ix86_cost->large_insn
18786    && peep2_regno_dead_p (0, FLAGS_REG)"
18787   [(parallel [(set (match_dup 2) (const_int 0))
18788               (clobber (reg:CC FLAGS_REG))])
18789    (set (match_dup 0) (match_dup 1))]
18790   "operands[2] = gen_lowpart (SImode, operands[1]);")
18791
18792 (define_peephole2
18793   [(match_scratch:SI 2 "r")
18794    (set (match_operand:SI 0 "memory_operand" "")
18795         (match_operand:SI 1 "immediate_operand" ""))]
18796   "! optimize_size
18797    && get_attr_length (insn) >= ix86_cost->large_insn
18798    && TARGET_SPLIT_LONG_MOVES"
18799   [(set (match_dup 2) (match_dup 1))
18800    (set (match_dup 0) (match_dup 2))]
18801   "")
18802
18803 (define_peephole2
18804   [(match_scratch:HI 2 "r")
18805    (set (match_operand:HI 0 "memory_operand" "")
18806         (match_operand:HI 1 "immediate_operand" ""))]
18807   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18808   && TARGET_SPLIT_LONG_MOVES"
18809   [(set (match_dup 2) (match_dup 1))
18810    (set (match_dup 0) (match_dup 2))]
18811   "")
18812
18813 (define_peephole2
18814   [(match_scratch:QI 2 "q")
18815    (set (match_operand:QI 0 "memory_operand" "")
18816         (match_operand:QI 1 "immediate_operand" ""))]
18817   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18818   && TARGET_SPLIT_LONG_MOVES"
18819   [(set (match_dup 2) (match_dup 1))
18820    (set (match_dup 0) (match_dup 2))]
18821   "")
18822
18823 ;; Don't compare memory with zero, load and use a test instead.
18824 (define_peephole2
18825   [(set (match_operand 0 "flags_reg_operand" "")
18826         (match_operator 1 "compare_operator"
18827           [(match_operand:SI 2 "memory_operand" "")
18828            (const_int 0)]))
18829    (match_scratch:SI 3 "r")]
18830   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18831   [(set (match_dup 3) (match_dup 2))
18832    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18833   "")
18834
18835 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18836 ;; Don't split NOTs with a displacement operand, because resulting XOR
18837 ;; will not be pairable anyway.
18838 ;;
18839 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18840 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18841 ;; so this split helps here as well.
18842 ;;
18843 ;; Note: Can't do this as a regular split because we can't get proper
18844 ;; lifetime information then.
18845
18846 (define_peephole2
18847   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18848         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18849   "!optimize_size
18850    && peep2_regno_dead_p (0, FLAGS_REG)
18851    && ((TARGET_PENTIUM 
18852         && (GET_CODE (operands[0]) != MEM
18853             || !memory_displacement_operand (operands[0], SImode)))
18854        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18855   [(parallel [(set (match_dup 0)
18856                    (xor:SI (match_dup 1) (const_int -1)))
18857               (clobber (reg:CC FLAGS_REG))])]
18858   "")
18859
18860 (define_peephole2
18861   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18862         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18863   "!optimize_size
18864    && peep2_regno_dead_p (0, FLAGS_REG)
18865    && ((TARGET_PENTIUM 
18866         && (GET_CODE (operands[0]) != MEM
18867             || !memory_displacement_operand (operands[0], HImode)))
18868        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18869   [(parallel [(set (match_dup 0)
18870                    (xor:HI (match_dup 1) (const_int -1)))
18871               (clobber (reg:CC FLAGS_REG))])]
18872   "")
18873
18874 (define_peephole2
18875   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18876         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18877   "!optimize_size
18878    && peep2_regno_dead_p (0, FLAGS_REG)
18879    && ((TARGET_PENTIUM 
18880         && (GET_CODE (operands[0]) != MEM
18881             || !memory_displacement_operand (operands[0], QImode)))
18882        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18883   [(parallel [(set (match_dup 0)
18884                    (xor:QI (match_dup 1) (const_int -1)))
18885               (clobber (reg:CC FLAGS_REG))])]
18886   "")
18887
18888 ;; Non pairable "test imm, reg" instructions can be translated to
18889 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18890 ;; byte opcode instead of two, have a short form for byte operands),
18891 ;; so do it for other CPUs as well.  Given that the value was dead,
18892 ;; this should not create any new dependencies.  Pass on the sub-word
18893 ;; versions if we're concerned about partial register stalls.
18894
18895 (define_peephole2
18896   [(set (match_operand 0 "flags_reg_operand" "")
18897         (match_operator 1 "compare_operator"
18898           [(and:SI (match_operand:SI 2 "register_operand" "")
18899                    (match_operand:SI 3 "immediate_operand" ""))
18900            (const_int 0)]))]
18901   "ix86_match_ccmode (insn, CCNOmode)
18902    && (true_regnum (operands[2]) != 0
18903        || (GET_CODE (operands[3]) == CONST_INT
18904            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18905    && peep2_reg_dead_p (1, operands[2])"
18906   [(parallel
18907      [(set (match_dup 0)
18908            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18909                             (const_int 0)]))
18910       (set (match_dup 2)
18911            (and:SI (match_dup 2) (match_dup 3)))])]
18912   "")
18913
18914 ;; We don't need to handle HImode case, because it will be promoted to SImode
18915 ;; on ! TARGET_PARTIAL_REG_STALL
18916
18917 (define_peephole2
18918   [(set (match_operand 0 "flags_reg_operand" "")
18919         (match_operator 1 "compare_operator"
18920           [(and:QI (match_operand:QI 2 "register_operand" "")
18921                    (match_operand:QI 3 "immediate_operand" ""))
18922            (const_int 0)]))]
18923   "! TARGET_PARTIAL_REG_STALL
18924    && ix86_match_ccmode (insn, CCNOmode)
18925    && true_regnum (operands[2]) != 0
18926    && peep2_reg_dead_p (1, operands[2])"
18927   [(parallel
18928      [(set (match_dup 0)
18929            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18930                             (const_int 0)]))
18931       (set (match_dup 2)
18932            (and:QI (match_dup 2) (match_dup 3)))])]
18933   "")
18934
18935 (define_peephole2
18936   [(set (match_operand 0 "flags_reg_operand" "")
18937         (match_operator 1 "compare_operator"
18938           [(and:SI
18939              (zero_extract:SI
18940                (match_operand 2 "ext_register_operand" "")
18941                (const_int 8)
18942                (const_int 8))
18943              (match_operand 3 "const_int_operand" ""))
18944            (const_int 0)]))]
18945   "! TARGET_PARTIAL_REG_STALL
18946    && ix86_match_ccmode (insn, CCNOmode)
18947    && true_regnum (operands[2]) != 0
18948    && peep2_reg_dead_p (1, operands[2])"
18949   [(parallel [(set (match_dup 0)
18950                    (match_op_dup 1
18951                      [(and:SI
18952                         (zero_extract:SI
18953                           (match_dup 2)
18954                           (const_int 8)
18955                           (const_int 8))
18956                         (match_dup 3))
18957                       (const_int 0)]))
18958               (set (zero_extract:SI (match_dup 2)
18959                                     (const_int 8)
18960                                     (const_int 8))
18961                    (and:SI 
18962                      (zero_extract:SI
18963                        (match_dup 2)
18964                        (const_int 8)
18965                        (const_int 8))
18966                      (match_dup 3)))])]
18967   "")
18968
18969 ;; Don't do logical operations with memory inputs.
18970 (define_peephole2
18971   [(match_scratch:SI 2 "r")
18972    (parallel [(set (match_operand:SI 0 "register_operand" "")
18973                    (match_operator:SI 3 "arith_or_logical_operator"
18974                      [(match_dup 0)
18975                       (match_operand:SI 1 "memory_operand" "")]))
18976               (clobber (reg:CC FLAGS_REG))])]
18977   "! optimize_size && ! TARGET_READ_MODIFY"
18978   [(set (match_dup 2) (match_dup 1))
18979    (parallel [(set (match_dup 0)
18980                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18981               (clobber (reg:CC FLAGS_REG))])]
18982   "")
18983
18984 (define_peephole2
18985   [(match_scratch:SI 2 "r")
18986    (parallel [(set (match_operand:SI 0 "register_operand" "")
18987                    (match_operator:SI 3 "arith_or_logical_operator"
18988                      [(match_operand:SI 1 "memory_operand" "")
18989                       (match_dup 0)]))
18990               (clobber (reg:CC FLAGS_REG))])]
18991   "! optimize_size && ! TARGET_READ_MODIFY"
18992   [(set (match_dup 2) (match_dup 1))
18993    (parallel [(set (match_dup 0)
18994                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18995               (clobber (reg:CC FLAGS_REG))])]
18996   "")
18997
18998 ; Don't do logical operations with memory outputs
18999 ;
19000 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19001 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19002 ; the same decoder scheduling characteristics as the original.
19003
19004 (define_peephole2
19005   [(match_scratch:SI 2 "r")
19006    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19007                    (match_operator:SI 3 "arith_or_logical_operator"
19008                      [(match_dup 0)
19009                       (match_operand:SI 1 "nonmemory_operand" "")]))
19010               (clobber (reg:CC FLAGS_REG))])]
19011   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19012   [(set (match_dup 2) (match_dup 0))
19013    (parallel [(set (match_dup 2)
19014                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19015               (clobber (reg:CC FLAGS_REG))])
19016    (set (match_dup 0) (match_dup 2))]
19017   "")
19018
19019 (define_peephole2
19020   [(match_scratch:SI 2 "r")
19021    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19022                    (match_operator:SI 3 "arith_or_logical_operator"
19023                      [(match_operand:SI 1 "nonmemory_operand" "")
19024                       (match_dup 0)]))
19025               (clobber (reg:CC FLAGS_REG))])]
19026   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19027   [(set (match_dup 2) (match_dup 0))
19028    (parallel [(set (match_dup 2)
19029                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19030               (clobber (reg:CC FLAGS_REG))])
19031    (set (match_dup 0) (match_dup 2))]
19032   "")
19033
19034 ;; Attempt to always use XOR for zeroing registers.
19035 (define_peephole2
19036   [(set (match_operand 0 "register_operand" "")
19037         (const_int 0))]
19038   "(GET_MODE (operands[0]) == QImode
19039     || GET_MODE (operands[0]) == HImode
19040     || GET_MODE (operands[0]) == SImode
19041     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19042    && (! TARGET_USE_MOV0 || optimize_size)
19043    && peep2_regno_dead_p (0, FLAGS_REG)"
19044   [(parallel [(set (match_dup 0) (const_int 0))
19045               (clobber (reg:CC FLAGS_REG))])]
19046   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19047                               operands[0]);")
19048
19049 (define_peephole2
19050   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19051         (const_int 0))]
19052   "(GET_MODE (operands[0]) == QImode
19053     || GET_MODE (operands[0]) == HImode)
19054    && (! TARGET_USE_MOV0 || optimize_size)
19055    && peep2_regno_dead_p (0, FLAGS_REG)"
19056   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19057               (clobber (reg:CC FLAGS_REG))])])
19058
19059 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19060 (define_peephole2
19061   [(set (match_operand 0 "register_operand" "")
19062         (const_int -1))]
19063   "(GET_MODE (operands[0]) == HImode
19064     || GET_MODE (operands[0]) == SImode 
19065     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19066    && (optimize_size || TARGET_PENTIUM)
19067    && peep2_regno_dead_p (0, FLAGS_REG)"
19068   [(parallel [(set (match_dup 0) (const_int -1))
19069               (clobber (reg:CC FLAGS_REG))])]
19070   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19071                               operands[0]);")
19072
19073 ;; Attempt to convert simple leas to adds. These can be created by
19074 ;; move expanders.
19075 (define_peephole2
19076   [(set (match_operand:SI 0 "register_operand" "")
19077         (plus:SI (match_dup 0)
19078                  (match_operand:SI 1 "nonmemory_operand" "")))]
19079   "peep2_regno_dead_p (0, FLAGS_REG)"
19080   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19081               (clobber (reg:CC FLAGS_REG))])]
19082   "")
19083
19084 (define_peephole2
19085   [(set (match_operand:SI 0 "register_operand" "")
19086         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19087                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19088   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19089   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19090               (clobber (reg:CC FLAGS_REG))])]
19091   "operands[2] = gen_lowpart (SImode, operands[2]);")
19092
19093 (define_peephole2
19094   [(set (match_operand:DI 0 "register_operand" "")
19095         (plus:DI (match_dup 0)
19096                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19097   "peep2_regno_dead_p (0, FLAGS_REG)"
19098   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19099               (clobber (reg:CC FLAGS_REG))])]
19100   "")
19101
19102 (define_peephole2
19103   [(set (match_operand:SI 0 "register_operand" "")
19104         (mult:SI (match_dup 0)
19105                  (match_operand:SI 1 "const_int_operand" "")))]
19106   "exact_log2 (INTVAL (operands[1])) >= 0
19107    && peep2_regno_dead_p (0, FLAGS_REG)"
19108   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19109               (clobber (reg:CC FLAGS_REG))])]
19110   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19111
19112 (define_peephole2
19113   [(set (match_operand:DI 0 "register_operand" "")
19114         (mult:DI (match_dup 0)
19115                  (match_operand:DI 1 "const_int_operand" "")))]
19116   "exact_log2 (INTVAL (operands[1])) >= 0
19117    && peep2_regno_dead_p (0, FLAGS_REG)"
19118   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19119               (clobber (reg:CC FLAGS_REG))])]
19120   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19121
19122 (define_peephole2
19123   [(set (match_operand:SI 0 "register_operand" "")
19124         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19125                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19126   "exact_log2 (INTVAL (operands[2])) >= 0
19127    && REGNO (operands[0]) == REGNO (operands[1])
19128    && peep2_regno_dead_p (0, FLAGS_REG)"
19129   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19130               (clobber (reg:CC FLAGS_REG))])]
19131   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19132
19133 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19134 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19135 ;; many CPUs it is also faster, since special hardware to avoid esp
19136 ;; dependencies is present.
19137
19138 ;; While some of these conversions may be done using splitters, we use peepholes
19139 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19140
19141 ;; Convert prologue esp subtractions to push.
19142 ;; We need register to push.  In order to keep verify_flow_info happy we have
19143 ;; two choices
19144 ;; - use scratch and clobber it in order to avoid dependencies
19145 ;; - use already live register
19146 ;; We can't use the second way right now, since there is no reliable way how to
19147 ;; verify that given register is live.  First choice will also most likely in
19148 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19149 ;; call clobbered registers are dead.  We may want to use base pointer as an
19150 ;; alternative when no register is available later.
19151
19152 (define_peephole2
19153   [(match_scratch:SI 0 "r")
19154    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19155               (clobber (reg:CC FLAGS_REG))
19156               (clobber (mem:BLK (scratch)))])]
19157   "optimize_size || !TARGET_SUB_ESP_4"
19158   [(clobber (match_dup 0))
19159    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19160               (clobber (mem:BLK (scratch)))])])
19161
19162 (define_peephole2
19163   [(match_scratch:SI 0 "r")
19164    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19165               (clobber (reg:CC FLAGS_REG))
19166               (clobber (mem:BLK (scratch)))])]
19167   "optimize_size || !TARGET_SUB_ESP_8"
19168   [(clobber (match_dup 0))
19169    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19170    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19171               (clobber (mem:BLK (scratch)))])])
19172
19173 ;; Convert esp subtractions to push.
19174 (define_peephole2
19175   [(match_scratch:SI 0 "r")
19176    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19177               (clobber (reg:CC FLAGS_REG))])]
19178   "optimize_size || !TARGET_SUB_ESP_4"
19179   [(clobber (match_dup 0))
19180    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19181
19182 (define_peephole2
19183   [(match_scratch:SI 0 "r")
19184    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19185               (clobber (reg:CC FLAGS_REG))])]
19186   "optimize_size || !TARGET_SUB_ESP_8"
19187   [(clobber (match_dup 0))
19188    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19189    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19190
19191 ;; Convert epilogue deallocator to pop.
19192 (define_peephole2
19193   [(match_scratch:SI 0 "r")
19194    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19195               (clobber (reg:CC FLAGS_REG))
19196               (clobber (mem:BLK (scratch)))])]
19197   "optimize_size || !TARGET_ADD_ESP_4"
19198   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19199               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19200               (clobber (mem:BLK (scratch)))])]
19201   "")
19202
19203 ;; Two pops case is tricky, since pop causes dependency on destination register.
19204 ;; We use two registers if available.
19205 (define_peephole2
19206   [(match_scratch:SI 0 "r")
19207    (match_scratch:SI 1 "r")
19208    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19209               (clobber (reg:CC FLAGS_REG))
19210               (clobber (mem:BLK (scratch)))])]
19211   "optimize_size || !TARGET_ADD_ESP_8"
19212   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19213               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19214               (clobber (mem:BLK (scratch)))])
19215    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19216               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19217   "")
19218
19219 (define_peephole2
19220   [(match_scratch:SI 0 "r")
19221    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19222               (clobber (reg:CC FLAGS_REG))
19223               (clobber (mem:BLK (scratch)))])]
19224   "optimize_size"
19225   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19226               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19227               (clobber (mem:BLK (scratch)))])
19228    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19229               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19230   "")
19231
19232 ;; Convert esp additions to pop.
19233 (define_peephole2
19234   [(match_scratch:SI 0 "r")
19235    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19236               (clobber (reg:CC FLAGS_REG))])]
19237   ""
19238   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19239               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19240   "")
19241
19242 ;; Two pops case is tricky, since pop causes dependency on destination register.
19243 ;; We use two registers if available.
19244 (define_peephole2
19245   [(match_scratch:SI 0 "r")
19246    (match_scratch:SI 1 "r")
19247    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19248               (clobber (reg:CC FLAGS_REG))])]
19249   ""
19250   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19251               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19252    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19253               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19254   "")
19255
19256 (define_peephole2
19257   [(match_scratch:SI 0 "r")
19258    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19259               (clobber (reg:CC FLAGS_REG))])]
19260   "optimize_size"
19261   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19262               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19263    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19264               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19265   "")
19266 \f
19267 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19268 ;; required and register dies.  Similarly for 128 to plus -128.
19269 (define_peephole2
19270   [(set (match_operand 0 "flags_reg_operand" "")
19271         (match_operator 1 "compare_operator"
19272           [(match_operand 2 "register_operand" "")
19273            (match_operand 3 "const_int_operand" "")]))]
19274   "(INTVAL (operands[3]) == -1
19275     || INTVAL (operands[3]) == 1
19276     || INTVAL (operands[3]) == 128)
19277    && ix86_match_ccmode (insn, CCGCmode)
19278    && peep2_reg_dead_p (1, operands[2])"
19279   [(parallel [(set (match_dup 0)
19280                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19281               (clobber (match_dup 2))])]
19282   "")
19283 \f
19284 (define_peephole2
19285   [(match_scratch:DI 0 "r")
19286    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19287               (clobber (reg:CC FLAGS_REG))
19288               (clobber (mem:BLK (scratch)))])]
19289   "optimize_size || !TARGET_SUB_ESP_4"
19290   [(clobber (match_dup 0))
19291    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19292               (clobber (mem:BLK (scratch)))])])
19293
19294 (define_peephole2
19295   [(match_scratch:DI 0 "r")
19296    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19297               (clobber (reg:CC FLAGS_REG))
19298               (clobber (mem:BLK (scratch)))])]
19299   "optimize_size || !TARGET_SUB_ESP_8"
19300   [(clobber (match_dup 0))
19301    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19302    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19303               (clobber (mem:BLK (scratch)))])])
19304
19305 ;; Convert esp subtractions to push.
19306 (define_peephole2
19307   [(match_scratch:DI 0 "r")
19308    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19309               (clobber (reg:CC FLAGS_REG))])]
19310   "optimize_size || !TARGET_SUB_ESP_4"
19311   [(clobber (match_dup 0))
19312    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19313
19314 (define_peephole2
19315   [(match_scratch:DI 0 "r")
19316    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19317               (clobber (reg:CC FLAGS_REG))])]
19318   "optimize_size || !TARGET_SUB_ESP_8"
19319   [(clobber (match_dup 0))
19320    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19321    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19322
19323 ;; Convert epilogue deallocator to pop.
19324 (define_peephole2
19325   [(match_scratch:DI 0 "r")
19326    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19327               (clobber (reg:CC FLAGS_REG))
19328               (clobber (mem:BLK (scratch)))])]
19329   "optimize_size || !TARGET_ADD_ESP_4"
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               (clobber (mem:BLK (scratch)))])]
19333   "")
19334
19335 ;; Two pops case is tricky, since pop causes dependency on destination register.
19336 ;; We use two registers if available.
19337 (define_peephole2
19338   [(match_scratch:DI 0 "r")
19339    (match_scratch:DI 1 "r")
19340    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19341               (clobber (reg:CC FLAGS_REG))
19342               (clobber (mem:BLK (scratch)))])]
19343   "optimize_size || !TARGET_ADD_ESP_8"
19344   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19345               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19346               (clobber (mem:BLK (scratch)))])
19347    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19348               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19349   "")
19350
19351 (define_peephole2
19352   [(match_scratch:DI 0 "r")
19353    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19354               (clobber (reg:CC FLAGS_REG))
19355               (clobber (mem:BLK (scratch)))])]
19356   "optimize_size"
19357   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19358               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19359               (clobber (mem:BLK (scratch)))])
19360    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19361               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19362   "")
19363
19364 ;; Convert esp additions to pop.
19365 (define_peephole2
19366   [(match_scratch:DI 0 "r")
19367    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19368               (clobber (reg:CC FLAGS_REG))])]
19369   ""
19370   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19371               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19372   "")
19373
19374 ;; Two pops case is tricky, since pop causes dependency on destination register.
19375 ;; We use two registers if available.
19376 (define_peephole2
19377   [(match_scratch:DI 0 "r")
19378    (match_scratch:DI 1 "r")
19379    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19380               (clobber (reg:CC FLAGS_REG))])]
19381   ""
19382   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19383               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19384    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19385               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19386   "")
19387
19388 (define_peephole2
19389   [(match_scratch:DI 0 "r")
19390    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19391               (clobber (reg:CC FLAGS_REG))])]
19392   "optimize_size"
19393   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19394               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19395    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19396               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19397   "")
19398 \f
19399 ;; Convert imul by three, five and nine into lea
19400 (define_peephole2
19401   [(parallel
19402     [(set (match_operand:SI 0 "register_operand" "")
19403           (mult:SI (match_operand:SI 1 "register_operand" "")
19404                    (match_operand:SI 2 "const_int_operand" "")))
19405      (clobber (reg:CC FLAGS_REG))])]
19406   "INTVAL (operands[2]) == 3
19407    || INTVAL (operands[2]) == 5
19408    || INTVAL (operands[2]) == 9"
19409   [(set (match_dup 0)
19410         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19411                  (match_dup 1)))]
19412   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19413
19414 (define_peephole2
19415   [(parallel
19416     [(set (match_operand:SI 0 "register_operand" "")
19417           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19418                    (match_operand:SI 2 "const_int_operand" "")))
19419      (clobber (reg:CC FLAGS_REG))])]
19420   "!optimize_size 
19421    && (INTVAL (operands[2]) == 3
19422        || INTVAL (operands[2]) == 5
19423        || INTVAL (operands[2]) == 9)"
19424   [(set (match_dup 0) (match_dup 1))
19425    (set (match_dup 0)
19426         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19427                  (match_dup 0)))]
19428   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19429
19430 (define_peephole2
19431   [(parallel
19432     [(set (match_operand:DI 0 "register_operand" "")
19433           (mult:DI (match_operand:DI 1 "register_operand" "")
19434                    (match_operand:DI 2 "const_int_operand" "")))
19435      (clobber (reg:CC FLAGS_REG))])]
19436   "TARGET_64BIT
19437    && (INTVAL (operands[2]) == 3
19438        || INTVAL (operands[2]) == 5
19439        || INTVAL (operands[2]) == 9)"
19440   [(set (match_dup 0)
19441         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19442                  (match_dup 1)))]
19443   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19444
19445 (define_peephole2
19446   [(parallel
19447     [(set (match_operand:DI 0 "register_operand" "")
19448           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19449                    (match_operand:DI 2 "const_int_operand" "")))
19450      (clobber (reg:CC FLAGS_REG))])]
19451   "TARGET_64BIT
19452    && !optimize_size 
19453    && (INTVAL (operands[2]) == 3
19454        || INTVAL (operands[2]) == 5
19455        || INTVAL (operands[2]) == 9)"
19456   [(set (match_dup 0) (match_dup 1))
19457    (set (match_dup 0)
19458         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19459                  (match_dup 0)))]
19460   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19461
19462 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19463 ;; imul $32bit_imm, reg, reg is direct decoded.
19464 (define_peephole2
19465   [(match_scratch:DI 3 "r")
19466    (parallel [(set (match_operand:DI 0 "register_operand" "")
19467                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19468                             (match_operand:DI 2 "immediate_operand" "")))
19469               (clobber (reg:CC FLAGS_REG))])]
19470   "TARGET_K8 && !optimize_size
19471    && (GET_CODE (operands[2]) != CONST_INT
19472        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19473   [(set (match_dup 3) (match_dup 1))
19474    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19475               (clobber (reg:CC FLAGS_REG))])]
19476 "")
19477
19478 (define_peephole2
19479   [(match_scratch:SI 3 "r")
19480    (parallel [(set (match_operand:SI 0 "register_operand" "")
19481                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19482                             (match_operand:SI 2 "immediate_operand" "")))
19483               (clobber (reg:CC FLAGS_REG))])]
19484   "TARGET_K8 && !optimize_size
19485    && (GET_CODE (operands[2]) != CONST_INT
19486        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19487   [(set (match_dup 3) (match_dup 1))
19488    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19489               (clobber (reg:CC FLAGS_REG))])]
19490 "")
19491
19492 (define_peephole2
19493   [(match_scratch:SI 3 "r")
19494    (parallel [(set (match_operand:DI 0 "register_operand" "")
19495                    (zero_extend:DI
19496                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19497                               (match_operand:SI 2 "immediate_operand" ""))))
19498               (clobber (reg:CC FLAGS_REG))])]
19499   "TARGET_K8 && !optimize_size
19500    && (GET_CODE (operands[2]) != CONST_INT
19501        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19502   [(set (match_dup 3) (match_dup 1))
19503    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19504               (clobber (reg:CC FLAGS_REG))])]
19505 "")
19506
19507 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19508 ;; Convert it into imul reg, reg
19509 ;; It would be better to force assembler to encode instruction using long
19510 ;; immediate, but there is apparently no way to do so.
19511 (define_peephole2
19512   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19513                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19514                             (match_operand:DI 2 "const_int_operand" "")))
19515               (clobber (reg:CC FLAGS_REG))])
19516    (match_scratch:DI 3 "r")]
19517   "TARGET_K8 && !optimize_size
19518    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19519   [(set (match_dup 3) (match_dup 2))
19520    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19521               (clobber (reg:CC FLAGS_REG))])]
19522 {
19523   if (!rtx_equal_p (operands[0], operands[1]))
19524     emit_move_insn (operands[0], operands[1]);
19525 })
19526
19527 (define_peephole2
19528   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19529                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19530                             (match_operand:SI 2 "const_int_operand" "")))
19531               (clobber (reg:CC FLAGS_REG))])
19532    (match_scratch:SI 3 "r")]
19533   "TARGET_K8 && !optimize_size
19534    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19535   [(set (match_dup 3) (match_dup 2))
19536    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19537               (clobber (reg:CC FLAGS_REG))])]
19538 {
19539   if (!rtx_equal_p (operands[0], operands[1]))
19540     emit_move_insn (operands[0], operands[1]);
19541 })
19542
19543 (define_peephole2
19544   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19545                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19546                             (match_operand:HI 2 "immediate_operand" "")))
19547               (clobber (reg:CC FLAGS_REG))])
19548    (match_scratch:HI 3 "r")]
19549   "TARGET_K8 && !optimize_size"
19550   [(set (match_dup 3) (match_dup 2))
19551    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19552               (clobber (reg:CC FLAGS_REG))])]
19553 {
19554   if (!rtx_equal_p (operands[0], operands[1]))
19555     emit_move_insn (operands[0], operands[1]);
19556 })
19557 \f
19558 ;; Call-value patterns last so that the wildcard operand does not
19559 ;; disrupt insn-recog's switch tables.
19560
19561 (define_insn "*call_value_pop_0"
19562   [(set (match_operand 0 "" "")
19563         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19564               (match_operand:SI 2 "" "")))
19565    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19566                             (match_operand:SI 3 "immediate_operand" "")))]
19567   "!TARGET_64BIT"
19568 {
19569   if (SIBLING_CALL_P (insn))
19570     return "jmp\t%P1";
19571   else
19572     return "call\t%P1";
19573 }
19574   [(set_attr "type" "callv")])
19575
19576 (define_insn "*call_value_pop_1"
19577   [(set (match_operand 0 "" "")
19578         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19579               (match_operand:SI 2 "" "")))
19580    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19581                             (match_operand:SI 3 "immediate_operand" "i")))]
19582   "!TARGET_64BIT"
19583 {
19584   if (constant_call_address_operand (operands[1], Pmode))
19585     {
19586       if (SIBLING_CALL_P (insn))
19587         return "jmp\t%P1";
19588       else
19589         return "call\t%P1";
19590     }
19591   if (SIBLING_CALL_P (insn))
19592     return "jmp\t%A1";
19593   else
19594     return "call\t%A1";
19595 }
19596   [(set_attr "type" "callv")])
19597
19598 (define_insn "*call_value_0"
19599   [(set (match_operand 0 "" "")
19600         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19601               (match_operand:SI 2 "" "")))]
19602   "!TARGET_64BIT"
19603 {
19604   if (SIBLING_CALL_P (insn))
19605     return "jmp\t%P1";
19606   else
19607     return "call\t%P1";
19608 }
19609   [(set_attr "type" "callv")])
19610
19611 (define_insn "*call_value_0_rex64"
19612   [(set (match_operand 0 "" "")
19613         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19614               (match_operand:DI 2 "const_int_operand" "")))]
19615   "TARGET_64BIT"
19616 {
19617   if (SIBLING_CALL_P (insn))
19618     return "jmp\t%P1";
19619   else
19620     return "call\t%P1";
19621 }
19622   [(set_attr "type" "callv")])
19623
19624 (define_insn "*call_value_1"
19625   [(set (match_operand 0 "" "")
19626         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19627               (match_operand:SI 2 "" "")))]
19628   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19629 {
19630   if (constant_call_address_operand (operands[1], Pmode))
19631     return "call\t%P1";
19632   return "call\t%A1";
19633 }
19634   [(set_attr "type" "callv")])
19635
19636 (define_insn "*sibcall_value_1"
19637   [(set (match_operand 0 "" "")
19638         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19639               (match_operand:SI 2 "" "")))]
19640   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19641 {
19642   if (constant_call_address_operand (operands[1], Pmode))
19643     return "jmp\t%P1";
19644   return "jmp\t%A1";
19645 }
19646   [(set_attr "type" "callv")])
19647
19648 (define_insn "*call_value_1_rex64"
19649   [(set (match_operand 0 "" "")
19650         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19651               (match_operand:DI 2 "" "")))]
19652   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19653 {
19654   if (constant_call_address_operand (operands[1], Pmode))
19655     return "call\t%P1";
19656   return "call\t%A1";
19657 }
19658   [(set_attr "type" "callv")])
19659
19660 (define_insn "*sibcall_value_1_rex64"
19661   [(set (match_operand 0 "" "")
19662         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19663               (match_operand:DI 2 "" "")))]
19664   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19665   "jmp\t%P1"
19666   [(set_attr "type" "callv")])
19667
19668 (define_insn "*sibcall_value_1_rex64_v"
19669   [(set (match_operand 0 "" "")
19670         (call (mem:QI (reg:DI 40))
19671               (match_operand:DI 1 "" "")))]
19672   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19673   "jmp\t*%%r11"
19674   [(set_attr "type" "callv")])
19675 \f
19676 (define_insn "trap"
19677   [(trap_if (const_int 1) (const_int 5))]
19678   ""
19679   "int\t$5")
19680
19681 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19682 ;;; for the sake of bounds checking.  By emitting bounds checks as
19683 ;;; conditional traps rather than as conditional jumps around
19684 ;;; unconditional traps we avoid introducing spurious basic-block
19685 ;;; boundaries and facilitate elimination of redundant checks.  In
19686 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19687 ;;; interrupt 5.
19688 ;;; 
19689 ;;; FIXME: Static branch prediction rules for ix86 are such that
19690 ;;; forward conditional branches predict as untaken.  As implemented
19691 ;;; below, pseudo conditional traps violate that rule.  We should use
19692 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19693 ;;; section loaded at the end of the text segment and branch forward
19694 ;;; there on bounds-failure, and then jump back immediately (in case
19695 ;;; the system chooses to ignore bounds violations, or to report
19696 ;;; violations and continue execution).
19697
19698 (define_expand "conditional_trap"
19699   [(trap_if (match_operator 0 "comparison_operator"
19700              [(match_dup 2) (const_int 0)])
19701             (match_operand 1 "const_int_operand" ""))]
19702   ""
19703 {
19704   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19705                               ix86_expand_compare (GET_CODE (operands[0]),
19706                                                    NULL, NULL),
19707                               operands[1]));
19708   DONE;
19709 })
19710
19711 (define_insn "*conditional_trap_1"
19712   [(trap_if (match_operator 0 "comparison_operator"
19713              [(reg FLAGS_REG) (const_int 0)])
19714             (match_operand 1 "const_int_operand" ""))]
19715   ""
19716 {
19717   operands[2] = gen_label_rtx ();
19718   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19719   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19720                              CODE_LABEL_NUMBER (operands[2]));
19721   RET;
19722 })
19723
19724         ;; Pentium III SIMD instructions.
19725
19726 ;; Moves for SSE/MMX regs.
19727
19728 (define_insn "movv4sf_internal"
19729   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19730         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19731   "TARGET_SSE"
19732   "@
19733     xorps\t%0, %0
19734     movaps\t{%1, %0|%0, %1}
19735     movaps\t{%1, %0|%0, %1}"
19736   [(set_attr "type" "ssemov")
19737    (set_attr "mode" "V4SF")])
19738
19739 (define_split
19740   [(set (match_operand:V4SF 0 "register_operand" "")
19741         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19742   "TARGET_SSE && reload_completed"
19743   [(set (match_dup 0)
19744         (vec_merge:V4SF
19745          (vec_duplicate:V4SF (match_dup 1))
19746          (match_dup 2)
19747          (const_int 1)))]
19748 {
19749   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19750   operands[2] = CONST0_RTX (V4SFmode);
19751 })
19752
19753 (define_insn "movv4si_internal"
19754   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19755         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19756   "TARGET_SSE"
19757 {
19758   switch (which_alternative)
19759     {
19760     case 0:
19761       if (get_attr_mode (insn) == MODE_V4SF)
19762         return "xorps\t%0, %0";
19763       else
19764         return "pxor\t%0, %0";
19765     case 1:
19766     case 2:
19767       if (get_attr_mode (insn) == MODE_V4SF)
19768         return "movaps\t{%1, %0|%0, %1}";
19769       else
19770         return "movdqa\t{%1, %0|%0, %1}";
19771     default:
19772       abort ();
19773     }
19774 }
19775   [(set_attr "type" "ssemov")
19776    (set (attr "mode")
19777         (cond [(eq_attr "alternative" "0,1")
19778                  (if_then_else
19779                    (ne (symbol_ref "optimize_size")
19780                        (const_int 0))
19781                    (const_string "V4SF")
19782                    (const_string "TI"))
19783                (eq_attr "alternative" "2")
19784                  (if_then_else
19785                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19786                             (const_int 0))
19787                         (ne (symbol_ref "optimize_size")
19788                             (const_int 0)))
19789                    (const_string "V4SF")
19790                    (const_string "TI"))]
19791                (const_string "TI")))])
19792
19793 (define_insn "movv2di_internal"
19794   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19795         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19796   "TARGET_SSE"
19797 {
19798   switch (which_alternative)
19799     {
19800     case 0:
19801       if (get_attr_mode (insn) == MODE_V4SF)
19802         return "xorps\t%0, %0";
19803       else
19804         return "pxor\t%0, %0";
19805     case 1:
19806     case 2:
19807       if (get_attr_mode (insn) == MODE_V4SF)
19808         return "movaps\t{%1, %0|%0, %1}";
19809       else
19810         return "movdqa\t{%1, %0|%0, %1}";
19811     default:
19812       abort ();
19813     }
19814 }
19815   [(set_attr "type" "ssemov")
19816    (set (attr "mode")
19817         (cond [(eq_attr "alternative" "0,1")
19818                  (if_then_else
19819                    (ne (symbol_ref "optimize_size")
19820                        (const_int 0))
19821                    (const_string "V4SF")
19822                    (const_string "TI"))
19823                (eq_attr "alternative" "2")
19824                  (if_then_else
19825                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19826                             (const_int 0))
19827                         (ne (symbol_ref "optimize_size")
19828                             (const_int 0)))
19829                    (const_string "V4SF")
19830                    (const_string "TI"))]
19831                (const_string "TI")))])
19832
19833 (define_split
19834   [(set (match_operand:V2DF 0 "register_operand" "")
19835         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19836   "TARGET_SSE2 && reload_completed"
19837   [(set (match_dup 0)
19838         (vec_merge:V2DF
19839          (vec_duplicate:V2DF (match_dup 1))
19840          (match_dup 2)
19841          (const_int 1)))]
19842 {
19843   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19844   operands[2] = CONST0_RTX (V2DFmode);
19845 })
19846
19847 (define_insn "movv8qi_internal"
19848   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19849         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19850   "TARGET_MMX
19851    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19852   "@
19853     pxor\t%0, %0
19854     movq\t{%1, %0|%0, %1}
19855     movq\t{%1, %0|%0, %1}
19856     movdq2q\t{%1, %0|%0, %1}
19857     movq2dq\t{%1, %0|%0, %1}
19858     movq\t{%1, %0|%0, %1}
19859     movq\t{%1, %0|%0, %1}"
19860   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19861    (set_attr "mode" "DI")])
19862
19863 (define_insn "movv4hi_internal"
19864   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19865         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19866   "TARGET_MMX
19867    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19868   "@
19869     pxor\t%0, %0
19870     movq\t{%1, %0|%0, %1}
19871     movq\t{%1, %0|%0, %1}
19872     movdq2q\t{%1, %0|%0, %1}
19873     movq2dq\t{%1, %0|%0, %1}
19874     movq\t{%1, %0|%0, %1}
19875     movq\t{%1, %0|%0, %1}"
19876   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19877    (set_attr "mode" "DI")])
19878
19879 (define_insn "*movv2si_internal"
19880   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19881         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19882   "TARGET_MMX
19883    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19884   "@
19885     pxor\t%0, %0
19886     movq\t{%1, %0|%0, %1}
19887     movq\t{%1, %0|%0, %1}
19888     movdq2q\t{%1, %0|%0, %1}
19889     movq2dq\t{%1, %0|%0, %1}
19890     movq\t{%1, %0|%0, %1}
19891     movq\t{%1, %0|%0, %1}"
19892   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19893    (set_attr "mode" "DI")])
19894
19895 (define_insn "movv2sf_internal"
19896   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19897         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
19898   "TARGET_3DNOW
19899    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19900   "@
19901     pxor\t%0, %0
19902     movq\t{%1, %0|%0, %1}
19903     movq\t{%1, %0|%0, %1}
19904     movdq2q\t{%1, %0|%0, %1}
19905     movq2dq\t{%1, %0|%0, %1}
19906     movlps\t{%1, %0|%0, %1}
19907     movlps\t{%1, %0|%0, %1}"
19908   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19909    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
19910
19911 (define_expand "movti"
19912   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19913         (match_operand:TI 1 "nonimmediate_operand" ""))]
19914   "TARGET_SSE || TARGET_64BIT"
19915 {
19916   if (TARGET_64BIT)
19917     ix86_expand_move (TImode, operands);
19918   else
19919     ix86_expand_vector_move (TImode, operands);
19920   DONE;
19921 })
19922
19923 (define_expand "movtf"
19924   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19925         (match_operand:TF 1 "nonimmediate_operand" ""))]
19926   "TARGET_64BIT"
19927 {
19928   if (TARGET_64BIT)
19929     ix86_expand_move (TFmode, operands);
19930   else
19931     ix86_expand_vector_move (TFmode, operands);
19932   DONE;
19933 })
19934
19935 (define_insn "movv2df_internal"
19936   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19937         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19938   "TARGET_SSE2
19939    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19940 {
19941   switch (which_alternative)
19942     {
19943     case 0:
19944       if (get_attr_mode (insn) == MODE_V4SF)
19945         return "xorps\t%0, %0";
19946       else
19947         return "xorpd\t%0, %0";
19948     case 1:
19949     case 2:
19950       if (get_attr_mode (insn) == MODE_V4SF)
19951         return "movaps\t{%1, %0|%0, %1}";
19952       else
19953         return "movapd\t{%1, %0|%0, %1}";
19954     default:
19955       abort ();
19956     }
19957 }
19958   [(set_attr "type" "ssemov")
19959    (set (attr "mode")
19960         (cond [(eq_attr "alternative" "0,1")
19961                  (if_then_else
19962                    (ne (symbol_ref "optimize_size")
19963                        (const_int 0))
19964                    (const_string "V4SF")
19965                    (const_string "V2DF"))
19966                (eq_attr "alternative" "2")
19967                  (if_then_else
19968                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19969                             (const_int 0))
19970                         (ne (symbol_ref "optimize_size")
19971                             (const_int 0)))
19972                    (const_string "V4SF")
19973                    (const_string "V2DF"))]
19974                (const_string "V2DF")))])
19975
19976 (define_insn "movv8hi_internal"
19977   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19978         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19979   "TARGET_SSE2
19980    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19981 {
19982   switch (which_alternative)
19983     {
19984     case 0:
19985       if (get_attr_mode (insn) == MODE_V4SF)
19986         return "xorps\t%0, %0";
19987       else
19988         return "pxor\t%0, %0";
19989     case 1:
19990     case 2:
19991       if (get_attr_mode (insn) == MODE_V4SF)
19992         return "movaps\t{%1, %0|%0, %1}";
19993       else
19994         return "movdqa\t{%1, %0|%0, %1}";
19995     default:
19996       abort ();
19997     }
19998 }
19999   [(set_attr "type" "ssemov")
20000    (set (attr "mode")
20001         (cond [(eq_attr "alternative" "0,1")
20002                  (if_then_else
20003                    (ne (symbol_ref "optimize_size")
20004                        (const_int 0))
20005                    (const_string "V4SF")
20006                    (const_string "TI"))
20007                (eq_attr "alternative" "2")
20008                  (if_then_else
20009                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20010                             (const_int 0))
20011                         (ne (symbol_ref "optimize_size")
20012                             (const_int 0)))
20013                    (const_string "V4SF")
20014                    (const_string "TI"))]
20015                (const_string "TI")))])
20016
20017 (define_insn "movv16qi_internal"
20018   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20019         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20020   "TARGET_SSE2
20021    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20022 {
20023   switch (which_alternative)
20024     {
20025     case 0:
20026       if (get_attr_mode (insn) == MODE_V4SF)
20027         return "xorps\t%0, %0";
20028       else
20029         return "pxor\t%0, %0";
20030     case 1:
20031     case 2:
20032       if (get_attr_mode (insn) == MODE_V4SF)
20033         return "movaps\t{%1, %0|%0, %1}";
20034       else
20035         return "movdqa\t{%1, %0|%0, %1}";
20036     default:
20037       abort ();
20038     }
20039 }
20040   [(set_attr "type" "ssemov")
20041    (set (attr "mode")
20042         (cond [(eq_attr "alternative" "0,1")
20043                  (if_then_else
20044                    (ne (symbol_ref "optimize_size")
20045                        (const_int 0))
20046                    (const_string "V4SF")
20047                    (const_string "TI"))
20048                (eq_attr "alternative" "2")
20049                  (if_then_else
20050                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20051                             (const_int 0))
20052                         (ne (symbol_ref "optimize_size")
20053                             (const_int 0)))
20054                    (const_string "V4SF")
20055                    (const_string "TI"))]
20056                (const_string "TI")))])
20057
20058 (define_expand "movv2df"
20059   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20060         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20061   "TARGET_SSE2"
20062 {
20063   ix86_expand_vector_move (V2DFmode, operands);
20064   DONE;
20065 })
20066
20067 (define_expand "movv8hi"
20068   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20069         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20070   "TARGET_SSE2"
20071 {
20072   ix86_expand_vector_move (V8HImode, operands);
20073   DONE;
20074 })
20075
20076 (define_expand "movv16qi"
20077   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20078         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20079   "TARGET_SSE2"
20080 {
20081   ix86_expand_vector_move (V16QImode, operands);
20082   DONE;
20083 })
20084
20085 (define_expand "movv4sf"
20086   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20087         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20088   "TARGET_SSE"
20089 {
20090   ix86_expand_vector_move (V4SFmode, operands);
20091   DONE;
20092 })
20093
20094 (define_expand "movv4si"
20095   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20096         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20097   "TARGET_SSE"
20098 {
20099   ix86_expand_vector_move (V4SImode, operands);
20100   DONE;
20101 })
20102
20103 (define_expand "movv2di"
20104   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20105         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20106   "TARGET_SSE"
20107 {
20108   ix86_expand_vector_move (V2DImode, operands);
20109   DONE;
20110 })
20111
20112 (define_expand "movv2si"
20113   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20114         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20115   "TARGET_MMX"
20116 {
20117   ix86_expand_vector_move (V2SImode, operands);
20118   DONE;
20119 })
20120
20121 (define_expand "movv4hi"
20122   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20123         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20124   "TARGET_MMX"
20125 {
20126   ix86_expand_vector_move (V4HImode, operands);
20127   DONE;
20128 })
20129
20130 (define_expand "movv8qi"
20131   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20132         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20133   "TARGET_MMX"
20134 {
20135   ix86_expand_vector_move (V8QImode, operands);
20136   DONE;
20137 })
20138
20139 (define_expand "movv2sf"
20140   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20141         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20142    "TARGET_3DNOW"
20143 {
20144   ix86_expand_vector_move (V2SFmode, operands);
20145   DONE;
20146 })
20147
20148 (define_insn "*pushti"
20149   [(set (match_operand:TI 0 "push_operand" "=<")
20150         (match_operand:TI 1 "register_operand" "x"))]
20151   "TARGET_SSE"
20152   "#")
20153
20154 (define_insn "*pushv2df"
20155   [(set (match_operand:V2DF 0 "push_operand" "=<")
20156         (match_operand:V2DF 1 "register_operand" "x"))]
20157   "TARGET_SSE"
20158   "#")
20159
20160 (define_insn "*pushv2di"
20161   [(set (match_operand:V2DI 0 "push_operand" "=<")
20162         (match_operand:V2DI 1 "register_operand" "x"))]
20163   "TARGET_SSE2"
20164   "#")
20165
20166 (define_insn "*pushv8hi"
20167   [(set (match_operand:V8HI 0 "push_operand" "=<")
20168         (match_operand:V8HI 1 "register_operand" "x"))]
20169   "TARGET_SSE2"
20170   "#")
20171
20172 (define_insn "*pushv16qi"
20173   [(set (match_operand:V16QI 0 "push_operand" "=<")
20174         (match_operand:V16QI 1 "register_operand" "x"))]
20175   "TARGET_SSE2"
20176   "#")
20177
20178 (define_insn "*pushv4sf"
20179   [(set (match_operand:V4SF 0 "push_operand" "=<")
20180         (match_operand:V4SF 1 "register_operand" "x"))]
20181   "TARGET_SSE"
20182   "#")
20183
20184 (define_insn "*pushv4si"
20185   [(set (match_operand:V4SI 0 "push_operand" "=<")
20186         (match_operand:V4SI 1 "register_operand" "x"))]
20187   "TARGET_SSE2"
20188   "#")
20189
20190 (define_insn "*pushv2si"
20191   [(set (match_operand:V2SI 0 "push_operand" "=<")
20192         (match_operand:V2SI 1 "register_operand" "y"))]
20193   "TARGET_MMX"
20194   "#")
20195
20196 (define_insn "*pushv4hi"
20197   [(set (match_operand:V4HI 0 "push_operand" "=<")
20198         (match_operand:V4HI 1 "register_operand" "y"))]
20199   "TARGET_MMX"
20200   "#")
20201
20202 (define_insn "*pushv8qi"
20203   [(set (match_operand:V8QI 0 "push_operand" "=<")
20204         (match_operand:V8QI 1 "register_operand" "y"))]
20205   "TARGET_MMX"
20206   "#")
20207
20208 (define_insn "*pushv2sf"
20209   [(set (match_operand:V2SF 0 "push_operand" "=<")
20210         (match_operand:V2SF 1 "register_operand" "y"))]
20211   "TARGET_3DNOW"
20212   "#")
20213
20214 (define_split
20215   [(set (match_operand 0 "push_operand" "")
20216         (match_operand 1 "register_operand" ""))]
20217   "!TARGET_64BIT && reload_completed
20218    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20219   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20220    (set (match_dup 2) (match_dup 1))]
20221   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20222                                  stack_pointer_rtx);
20223    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20224
20225 (define_split
20226   [(set (match_operand 0 "push_operand" "")
20227         (match_operand 1 "register_operand" ""))]
20228   "TARGET_64BIT && reload_completed
20229    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20230   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20231    (set (match_dup 2) (match_dup 1))]
20232   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20233                                  stack_pointer_rtx);
20234    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20235
20236
20237 (define_insn "movti_internal"
20238   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20239         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20240   "TARGET_SSE && !TARGET_64BIT
20241    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20242 {
20243   switch (which_alternative)
20244     {
20245     case 0:
20246       if (get_attr_mode (insn) == MODE_V4SF)
20247         return "xorps\t%0, %0";
20248       else
20249         return "pxor\t%0, %0";
20250     case 1:
20251     case 2:
20252       if (get_attr_mode (insn) == MODE_V4SF)
20253         return "movaps\t{%1, %0|%0, %1}";
20254       else
20255         return "movdqa\t{%1, %0|%0, %1}";
20256     default:
20257       abort ();
20258     }
20259 }
20260   [(set_attr "type" "ssemov,ssemov,ssemov")
20261    (set (attr "mode")
20262         (cond [(eq_attr "alternative" "0,1")
20263                  (if_then_else
20264                    (ne (symbol_ref "optimize_size")
20265                        (const_int 0))
20266                    (const_string "V4SF")
20267                    (const_string "TI"))
20268                (eq_attr "alternative" "2")
20269                  (if_then_else
20270                    (ne (symbol_ref "optimize_size")
20271                        (const_int 0))
20272                    (const_string "V4SF")
20273                    (const_string "TI"))]
20274                (const_string "TI")))])
20275
20276 (define_insn "*movti_rex64"
20277   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20278         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20279   "TARGET_64BIT
20280    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20281 {
20282   switch (which_alternative)
20283     {
20284     case 0:
20285     case 1:
20286       return "#";
20287     case 2:
20288       if (get_attr_mode (insn) == MODE_V4SF)
20289         return "xorps\t%0, %0";
20290       else
20291         return "pxor\t%0, %0";
20292     case 3:
20293     case 4:
20294       if (get_attr_mode (insn) == MODE_V4SF)
20295         return "movaps\t{%1, %0|%0, %1}";
20296       else
20297         return "movdqa\t{%1, %0|%0, %1}";
20298     default:
20299       abort ();
20300     }
20301 }
20302   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20303    (set (attr "mode")
20304         (cond [(eq_attr "alternative" "2,3")
20305                  (if_then_else
20306                    (ne (symbol_ref "optimize_size")
20307                        (const_int 0))
20308                    (const_string "V4SF")
20309                    (const_string "TI"))
20310                (eq_attr "alternative" "4")
20311                  (if_then_else
20312                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20313                             (const_int 0))
20314                         (ne (symbol_ref "optimize_size")
20315                             (const_int 0)))
20316                    (const_string "V4SF")
20317                    (const_string "TI"))]
20318                (const_string "DI")))])
20319
20320 (define_insn "*movtf_rex64"
20321   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20322         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20323   "TARGET_64BIT
20324    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20325 {
20326   switch (which_alternative)
20327     {
20328     case 0:
20329     case 1:
20330       return "#";
20331     case 2:
20332       if (get_attr_mode (insn) == MODE_V4SF)
20333         return "xorps\t%0, %0";
20334       else
20335         return "pxor\t%0, %0";
20336     case 3:
20337     case 4:
20338       if (get_attr_mode (insn) == MODE_V4SF)
20339         return "movaps\t{%1, %0|%0, %1}";
20340       else
20341         return "movdqa\t{%1, %0|%0, %1}";
20342     default:
20343       abort ();
20344     }
20345 }
20346   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20347    (set (attr "mode")
20348         (cond [(eq_attr "alternative" "2,3")
20349                  (if_then_else
20350                    (ne (symbol_ref "optimize_size")
20351                        (const_int 0))
20352                    (const_string "V4SF")
20353                    (const_string "TI"))
20354                (eq_attr "alternative" "4")
20355                  (if_then_else
20356                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20357                             (const_int 0))
20358                         (ne (symbol_ref "optimize_size")
20359                             (const_int 0)))
20360                    (const_string "V4SF")
20361                    (const_string "TI"))]
20362                (const_string "DI")))])
20363
20364 (define_split
20365   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20366         (match_operand:TI 1 "general_operand" ""))]
20367   "reload_completed && !SSE_REG_P (operands[0])
20368    && !SSE_REG_P (operands[1])"
20369   [(const_int 0)]
20370   "ix86_split_long_move (operands); DONE;")
20371
20372 (define_split
20373   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20374         (match_operand:TF 1 "general_operand" ""))]
20375   "reload_completed && !SSE_REG_P (operands[0])
20376    && !SSE_REG_P (operands[1])"
20377   [(const_int 0)]
20378   "ix86_split_long_move (operands); DONE;")
20379
20380 ;; These two patterns are useful for specifying exactly whether to use
20381 ;; movaps or movups
20382 (define_expand "sse_movaps"
20383   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20384         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20385                      UNSPEC_MOVA))]
20386   "TARGET_SSE"
20387 {
20388   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20389     {
20390       rtx tmp = gen_reg_rtx (V4SFmode);
20391       emit_insn (gen_sse_movaps (tmp, operands[1]));
20392       emit_move_insn (operands[0], tmp);
20393       DONE;
20394     }
20395 })
20396
20397 (define_insn "*sse_movaps_1"
20398   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20399         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20400                      UNSPEC_MOVA))]
20401   "TARGET_SSE
20402    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20403   "movaps\t{%1, %0|%0, %1}"
20404   [(set_attr "type" "ssemov,ssemov")
20405    (set_attr "mode" "V4SF")])
20406
20407 (define_expand "sse_movups"
20408   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20409         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20410                      UNSPEC_MOVU))]
20411   "TARGET_SSE"
20412 {
20413   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20414     {
20415       rtx tmp = gen_reg_rtx (V4SFmode);
20416       emit_insn (gen_sse_movups (tmp, operands[1]));
20417       emit_move_insn (operands[0], tmp);
20418       DONE;
20419     }
20420 })
20421
20422 (define_insn "*sse_movups_1"
20423   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20424         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20425                      UNSPEC_MOVU))]
20426   "TARGET_SSE
20427    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20428   "movups\t{%1, %0|%0, %1}"
20429   [(set_attr "type" "ssecvt,ssecvt")
20430    (set_attr "mode" "V4SF")])
20431
20432 ;; SSE Strange Moves.
20433
20434 (define_insn "sse_movmskps"
20435   [(set (match_operand:SI 0 "register_operand" "=r")
20436         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20437                    UNSPEC_MOVMSK))]
20438   "TARGET_SSE"
20439   "movmskps\t{%1, %0|%0, %1}"
20440   [(set_attr "type" "ssecvt")
20441    (set_attr "mode" "V4SF")])
20442
20443 (define_insn "mmx_pmovmskb"
20444   [(set (match_operand:SI 0 "register_operand" "=r")
20445         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20446                    UNSPEC_MOVMSK))]
20447   "TARGET_SSE || TARGET_3DNOW_A"
20448   "pmovmskb\t{%1, %0|%0, %1}"
20449   [(set_attr "type" "ssecvt")
20450    (set_attr "mode" "V4SF")])
20451
20452
20453 (define_insn "mmx_maskmovq"
20454   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20455         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20456                       (match_operand:V8QI 2 "register_operand" "y")]
20457                      UNSPEC_MASKMOV))]
20458   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20459   ;; @@@ check ordering of operands in intel/nonintel syntax
20460   "maskmovq\t{%2, %1|%1, %2}"
20461   [(set_attr "type" "mmxcvt")
20462    (set_attr "mode" "DI")])
20463
20464 (define_insn "mmx_maskmovq_rex"
20465   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20466         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20467                       (match_operand:V8QI 2 "register_operand" "y")]
20468                      UNSPEC_MASKMOV))]
20469   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20470   ;; @@@ check ordering of operands in intel/nonintel syntax
20471   "maskmovq\t{%2, %1|%1, %2}"
20472   [(set_attr "type" "mmxcvt")
20473    (set_attr "mode" "DI")])
20474
20475 (define_insn "sse_movntv4sf"
20476   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20477         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20478                      UNSPEC_MOVNT))]
20479   "TARGET_SSE"
20480   "movntps\t{%1, %0|%0, %1}"
20481   [(set_attr "type" "ssemov")
20482    (set_attr "mode" "V4SF")])
20483
20484 (define_insn "sse_movntdi"
20485   [(set (match_operand:DI 0 "memory_operand" "=m")
20486         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20487                    UNSPEC_MOVNT))]
20488   "TARGET_SSE || TARGET_3DNOW_A"
20489   "movntq\t{%1, %0|%0, %1}"
20490   [(set_attr "type" "mmxmov")
20491    (set_attr "mode" "DI")])
20492
20493 (define_insn "sse_movhlps"
20494   [(set (match_operand:V4SF 0 "register_operand" "=x")
20495         (vec_merge:V4SF
20496          (match_operand:V4SF 1 "register_operand" "0")
20497          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20498                           (parallel [(const_int 2)
20499                                      (const_int 3)
20500                                      (const_int 0)
20501                                      (const_int 1)]))
20502          (const_int 3)))]
20503   "TARGET_SSE"
20504   "movhlps\t{%2, %0|%0, %2}"
20505   [(set_attr "type" "ssecvt")
20506    (set_attr "mode" "V4SF")])
20507
20508 (define_insn "sse_movlhps"
20509   [(set (match_operand:V4SF 0 "register_operand" "=x")
20510         (vec_merge:V4SF
20511          (match_operand:V4SF 1 "register_operand" "0")
20512          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20513                           (parallel [(const_int 2)
20514                                      (const_int 3)
20515                                      (const_int 0)
20516                                      (const_int 1)]))
20517          (const_int 12)))]
20518   "TARGET_SSE"
20519   "movlhps\t{%2, %0|%0, %2}"
20520   [(set_attr "type" "ssecvt")
20521    (set_attr "mode" "V4SF")])
20522
20523 (define_insn "sse_movhps"
20524   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20525         (vec_merge:V4SF
20526          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20527          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20528          (const_int 12)))]
20529   "TARGET_SSE
20530    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20531   "movhps\t{%2, %0|%0, %2}"
20532   [(set_attr "type" "ssecvt")
20533    (set_attr "mode" "V4SF")])
20534
20535 (define_insn "sse_movlps"
20536   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20537         (vec_merge:V4SF
20538          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20539          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20540          (const_int 3)))]
20541   "TARGET_SSE
20542    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20543   "movlps\t{%2, %0|%0, %2}"
20544   [(set_attr "type" "ssecvt")
20545    (set_attr "mode" "V4SF")])
20546
20547 (define_expand "sse_loadss"
20548   [(match_operand:V4SF 0 "register_operand" "")
20549    (match_operand:SF 1 "memory_operand" "")]
20550   "TARGET_SSE"
20551 {
20552   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20553                                CONST0_RTX (V4SFmode)));
20554   DONE;
20555 })
20556
20557 (define_insn "sse_loadss_1"
20558   [(set (match_operand:V4SF 0 "register_operand" "=x")
20559         (vec_merge:V4SF
20560          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20561          (match_operand:V4SF 2 "const0_operand" "X")
20562          (const_int 1)))]
20563   "TARGET_SSE"
20564   "movss\t{%1, %0|%0, %1}"
20565   [(set_attr "type" "ssemov")
20566    (set_attr "mode" "SF")])
20567
20568 (define_insn "sse_movss"
20569   [(set (match_operand:V4SF 0 "register_operand" "=x")
20570         (vec_merge:V4SF
20571          (match_operand:V4SF 1 "register_operand" "0")
20572          (match_operand:V4SF 2 "register_operand" "x")
20573          (const_int 14)))]
20574   "TARGET_SSE"
20575   "movss\t{%2, %0|%0, %2}"
20576   [(set_attr "type" "ssemov")
20577    (set_attr "mode" "SF")])
20578
20579 (define_insn "sse_storess"
20580   [(set (match_operand:SF 0 "memory_operand" "=m")
20581         (vec_select:SF
20582          (match_operand:V4SF 1 "register_operand" "x")
20583          (parallel [(const_int 0)])))]
20584   "TARGET_SSE"
20585   "movss\t{%1, %0|%0, %1}"
20586   [(set_attr "type" "ssemov")
20587    (set_attr "mode" "SF")])
20588
20589 (define_insn "sse_shufps"
20590   [(set (match_operand:V4SF 0 "register_operand" "=x")
20591         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20592                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20593                       (match_operand:SI 3 "immediate_operand" "i")]
20594                      UNSPEC_SHUFFLE))]
20595   "TARGET_SSE"
20596   ;; @@@ check operand order for intel/nonintel syntax
20597   "shufps\t{%3, %2, %0|%0, %2, %3}"
20598   [(set_attr "type" "ssecvt")
20599    (set_attr "mode" "V4SF")])
20600
20601
20602 ;; SSE arithmetic
20603
20604 (define_insn "addv4sf3"
20605   [(set (match_operand:V4SF 0 "register_operand" "=x")
20606         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20607                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20608   "TARGET_SSE"
20609   "addps\t{%2, %0|%0, %2}"
20610   [(set_attr "type" "sseadd")
20611    (set_attr "mode" "V4SF")])
20612
20613 (define_insn "vmaddv4sf3"
20614   [(set (match_operand:V4SF 0 "register_operand" "=x")
20615         (vec_merge:V4SF
20616          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20617                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20618          (match_dup 1)
20619          (const_int 1)))]
20620   "TARGET_SSE"
20621   "addss\t{%2, %0|%0, %2}"
20622   [(set_attr "type" "sseadd")
20623    (set_attr "mode" "SF")])
20624
20625 (define_insn "subv4sf3"
20626   [(set (match_operand:V4SF 0 "register_operand" "=x")
20627         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20628                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20629   "TARGET_SSE"
20630   "subps\t{%2, %0|%0, %2}"
20631   [(set_attr "type" "sseadd")
20632    (set_attr "mode" "V4SF")])
20633
20634 (define_insn "vmsubv4sf3"
20635   [(set (match_operand:V4SF 0 "register_operand" "=x")
20636         (vec_merge:V4SF
20637          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20638                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20639          (match_dup 1)
20640          (const_int 1)))]
20641   "TARGET_SSE"
20642   "subss\t{%2, %0|%0, %2}"
20643   [(set_attr "type" "sseadd")
20644    (set_attr "mode" "SF")])
20645
20646 ;; ??? Should probably be done by generic code instead.
20647 (define_expand "negv4sf2"
20648   [(set (match_operand:V4SF 0 "register_operand" "")
20649         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20650                   (match_dup 2)))]
20651   "TARGET_SSE"
20652 {
20653   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20654   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20655   operands[2] = force_reg (V4SFmode, vm0);
20656 })
20657
20658 (define_insn "mulv4sf3"
20659   [(set (match_operand:V4SF 0 "register_operand" "=x")
20660         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20661                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20662   "TARGET_SSE"
20663   "mulps\t{%2, %0|%0, %2}"
20664   [(set_attr "type" "ssemul")
20665    (set_attr "mode" "V4SF")])
20666
20667 (define_insn "vmmulv4sf3"
20668   [(set (match_operand:V4SF 0 "register_operand" "=x")
20669         (vec_merge:V4SF
20670          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20671                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20672          (match_dup 1)
20673          (const_int 1)))]
20674   "TARGET_SSE"
20675   "mulss\t{%2, %0|%0, %2}"
20676   [(set_attr "type" "ssemul")
20677    (set_attr "mode" "SF")])
20678
20679 (define_insn "divv4sf3"
20680   [(set (match_operand:V4SF 0 "register_operand" "=x")
20681         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20682                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20683   "TARGET_SSE"
20684   "divps\t{%2, %0|%0, %2}"
20685   [(set_attr "type" "ssediv")
20686    (set_attr "mode" "V4SF")])
20687
20688 (define_insn "vmdivv4sf3"
20689   [(set (match_operand:V4SF 0 "register_operand" "=x")
20690         (vec_merge:V4SF
20691          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20692                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20693          (match_dup 1)
20694          (const_int 1)))]
20695   "TARGET_SSE"
20696   "divss\t{%2, %0|%0, %2}"
20697   [(set_attr "type" "ssediv")
20698    (set_attr "mode" "SF")])
20699
20700
20701 ;; SSE square root/reciprocal
20702
20703 (define_insn "rcpv4sf2"
20704   [(set (match_operand:V4SF 0 "register_operand" "=x")
20705         (unspec:V4SF
20706          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20707   "TARGET_SSE"
20708   "rcpps\t{%1, %0|%0, %1}"
20709   [(set_attr "type" "sse")
20710    (set_attr "mode" "V4SF")])
20711
20712 (define_insn "vmrcpv4sf2"
20713   [(set (match_operand:V4SF 0 "register_operand" "=x")
20714         (vec_merge:V4SF
20715          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20716                       UNSPEC_RCP)
20717          (match_operand:V4SF 2 "register_operand" "0")
20718          (const_int 1)))]
20719   "TARGET_SSE"
20720   "rcpss\t{%1, %0|%0, %1}"
20721   [(set_attr "type" "sse")
20722    (set_attr "mode" "SF")])
20723
20724 (define_insn "rsqrtv4sf2"
20725   [(set (match_operand:V4SF 0 "register_operand" "=x")
20726         (unspec:V4SF
20727          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20728   "TARGET_SSE"
20729   "rsqrtps\t{%1, %0|%0, %1}"
20730   [(set_attr "type" "sse")
20731    (set_attr "mode" "V4SF")])
20732
20733 (define_insn "vmrsqrtv4sf2"
20734   [(set (match_operand:V4SF 0 "register_operand" "=x")
20735         (vec_merge:V4SF
20736          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20737                       UNSPEC_RSQRT)
20738          (match_operand:V4SF 2 "register_operand" "0")
20739          (const_int 1)))]
20740   "TARGET_SSE"
20741   "rsqrtss\t{%1, %0|%0, %1}"
20742   [(set_attr "type" "sse")
20743    (set_attr "mode" "SF")])
20744
20745 (define_insn "sqrtv4sf2"
20746   [(set (match_operand:V4SF 0 "register_operand" "=x")
20747         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20748   "TARGET_SSE"
20749   "sqrtps\t{%1, %0|%0, %1}"
20750   [(set_attr "type" "sse")
20751    (set_attr "mode" "V4SF")])
20752
20753 (define_insn "vmsqrtv4sf2"
20754   [(set (match_operand:V4SF 0 "register_operand" "=x")
20755         (vec_merge:V4SF
20756          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20757          (match_operand:V4SF 2 "register_operand" "0")
20758          (const_int 1)))]
20759   "TARGET_SSE"
20760   "sqrtss\t{%1, %0|%0, %1}"
20761   [(set_attr "type" "sse")
20762    (set_attr "mode" "SF")])
20763
20764 ;; SSE logical operations.
20765
20766 ;; SSE defines logical operations on floating point values.  This brings
20767 ;; interesting challenge to RTL representation where logicals are only valid
20768 ;; on integral types.  We deal with this by representing the floating point
20769 ;; logical as logical on arguments casted to TImode as this is what hardware
20770 ;; really does.  Unfortunately hardware requires the type information to be
20771 ;; present and thus we must avoid subregs from being simplified and eliminated
20772 ;; in later compilation phases.
20773 ;;
20774 ;; We have following variants from each instruction:
20775 ;; sse_andsf3 - the operation taking V4SF vector operands
20776 ;;              and doing TImode cast on them
20777 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20778 ;;                      TImode, since backend insist on eliminating casts
20779 ;;                      on memory operands
20780 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20781 ;;                   We cannot accept memory operand here as instruction reads
20782 ;;                   whole scalar.  This is generated only post reload by GCC
20783 ;;                   scalar float operations that expands to logicals (fabs)
20784 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20785 ;;                   memory operand.  Eventually combine can be able
20786 ;;                   to synthesize these using splitter.
20787 ;; sse2_anddf3, *sse2_anddf3_memory
20788 ;;              
20789 ;; 
20790 ;; These are not called andti3 etc. because we really really don't want
20791 ;; the compiler to widen DImode ands to TImode ands and then try to move
20792 ;; into DImode subregs of SSE registers, and them together, and move out
20793 ;; of DImode subregs again!
20794 ;; SSE1 single precision floating point logical operation
20795 (define_expand "sse_andv4sf3"
20796   [(set (match_operand:V4SF 0 "register_operand" "")
20797         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20798                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20799   "TARGET_SSE"
20800   "")
20801
20802 (define_insn "*sse_andv4sf3"
20803   [(set (match_operand:V4SF 0 "register_operand" "=x")
20804         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20805                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20806   "TARGET_SSE
20807    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20808   "andps\t{%2, %0|%0, %2}"
20809   [(set_attr "type" "sselog")
20810    (set_attr "mode" "V4SF")])
20811
20812 (define_expand "sse_nandv4sf3"
20813   [(set (match_operand:V4SF 0 "register_operand" "")
20814         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20815                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20816   "TARGET_SSE"
20817   "")
20818
20819 (define_insn "*sse_nandv4sf3"
20820   [(set (match_operand:V4SF 0 "register_operand" "=x")
20821         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20822                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20823   "TARGET_SSE"
20824   "andnps\t{%2, %0|%0, %2}"
20825   [(set_attr "type" "sselog")
20826    (set_attr "mode" "V4SF")])
20827
20828 (define_expand "sse_iorv4sf3"
20829   [(set (match_operand:V4SF 0 "register_operand" "")
20830         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20831                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20832   "TARGET_SSE"
20833   "")
20834
20835 (define_insn "*sse_iorv4sf3"
20836   [(set (match_operand:V4SF 0 "register_operand" "=x")
20837         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20838                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20839   "TARGET_SSE
20840    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20841   "orps\t{%2, %0|%0, %2}"
20842   [(set_attr "type" "sselog")
20843    (set_attr "mode" "V4SF")])
20844
20845 (define_expand "sse_xorv4sf3"
20846   [(set (match_operand:V4SF 0 "register_operand" "")
20847         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20848                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20849   "TARGET_SSE"
20850   "")
20851
20852 (define_insn "*sse_xorv4sf3"
20853   [(set (match_operand:V4SF 0 "register_operand" "=x")
20854         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20855                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20856   "TARGET_SSE
20857    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20858   "xorps\t{%2, %0|%0, %2}"
20859   [(set_attr "type" "sselog")
20860    (set_attr "mode" "V4SF")])
20861
20862 ;; SSE2 double precision floating point logical operation
20863
20864 (define_expand "sse2_andv2df3"
20865   [(set (match_operand:V2DF 0 "register_operand" "")
20866         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20867                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20868   "TARGET_SSE2"
20869   "")
20870
20871 (define_insn "*sse2_andv2df3"
20872   [(set (match_operand:V2DF 0 "register_operand" "=x")
20873         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20874                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20875   "TARGET_SSE2
20876    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20877   "andpd\t{%2, %0|%0, %2}"
20878   [(set_attr "type" "sselog")
20879    (set_attr "mode" "V2DF")])
20880
20881 (define_expand "sse2_nandv2df3"
20882   [(set (match_operand:V2DF 0 "register_operand" "")
20883         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20884                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20885   "TARGET_SSE2"
20886   "")
20887
20888 (define_insn "*sse2_nandv2df3"
20889   [(set (match_operand:V2DF 0 "register_operand" "=x")
20890         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20891                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20892   "TARGET_SSE2"
20893   "andnpd\t{%2, %0|%0, %2}"
20894   [(set_attr "type" "sselog")
20895    (set_attr "mode" "V2DF")])
20896
20897 (define_expand "sse2_iorv2df3"
20898   [(set (match_operand:V2DF 0 "register_operand" "")
20899         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20900                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20901   "TARGET_SSE2"
20902   "")
20903
20904 (define_insn "*sse2_iorv2df3"
20905   [(set (match_operand:V2DF 0 "register_operand" "=x")
20906         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20907                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20908   "TARGET_SSE2
20909    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20910   "orpd\t{%2, %0|%0, %2}"
20911   [(set_attr "type" "sselog")
20912    (set_attr "mode" "V2DF")])
20913
20914 (define_expand "sse2_xorv2df3"
20915   [(set (match_operand:V2DF 0 "register_operand" "")
20916         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20917                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20918   "TARGET_SSE2"
20919   "")
20920
20921 (define_insn "*sse2_xorv2df3"
20922   [(set (match_operand:V2DF 0 "register_operand" "=x")
20923         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20924                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20925   "TARGET_SSE2
20926    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20927   "xorpd\t{%2, %0|%0, %2}"
20928   [(set_attr "type" "sselog")
20929    (set_attr "mode" "V2DF")])
20930
20931 ;; SSE2 integral logicals.  These patterns must always come after floating
20932 ;; point ones since we don't want compiler to use integer opcodes on floating
20933 ;; point SSE values to avoid matching of subregs in the match_operand.
20934 (define_insn "*sse2_andti3"
20935   [(set (match_operand:TI 0 "register_operand" "=x")
20936         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20937                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20938   "TARGET_SSE2
20939    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20940   "pand\t{%2, %0|%0, %2}"
20941   [(set_attr "type" "sselog")
20942    (set_attr "mode" "TI")])
20943
20944 (define_insn "sse2_andv2di3"
20945   [(set (match_operand:V2DI 0 "register_operand" "=x")
20946         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20947                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20948   "TARGET_SSE2
20949    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20950   "pand\t{%2, %0|%0, %2}"
20951   [(set_attr "type" "sselog")
20952    (set_attr "mode" "TI")])
20953
20954 (define_insn "*sse2_nandti3"
20955   [(set (match_operand:TI 0 "register_operand" "=x")
20956         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20957                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20958   "TARGET_SSE2"
20959   "pandn\t{%2, %0|%0, %2}"
20960   [(set_attr "type" "sselog")
20961    (set_attr "mode" "TI")])
20962
20963 (define_insn "sse2_nandv2di3"
20964   [(set (match_operand:V2DI 0 "register_operand" "=x")
20965         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20966                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20967   "TARGET_SSE2
20968    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20969   "pandn\t{%2, %0|%0, %2}"
20970   [(set_attr "type" "sselog")
20971    (set_attr "mode" "TI")])
20972
20973 (define_insn "*sse2_iorti3"
20974   [(set (match_operand:TI 0 "register_operand" "=x")
20975         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20976                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20977   "TARGET_SSE2
20978    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20979   "por\t{%2, %0|%0, %2}"
20980   [(set_attr "type" "sselog")
20981    (set_attr "mode" "TI")])
20982
20983 (define_insn "sse2_iorv2di3"
20984   [(set (match_operand:V2DI 0 "register_operand" "=x")
20985         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20986                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20987   "TARGET_SSE2
20988    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20989   "por\t{%2, %0|%0, %2}"
20990   [(set_attr "type" "sselog")
20991    (set_attr "mode" "TI")])
20992
20993 (define_insn "*sse2_xorti3"
20994   [(set (match_operand:TI 0 "register_operand" "=x")
20995         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20996                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20997   "TARGET_SSE2
20998    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20999   "pxor\t{%2, %0|%0, %2}"
21000   [(set_attr "type" "sselog")
21001    (set_attr "mode" "TI")])
21002
21003 (define_insn "sse2_xorv2di3"
21004   [(set (match_operand:V2DI 0 "register_operand" "=x")
21005         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21006                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21007   "TARGET_SSE2
21008    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21009   "pxor\t{%2, %0|%0, %2}"
21010   [(set_attr "type" "sselog")
21011    (set_attr "mode" "TI")])
21012
21013 ;; Use xor, but don't show input operands so they aren't live before
21014 ;; this insn.
21015 (define_insn "sse_clrv4sf"
21016   [(set (match_operand:V4SF 0 "register_operand" "=x")
21017         (match_operand:V4SF 1 "const0_operand" "X"))]
21018   "TARGET_SSE"
21019 {
21020   if (get_attr_mode (insn) == MODE_TI)
21021     return "pxor\t{%0, %0|%0, %0}";
21022   else
21023     return "xorps\t{%0, %0|%0, %0}";
21024 }
21025   [(set_attr "type" "sselog")
21026    (set_attr "memory" "none")
21027    (set (attr "mode")
21028         (if_then_else
21029            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21030                          (const_int 0))
21031                      (ne (symbol_ref "TARGET_SSE2")
21032                          (const_int 0)))
21033                 (eq (symbol_ref "optimize_size")
21034                     (const_int 0)))
21035          (const_string "TI")
21036          (const_string "V4SF")))])
21037
21038 ;; Use xor, but don't show input operands so they aren't live before
21039 ;; this insn.
21040 (define_insn "sse_clrv2df"
21041   [(set (match_operand:V2DF 0 "register_operand" "=x")
21042         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21043   "TARGET_SSE2"
21044   "xorpd\t{%0, %0|%0, %0}"
21045   [(set_attr "type" "sselog")
21046    (set_attr "memory" "none")
21047    (set_attr "mode" "V4SF")])
21048
21049 ;; SSE mask-generating compares
21050
21051 (define_insn "maskcmpv4sf3"
21052   [(set (match_operand:V4SI 0 "register_operand" "=x")
21053         (match_operator:V4SI 3 "sse_comparison_operator"
21054                 [(match_operand:V4SF 1 "register_operand" "0")
21055                  (match_operand:V4SF 2 "register_operand" "x")]))]
21056   "TARGET_SSE"
21057   "cmp%D3ps\t{%2, %0|%0, %2}"
21058   [(set_attr "type" "ssecmp")
21059    (set_attr "mode" "V4SF")])
21060
21061 (define_insn "maskncmpv4sf3"
21062   [(set (match_operand:V4SI 0 "register_operand" "=x")
21063         (not:V4SI
21064          (match_operator:V4SI 3 "sse_comparison_operator"
21065                 [(match_operand:V4SF 1 "register_operand" "0")
21066                  (match_operand:V4SF 2 "register_operand" "x")])))]
21067   "TARGET_SSE"
21068 {
21069   if (GET_CODE (operands[3]) == UNORDERED)
21070     return "cmpordps\t{%2, %0|%0, %2}";
21071   else
21072     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21073 }
21074   [(set_attr "type" "ssecmp")
21075    (set_attr "mode" "V4SF")])
21076
21077 (define_insn "vmmaskcmpv4sf3"
21078   [(set (match_operand:V4SI 0 "register_operand" "=x")
21079         (vec_merge:V4SI
21080          (match_operator:V4SI 3 "sse_comparison_operator"
21081                 [(match_operand:V4SF 1 "register_operand" "0")
21082                  (match_operand:V4SF 2 "register_operand" "x")])
21083          (subreg:V4SI (match_dup 1) 0)
21084          (const_int 1)))]
21085   "TARGET_SSE"
21086   "cmp%D3ss\t{%2, %0|%0, %2}"
21087   [(set_attr "type" "ssecmp")
21088    (set_attr "mode" "SF")])
21089
21090 (define_insn "vmmaskncmpv4sf3"
21091   [(set (match_operand:V4SI 0 "register_operand" "=x")
21092         (vec_merge:V4SI
21093          (not:V4SI
21094           (match_operator:V4SI 3 "sse_comparison_operator"
21095                 [(match_operand:V4SF 1 "register_operand" "0")
21096                  (match_operand:V4SF 2 "register_operand" "x")]))
21097          (subreg:V4SI (match_dup 1) 0)
21098          (const_int 1)))]
21099   "TARGET_SSE"
21100 {
21101   if (GET_CODE (operands[3]) == UNORDERED)
21102     return "cmpordss\t{%2, %0|%0, %2}";
21103   else
21104     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21105 }
21106   [(set_attr "type" "ssecmp")
21107    (set_attr "mode" "SF")])
21108
21109 (define_insn "sse_comi"
21110   [(set (reg:CCFP FLAGS_REG)
21111         (compare:CCFP (vec_select:SF
21112                        (match_operand:V4SF 0 "register_operand" "x")
21113                        (parallel [(const_int 0)]))
21114                       (vec_select:SF
21115                        (match_operand:V4SF 1 "register_operand" "x")
21116                        (parallel [(const_int 0)]))))]
21117   "TARGET_SSE"
21118   "comiss\t{%1, %0|%0, %1}"
21119   [(set_attr "type" "ssecomi")
21120    (set_attr "mode" "SF")])
21121
21122 (define_insn "sse_ucomi"
21123   [(set (reg:CCFPU FLAGS_REG)
21124         (compare:CCFPU (vec_select:SF
21125                         (match_operand:V4SF 0 "register_operand" "x")
21126                         (parallel [(const_int 0)]))
21127                        (vec_select:SF
21128                         (match_operand:V4SF 1 "register_operand" "x")
21129                         (parallel [(const_int 0)]))))]
21130   "TARGET_SSE"
21131   "ucomiss\t{%1, %0|%0, %1}"
21132   [(set_attr "type" "ssecomi")
21133    (set_attr "mode" "SF")])
21134
21135
21136 ;; SSE unpack
21137
21138 (define_insn "sse_unpckhps"
21139   [(set (match_operand:V4SF 0 "register_operand" "=x")
21140         (vec_merge:V4SF
21141          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21142                           (parallel [(const_int 2)
21143                                      (const_int 0)
21144                                      (const_int 3)
21145                                      (const_int 1)]))
21146          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21147                           (parallel [(const_int 0)
21148                                      (const_int 2)
21149                                      (const_int 1)
21150                                      (const_int 3)]))
21151          (const_int 5)))]
21152   "TARGET_SSE"
21153   "unpckhps\t{%2, %0|%0, %2}"
21154   [(set_attr "type" "ssecvt")
21155    (set_attr "mode" "V4SF")])
21156
21157 (define_insn "sse_unpcklps"
21158   [(set (match_operand:V4SF 0 "register_operand" "=x")
21159         (vec_merge:V4SF
21160          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21161                           (parallel [(const_int 0)
21162                                      (const_int 2)
21163                                      (const_int 1)
21164                                      (const_int 3)]))
21165          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21166                           (parallel [(const_int 2)
21167                                      (const_int 0)
21168                                      (const_int 3)
21169                                      (const_int 1)]))
21170          (const_int 5)))]
21171   "TARGET_SSE"
21172   "unpcklps\t{%2, %0|%0, %2}"
21173   [(set_attr "type" "ssecvt")
21174    (set_attr "mode" "V4SF")])
21175
21176
21177 ;; SSE min/max
21178
21179 (define_insn "smaxv4sf3"
21180   [(set (match_operand:V4SF 0 "register_operand" "=x")
21181         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21182                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21183   "TARGET_SSE"
21184   "maxps\t{%2, %0|%0, %2}"
21185   [(set_attr "type" "sse")
21186    (set_attr "mode" "V4SF")])
21187
21188 (define_insn "vmsmaxv4sf3"
21189   [(set (match_operand:V4SF 0 "register_operand" "=x")
21190         (vec_merge:V4SF
21191          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21192                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21193          (match_dup 1)
21194          (const_int 1)))]
21195   "TARGET_SSE"
21196   "maxss\t{%2, %0|%0, %2}"
21197   [(set_attr "type" "sse")
21198    (set_attr "mode" "SF")])
21199
21200 (define_insn "sminv4sf3"
21201   [(set (match_operand:V4SF 0 "register_operand" "=x")
21202         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21203                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21204   "TARGET_SSE"
21205   "minps\t{%2, %0|%0, %2}"
21206   [(set_attr "type" "sse")
21207    (set_attr "mode" "V4SF")])
21208
21209 (define_insn "vmsminv4sf3"
21210   [(set (match_operand:V4SF 0 "register_operand" "=x")
21211         (vec_merge:V4SF
21212          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21213                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21214          (match_dup 1)
21215          (const_int 1)))]
21216   "TARGET_SSE"
21217   "minss\t{%2, %0|%0, %2}"
21218   [(set_attr "type" "sse")
21219    (set_attr "mode" "SF")])
21220
21221 ;; SSE <-> integer/MMX conversions
21222
21223 (define_insn "cvtpi2ps"
21224   [(set (match_operand:V4SF 0 "register_operand" "=x")
21225         (vec_merge:V4SF
21226          (match_operand:V4SF 1 "register_operand" "0")
21227          (vec_duplicate:V4SF
21228           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21229          (const_int 12)))]
21230   "TARGET_SSE"
21231   "cvtpi2ps\t{%2, %0|%0, %2}"
21232   [(set_attr "type" "ssecvt")
21233    (set_attr "mode" "V4SF")])
21234
21235 (define_insn "cvtps2pi"
21236   [(set (match_operand:V2SI 0 "register_operand" "=y")
21237         (vec_select:V2SI
21238          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21239          (parallel [(const_int 0) (const_int 1)])))]
21240   "TARGET_SSE"
21241   "cvtps2pi\t{%1, %0|%0, %1}"
21242   [(set_attr "type" "ssecvt")
21243    (set_attr "mode" "V4SF")])
21244
21245 (define_insn "cvttps2pi"
21246   [(set (match_operand:V2SI 0 "register_operand" "=y")
21247         (vec_select:V2SI
21248          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21249                       UNSPEC_FIX)
21250          (parallel [(const_int 0) (const_int 1)])))]
21251   "TARGET_SSE"
21252   "cvttps2pi\t{%1, %0|%0, %1}"
21253   [(set_attr "type" "ssecvt")
21254    (set_attr "mode" "SF")])
21255
21256 (define_insn "cvtsi2ss"
21257   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21258         (vec_merge:V4SF
21259          (match_operand:V4SF 1 "register_operand" "0,0")
21260          (vec_duplicate:V4SF
21261           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21262          (const_int 14)))]
21263   "TARGET_SSE"
21264   "cvtsi2ss\t{%2, %0|%0, %2}"
21265   [(set_attr "type" "sseicvt")
21266    (set_attr "athlon_decode" "vector,double")
21267    (set_attr "mode" "SF")])
21268
21269 (define_insn "cvtsi2ssq"
21270   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21271         (vec_merge:V4SF
21272          (match_operand:V4SF 1 "register_operand" "0,0")
21273          (vec_duplicate:V4SF
21274           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21275          (const_int 14)))]
21276   "TARGET_SSE && TARGET_64BIT"
21277   "cvtsi2ssq\t{%2, %0|%0, %2}"
21278   [(set_attr "type" "sseicvt")
21279    (set_attr "athlon_decode" "vector,double")
21280    (set_attr "mode" "SF")])
21281
21282 (define_insn "cvtss2si"
21283   [(set (match_operand:SI 0 "register_operand" "=r,r")
21284         (vec_select:SI
21285          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21286          (parallel [(const_int 0)])))]
21287   "TARGET_SSE"
21288   "cvtss2si\t{%1, %0|%0, %1}"
21289   [(set_attr "type" "sseicvt")
21290    (set_attr "athlon_decode" "double,vector")
21291    (set_attr "mode" "SI")])
21292
21293 (define_insn "cvtss2siq"
21294   [(set (match_operand:DI 0 "register_operand" "=r,r")
21295         (vec_select:DI
21296          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21297          (parallel [(const_int 0)])))]
21298   "TARGET_SSE"
21299   "cvtss2siq\t{%1, %0|%0, %1}"
21300   [(set_attr "type" "sseicvt")
21301    (set_attr "athlon_decode" "double,vector")
21302    (set_attr "mode" "DI")])
21303
21304 (define_insn "cvttss2si"
21305   [(set (match_operand:SI 0 "register_operand" "=r,r")
21306         (vec_select:SI
21307          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21308                       UNSPEC_FIX)
21309          (parallel [(const_int 0)])))]
21310   "TARGET_SSE"
21311   "cvttss2si\t{%1, %0|%0, %1}"
21312   [(set_attr "type" "sseicvt")
21313    (set_attr "mode" "SF")
21314    (set_attr "athlon_decode" "double,vector")])
21315
21316 (define_insn "cvttss2siq"
21317   [(set (match_operand:DI 0 "register_operand" "=r,r")
21318         (vec_select:DI
21319          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21320                       UNSPEC_FIX)
21321          (parallel [(const_int 0)])))]
21322   "TARGET_SSE && TARGET_64BIT"
21323   "cvttss2siq\t{%1, %0|%0, %1}"
21324   [(set_attr "type" "sseicvt")
21325    (set_attr "mode" "SF")
21326    (set_attr "athlon_decode" "double,vector")])
21327
21328
21329 ;; MMX insns
21330
21331 ;; MMX arithmetic
21332
21333 (define_insn "addv8qi3"
21334   [(set (match_operand:V8QI 0 "register_operand" "=y")
21335         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21336                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21337   "TARGET_MMX"
21338   "paddb\t{%2, %0|%0, %2}"
21339   [(set_attr "type" "mmxadd")
21340    (set_attr "mode" "DI")])
21341
21342 (define_insn "addv4hi3"
21343   [(set (match_operand:V4HI 0 "register_operand" "=y")
21344         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21345                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21346   "TARGET_MMX"
21347   "paddw\t{%2, %0|%0, %2}"
21348   [(set_attr "type" "mmxadd")
21349    (set_attr "mode" "DI")])
21350
21351 (define_insn "addv2si3"
21352   [(set (match_operand:V2SI 0 "register_operand" "=y")
21353         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21354                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21355   "TARGET_MMX"
21356   "paddd\t{%2, %0|%0, %2}"
21357   [(set_attr "type" "mmxadd")
21358    (set_attr "mode" "DI")])
21359
21360 (define_insn "mmx_adddi3"
21361   [(set (match_operand:DI 0 "register_operand" "=y")
21362         (unspec:DI
21363          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21364                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21365          UNSPEC_NOP))]
21366   "TARGET_MMX"
21367   "paddq\t{%2, %0|%0, %2}"
21368   [(set_attr "type" "mmxadd")
21369    (set_attr "mode" "DI")])
21370
21371 (define_insn "ssaddv8qi3"
21372   [(set (match_operand:V8QI 0 "register_operand" "=y")
21373         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21374                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21375   "TARGET_MMX"
21376   "paddsb\t{%2, %0|%0, %2}"
21377   [(set_attr "type" "mmxadd")
21378    (set_attr "mode" "DI")])
21379
21380 (define_insn "ssaddv4hi3"
21381   [(set (match_operand:V4HI 0 "register_operand" "=y")
21382         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21383                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21384   "TARGET_MMX"
21385   "paddsw\t{%2, %0|%0, %2}"
21386   [(set_attr "type" "mmxadd")
21387    (set_attr "mode" "DI")])
21388
21389 (define_insn "usaddv8qi3"
21390   [(set (match_operand:V8QI 0 "register_operand" "=y")
21391         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21392                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21393   "TARGET_MMX"
21394   "paddusb\t{%2, %0|%0, %2}"
21395   [(set_attr "type" "mmxadd")
21396    (set_attr "mode" "DI")])
21397
21398 (define_insn "usaddv4hi3"
21399   [(set (match_operand:V4HI 0 "register_operand" "=y")
21400         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21401                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21402   "TARGET_MMX"
21403   "paddusw\t{%2, %0|%0, %2}"
21404   [(set_attr "type" "mmxadd")
21405    (set_attr "mode" "DI")])
21406
21407 (define_insn "subv8qi3"
21408   [(set (match_operand:V8QI 0 "register_operand" "=y")
21409         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21410                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21411   "TARGET_MMX"
21412   "psubb\t{%2, %0|%0, %2}"
21413   [(set_attr "type" "mmxadd")
21414    (set_attr "mode" "DI")])
21415
21416 (define_insn "subv4hi3"
21417   [(set (match_operand:V4HI 0 "register_operand" "=y")
21418         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21419                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21420   "TARGET_MMX"
21421   "psubw\t{%2, %0|%0, %2}"
21422   [(set_attr "type" "mmxadd")
21423    (set_attr "mode" "DI")])
21424
21425 (define_insn "subv2si3"
21426   [(set (match_operand:V2SI 0 "register_operand" "=y")
21427         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21428                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21429   "TARGET_MMX"
21430   "psubd\t{%2, %0|%0, %2}"
21431   [(set_attr "type" "mmxadd")
21432    (set_attr "mode" "DI")])
21433
21434 (define_insn "mmx_subdi3"
21435   [(set (match_operand:DI 0 "register_operand" "=y")
21436         (unspec:DI
21437          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21438                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21439          UNSPEC_NOP))]
21440   "TARGET_MMX"
21441   "psubq\t{%2, %0|%0, %2}"
21442   [(set_attr "type" "mmxadd")
21443    (set_attr "mode" "DI")])
21444
21445 (define_insn "sssubv8qi3"
21446   [(set (match_operand:V8QI 0 "register_operand" "=y")
21447         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21448                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21449   "TARGET_MMX"
21450   "psubsb\t{%2, %0|%0, %2}"
21451   [(set_attr "type" "mmxadd")
21452    (set_attr "mode" "DI")])
21453
21454 (define_insn "sssubv4hi3"
21455   [(set (match_operand:V4HI 0 "register_operand" "=y")
21456         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21457                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21458   "TARGET_MMX"
21459   "psubsw\t{%2, %0|%0, %2}"
21460   [(set_attr "type" "mmxadd")
21461    (set_attr "mode" "DI")])
21462
21463 (define_insn "ussubv8qi3"
21464   [(set (match_operand:V8QI 0 "register_operand" "=y")
21465         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21466                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21467   "TARGET_MMX"
21468   "psubusb\t{%2, %0|%0, %2}"
21469   [(set_attr "type" "mmxadd")
21470    (set_attr "mode" "DI")])
21471
21472 (define_insn "ussubv4hi3"
21473   [(set (match_operand:V4HI 0 "register_operand" "=y")
21474         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21475                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21476   "TARGET_MMX"
21477   "psubusw\t{%2, %0|%0, %2}"
21478   [(set_attr "type" "mmxadd")
21479    (set_attr "mode" "DI")])
21480
21481 (define_insn "mulv4hi3"
21482   [(set (match_operand:V4HI 0 "register_operand" "=y")
21483         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21484                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21485   "TARGET_MMX"
21486   "pmullw\t{%2, %0|%0, %2}"
21487   [(set_attr "type" "mmxmul")
21488    (set_attr "mode" "DI")])
21489
21490 (define_insn "smulv4hi3_highpart"
21491   [(set (match_operand:V4HI 0 "register_operand" "=y")
21492         (truncate:V4HI
21493          (lshiftrt:V4SI
21494           (mult:V4SI (sign_extend:V4SI
21495                       (match_operand:V4HI 1 "register_operand" "0"))
21496                      (sign_extend:V4SI
21497                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21498           (const_int 16))))]
21499   "TARGET_MMX"
21500   "pmulhw\t{%2, %0|%0, %2}"
21501   [(set_attr "type" "mmxmul")
21502    (set_attr "mode" "DI")])
21503
21504 (define_insn "umulv4hi3_highpart"
21505   [(set (match_operand:V4HI 0 "register_operand" "=y")
21506         (truncate:V4HI
21507          (lshiftrt:V4SI
21508           (mult:V4SI (zero_extend:V4SI
21509                       (match_operand:V4HI 1 "register_operand" "0"))
21510                      (zero_extend:V4SI
21511                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21512           (const_int 16))))]
21513   "TARGET_SSE || TARGET_3DNOW_A"
21514   "pmulhuw\t{%2, %0|%0, %2}"
21515   [(set_attr "type" "mmxmul")
21516    (set_attr "mode" "DI")])
21517
21518 (define_insn "mmx_pmaddwd"
21519   [(set (match_operand:V2SI 0 "register_operand" "=y")
21520         (plus:V2SI
21521          (mult:V2SI
21522           (sign_extend:V2SI
21523            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21524                             (parallel [(const_int 0) (const_int 2)])))
21525           (sign_extend:V2SI
21526            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21527                             (parallel [(const_int 0) (const_int 2)]))))
21528          (mult:V2SI
21529           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21530                                              (parallel [(const_int 1)
21531                                                         (const_int 3)])))
21532           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21533                                              (parallel [(const_int 1)
21534                                                         (const_int 3)]))))))]
21535   "TARGET_MMX"
21536   "pmaddwd\t{%2, %0|%0, %2}"
21537   [(set_attr "type" "mmxmul")
21538    (set_attr "mode" "DI")])
21539
21540
21541 ;; MMX logical operations
21542 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21543 ;; normal code that also wants to use the FPU from getting broken.
21544 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21545 (define_insn "mmx_iordi3"
21546   [(set (match_operand:DI 0 "register_operand" "=y")
21547         (unspec:DI
21548          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21549                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21550          UNSPEC_NOP))]
21551   "TARGET_MMX"
21552   "por\t{%2, %0|%0, %2}"
21553   [(set_attr "type" "mmxadd")
21554    (set_attr "mode" "DI")])
21555
21556 (define_insn "mmx_xordi3"
21557   [(set (match_operand:DI 0 "register_operand" "=y")
21558         (unspec:DI
21559          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21560                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21561          UNSPEC_NOP))]
21562   "TARGET_MMX"
21563   "pxor\t{%2, %0|%0, %2}"
21564   [(set_attr "type" "mmxadd")
21565    (set_attr "mode" "DI")
21566    (set_attr "memory" "none")])
21567
21568 ;; Same as pxor, but don't show input operands so that we don't think
21569 ;; they are live.
21570 (define_insn "mmx_clrdi"
21571   [(set (match_operand:DI 0 "register_operand" "=y")
21572         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21573   "TARGET_MMX"
21574   "pxor\t{%0, %0|%0, %0}"
21575   [(set_attr "type" "mmxadd")
21576    (set_attr "mode" "DI")
21577    (set_attr "memory" "none")])
21578
21579 (define_insn "mmx_anddi3"
21580   [(set (match_operand:DI 0 "register_operand" "=y")
21581         (unspec:DI
21582          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21583                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21584          UNSPEC_NOP))]
21585   "TARGET_MMX"
21586   "pand\t{%2, %0|%0, %2}"
21587   [(set_attr "type" "mmxadd")
21588    (set_attr "mode" "DI")])
21589
21590 (define_insn "mmx_nanddi3"
21591   [(set (match_operand:DI 0 "register_operand" "=y")
21592         (unspec:DI
21593          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21594                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21595          UNSPEC_NOP))]
21596   "TARGET_MMX"
21597   "pandn\t{%2, %0|%0, %2}"
21598   [(set_attr "type" "mmxadd")
21599    (set_attr "mode" "DI")])
21600
21601
21602 ;; MMX unsigned averages/sum of absolute differences
21603
21604 (define_insn "mmx_uavgv8qi3"
21605   [(set (match_operand:V8QI 0 "register_operand" "=y")
21606         (ashiftrt:V8QI
21607          (plus:V8QI (plus:V8QI
21608                      (match_operand:V8QI 1 "register_operand" "0")
21609                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21610                     (const_vector:V8QI [(const_int 1)
21611                                         (const_int 1)
21612                                         (const_int 1)
21613                                         (const_int 1)
21614                                         (const_int 1)
21615                                         (const_int 1)
21616                                         (const_int 1)
21617                                         (const_int 1)]))
21618          (const_int 1)))]
21619   "TARGET_SSE || TARGET_3DNOW_A"
21620   "pavgb\t{%2, %0|%0, %2}"
21621   [(set_attr "type" "mmxshft")
21622    (set_attr "mode" "DI")])
21623
21624 (define_insn "mmx_uavgv4hi3"
21625   [(set (match_operand:V4HI 0 "register_operand" "=y")
21626         (ashiftrt:V4HI
21627          (plus:V4HI (plus:V4HI
21628                      (match_operand:V4HI 1 "register_operand" "0")
21629                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21630                     (const_vector:V4HI [(const_int 1)
21631                                         (const_int 1)
21632                                         (const_int 1)
21633                                         (const_int 1)]))
21634          (const_int 1)))]
21635   "TARGET_SSE || TARGET_3DNOW_A"
21636   "pavgw\t{%2, %0|%0, %2}"
21637   [(set_attr "type" "mmxshft")
21638    (set_attr "mode" "DI")])
21639
21640 (define_insn "mmx_psadbw"
21641   [(set (match_operand:DI 0 "register_operand" "=y")
21642         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21643                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21644                    UNSPEC_PSADBW))]
21645   "TARGET_SSE || TARGET_3DNOW_A"
21646   "psadbw\t{%2, %0|%0, %2}"
21647   [(set_attr "type" "mmxshft")
21648    (set_attr "mode" "DI")])
21649
21650
21651 ;; MMX insert/extract/shuffle
21652
21653 (define_insn "mmx_pinsrw"
21654   [(set (match_operand:V4HI 0 "register_operand" "=y")
21655         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21656                         (vec_duplicate:V4HI
21657                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21658                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21659   "TARGET_SSE || TARGET_3DNOW_A"
21660   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21661   [(set_attr "type" "mmxcvt")
21662    (set_attr "mode" "DI")])
21663
21664 (define_insn "mmx_pextrw"
21665   [(set (match_operand:SI 0 "register_operand" "=r")
21666         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21667                                        (parallel
21668                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21669   "TARGET_SSE || TARGET_3DNOW_A"
21670   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21671   [(set_attr "type" "mmxcvt")
21672    (set_attr "mode" "DI")])
21673
21674 (define_insn "mmx_pshufw"
21675   [(set (match_operand:V4HI 0 "register_operand" "=y")
21676         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21677                       (match_operand:SI 2 "immediate_operand" "i")]
21678                      UNSPEC_SHUFFLE))]
21679   "TARGET_SSE || TARGET_3DNOW_A"
21680   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21681   [(set_attr "type" "mmxcvt")
21682    (set_attr "mode" "DI")])
21683
21684
21685 ;; MMX mask-generating comparisons
21686
21687 (define_insn "eqv8qi3"
21688   [(set (match_operand:V8QI 0 "register_operand" "=y")
21689         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21690                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21691   "TARGET_MMX"
21692   "pcmpeqb\t{%2, %0|%0, %2}"
21693   [(set_attr "type" "mmxcmp")
21694    (set_attr "mode" "DI")])
21695
21696 (define_insn "eqv4hi3"
21697   [(set (match_operand:V4HI 0 "register_operand" "=y")
21698         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21699                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21700   "TARGET_MMX"
21701   "pcmpeqw\t{%2, %0|%0, %2}"
21702   [(set_attr "type" "mmxcmp")
21703    (set_attr "mode" "DI")])
21704
21705 (define_insn "eqv2si3"
21706   [(set (match_operand:V2SI 0 "register_operand" "=y")
21707         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21708                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21709   "TARGET_MMX"
21710   "pcmpeqd\t{%2, %0|%0, %2}"
21711   [(set_attr "type" "mmxcmp")
21712    (set_attr "mode" "DI")])
21713
21714 (define_insn "gtv8qi3"
21715   [(set (match_operand:V8QI 0 "register_operand" "=y")
21716         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21717                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21718   "TARGET_MMX"
21719   "pcmpgtb\t{%2, %0|%0, %2}"
21720   [(set_attr "type" "mmxcmp")
21721    (set_attr "mode" "DI")])
21722
21723 (define_insn "gtv4hi3"
21724   [(set (match_operand:V4HI 0 "register_operand" "=y")
21725         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21726                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21727   "TARGET_MMX"
21728   "pcmpgtw\t{%2, %0|%0, %2}"
21729   [(set_attr "type" "mmxcmp")
21730    (set_attr "mode" "DI")])
21731
21732 (define_insn "gtv2si3"
21733   [(set (match_operand:V2SI 0 "register_operand" "=y")
21734         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21735                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21736   "TARGET_MMX"
21737   "pcmpgtd\t{%2, %0|%0, %2}"
21738   [(set_attr "type" "mmxcmp")
21739    (set_attr "mode" "DI")])
21740
21741
21742 ;; MMX max/min insns
21743
21744 (define_insn "umaxv8qi3"
21745   [(set (match_operand:V8QI 0 "register_operand" "=y")
21746         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21747                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21748   "TARGET_SSE || TARGET_3DNOW_A"
21749   "pmaxub\t{%2, %0|%0, %2}"
21750   [(set_attr "type" "mmxadd")
21751    (set_attr "mode" "DI")])
21752
21753 (define_insn "smaxv4hi3"
21754   [(set (match_operand:V4HI 0 "register_operand" "=y")
21755         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21756                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21757   "TARGET_SSE || TARGET_3DNOW_A"
21758   "pmaxsw\t{%2, %0|%0, %2}"
21759   [(set_attr "type" "mmxadd")
21760    (set_attr "mode" "DI")])
21761
21762 (define_insn "uminv8qi3"
21763   [(set (match_operand:V8QI 0 "register_operand" "=y")
21764         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21765                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21766   "TARGET_SSE || TARGET_3DNOW_A"
21767   "pminub\t{%2, %0|%0, %2}"
21768   [(set_attr "type" "mmxadd")
21769    (set_attr "mode" "DI")])
21770
21771 (define_insn "sminv4hi3"
21772   [(set (match_operand:V4HI 0 "register_operand" "=y")
21773         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21774                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21775   "TARGET_SSE || TARGET_3DNOW_A"
21776   "pminsw\t{%2, %0|%0, %2}"
21777   [(set_attr "type" "mmxadd")
21778    (set_attr "mode" "DI")])
21779
21780
21781 ;; MMX shifts
21782
21783 (define_insn "ashrv4hi3"
21784   [(set (match_operand:V4HI 0 "register_operand" "=y")
21785         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21786                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21787   "TARGET_MMX"
21788   "psraw\t{%2, %0|%0, %2}"
21789   [(set_attr "type" "mmxshft")
21790    (set_attr "mode" "DI")])
21791
21792 (define_insn "ashrv2si3"
21793   [(set (match_operand:V2SI 0 "register_operand" "=y")
21794         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21795                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21796   "TARGET_MMX"
21797   "psrad\t{%2, %0|%0, %2}"
21798   [(set_attr "type" "mmxshft")
21799    (set_attr "mode" "DI")])
21800
21801 (define_insn "lshrv4hi3"
21802   [(set (match_operand:V4HI 0 "register_operand" "=y")
21803         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21804                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21805   "TARGET_MMX"
21806   "psrlw\t{%2, %0|%0, %2}"
21807   [(set_attr "type" "mmxshft")
21808    (set_attr "mode" "DI")])
21809
21810 (define_insn "lshrv2si3"
21811   [(set (match_operand:V2SI 0 "register_operand" "=y")
21812         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21813                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21814   "TARGET_MMX"
21815   "psrld\t{%2, %0|%0, %2}"
21816   [(set_attr "type" "mmxshft")
21817    (set_attr "mode" "DI")])
21818
21819 ;; See logical MMX insns.
21820 (define_insn "mmx_lshrdi3"
21821   [(set (match_operand:DI 0 "register_operand" "=y")
21822         (unspec:DI
21823           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21824                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21825           UNSPEC_NOP))]
21826   "TARGET_MMX"
21827   "psrlq\t{%2, %0|%0, %2}"
21828   [(set_attr "type" "mmxshft")
21829    (set_attr "mode" "DI")])
21830
21831 (define_insn "ashlv4hi3"
21832   [(set (match_operand:V4HI 0 "register_operand" "=y")
21833         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21834                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21835   "TARGET_MMX"
21836   "psllw\t{%2, %0|%0, %2}"
21837   [(set_attr "type" "mmxshft")
21838    (set_attr "mode" "DI")])
21839
21840 (define_insn "ashlv2si3"
21841   [(set (match_operand:V2SI 0 "register_operand" "=y")
21842         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21843                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21844   "TARGET_MMX"
21845   "pslld\t{%2, %0|%0, %2}"
21846   [(set_attr "type" "mmxshft")
21847    (set_attr "mode" "DI")])
21848
21849 ;; See logical MMX insns.
21850 (define_insn "mmx_ashldi3"
21851   [(set (match_operand:DI 0 "register_operand" "=y")
21852         (unspec:DI
21853          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21854                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21855          UNSPEC_NOP))]
21856   "TARGET_MMX"
21857   "psllq\t{%2, %0|%0, %2}"
21858   [(set_attr "type" "mmxshft")
21859    (set_attr "mode" "DI")])
21860
21861
21862 ;; MMX pack/unpack insns.
21863
21864 (define_insn "mmx_packsswb"
21865   [(set (match_operand:V8QI 0 "register_operand" "=y")
21866         (vec_concat:V8QI
21867          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21868          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21869   "TARGET_MMX"
21870   "packsswb\t{%2, %0|%0, %2}"
21871   [(set_attr "type" "mmxshft")
21872    (set_attr "mode" "DI")])
21873
21874 (define_insn "mmx_packssdw"
21875   [(set (match_operand:V4HI 0 "register_operand" "=y")
21876         (vec_concat:V4HI
21877          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21878          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21879   "TARGET_MMX"
21880   "packssdw\t{%2, %0|%0, %2}"
21881   [(set_attr "type" "mmxshft")
21882    (set_attr "mode" "DI")])
21883
21884 (define_insn "mmx_packuswb"
21885   [(set (match_operand:V8QI 0 "register_operand" "=y")
21886         (vec_concat:V8QI
21887          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21888          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21889   "TARGET_MMX"
21890   "packuswb\t{%2, %0|%0, %2}"
21891   [(set_attr "type" "mmxshft")
21892    (set_attr "mode" "DI")])
21893
21894 (define_insn "mmx_punpckhbw"
21895   [(set (match_operand:V8QI 0 "register_operand" "=y")
21896         (vec_merge:V8QI
21897          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21898                           (parallel [(const_int 4)
21899                                      (const_int 0)
21900                                      (const_int 5)
21901                                      (const_int 1)
21902                                      (const_int 6)
21903                                      (const_int 2)
21904                                      (const_int 7)
21905                                      (const_int 3)]))
21906          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21907                           (parallel [(const_int 0)
21908                                      (const_int 4)
21909                                      (const_int 1)
21910                                      (const_int 5)
21911                                      (const_int 2)
21912                                      (const_int 6)
21913                                      (const_int 3)
21914                                      (const_int 7)]))
21915          (const_int 85)))]
21916   "TARGET_MMX"
21917   "punpckhbw\t{%2, %0|%0, %2}"
21918   [(set_attr "type" "mmxcvt")
21919    (set_attr "mode" "DI")])
21920
21921 (define_insn "mmx_punpckhwd"
21922   [(set (match_operand:V4HI 0 "register_operand" "=y")
21923         (vec_merge:V4HI
21924          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21925                           (parallel [(const_int 0)
21926                                      (const_int 2)
21927                                      (const_int 1)
21928                                      (const_int 3)]))
21929          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21930                           (parallel [(const_int 2)
21931                                      (const_int 0)
21932                                      (const_int 3)
21933                                      (const_int 1)]))
21934          (const_int 5)))]
21935   "TARGET_MMX"
21936   "punpckhwd\t{%2, %0|%0, %2}"
21937   [(set_attr "type" "mmxcvt")
21938    (set_attr "mode" "DI")])
21939
21940 (define_insn "mmx_punpckhdq"
21941   [(set (match_operand:V2SI 0 "register_operand" "=y")
21942         (vec_merge:V2SI
21943          (match_operand:V2SI 1 "register_operand" "0")
21944          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21945                           (parallel [(const_int 1)
21946                                      (const_int 0)]))
21947          (const_int 1)))]
21948   "TARGET_MMX"
21949   "punpckhdq\t{%2, %0|%0, %2}"
21950   [(set_attr "type" "mmxcvt")
21951    (set_attr "mode" "DI")])
21952
21953 (define_insn "mmx_punpcklbw"
21954   [(set (match_operand:V8QI 0 "register_operand" "=y")
21955         (vec_merge:V8QI
21956          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21957                           (parallel [(const_int 0)
21958                                      (const_int 4)
21959                                      (const_int 1)
21960                                      (const_int 5)
21961                                      (const_int 2)
21962                                      (const_int 6)
21963                                      (const_int 3)
21964                                      (const_int 7)]))
21965          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21966                           (parallel [(const_int 4)
21967                                      (const_int 0)
21968                                      (const_int 5)
21969                                      (const_int 1)
21970                                      (const_int 6)
21971                                      (const_int 2)
21972                                      (const_int 7)
21973                                      (const_int 3)]))
21974          (const_int 85)))]
21975   "TARGET_MMX"
21976   "punpcklbw\t{%2, %0|%0, %2}"
21977   [(set_attr "type" "mmxcvt")
21978    (set_attr "mode" "DI")])
21979
21980 (define_insn "mmx_punpcklwd"
21981   [(set (match_operand:V4HI 0 "register_operand" "=y")
21982         (vec_merge:V4HI
21983          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21984                           (parallel [(const_int 2)
21985                                      (const_int 0)
21986                                      (const_int 3)
21987                                      (const_int 1)]))
21988          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21989                           (parallel [(const_int 0)
21990                                      (const_int 2)
21991                                      (const_int 1)
21992                                      (const_int 3)]))
21993          (const_int 5)))]
21994   "TARGET_MMX"
21995   "punpcklwd\t{%2, %0|%0, %2}"
21996   [(set_attr "type" "mmxcvt")
21997    (set_attr "mode" "DI")])
21998
21999 (define_insn "mmx_punpckldq"
22000   [(set (match_operand:V2SI 0 "register_operand" "=y")
22001         (vec_merge:V2SI
22002          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22003                            (parallel [(const_int 1)
22004                                       (const_int 0)]))
22005          (match_operand:V2SI 2 "register_operand" "y")
22006          (const_int 1)))]
22007   "TARGET_MMX"
22008   "punpckldq\t{%2, %0|%0, %2}"
22009   [(set_attr "type" "mmxcvt")
22010    (set_attr "mode" "DI")])
22011
22012
22013 ;; Miscellaneous stuff
22014
22015 (define_insn "emms"
22016   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22017    (clobber (reg:XF 8))
22018    (clobber (reg:XF 9))
22019    (clobber (reg:XF 10))
22020    (clobber (reg:XF 11))
22021    (clobber (reg:XF 12))
22022    (clobber (reg:XF 13))
22023    (clobber (reg:XF 14))
22024    (clobber (reg:XF 15))
22025    (clobber (reg:DI 29))
22026    (clobber (reg:DI 30))
22027    (clobber (reg:DI 31))
22028    (clobber (reg:DI 32))
22029    (clobber (reg:DI 33))
22030    (clobber (reg:DI 34))
22031    (clobber (reg:DI 35))
22032    (clobber (reg:DI 36))]
22033   "TARGET_MMX"
22034   "emms"
22035   [(set_attr "type" "mmx")
22036    (set_attr "memory" "unknown")])
22037
22038 (define_insn "ldmxcsr"
22039   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22040                     UNSPECV_LDMXCSR)]
22041   "TARGET_SSE"
22042   "ldmxcsr\t%0"
22043   [(set_attr "type" "sse")
22044    (set_attr "memory" "load")])
22045
22046 (define_insn "stmxcsr"
22047   [(set (match_operand:SI 0 "memory_operand" "=m")
22048         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22049   "TARGET_SSE"
22050   "stmxcsr\t%0"
22051   [(set_attr "type" "sse")
22052    (set_attr "memory" "store")])
22053
22054 (define_expand "sfence"
22055   [(set (match_dup 0)
22056         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22057   "TARGET_SSE || TARGET_3DNOW_A"
22058 {
22059   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22060   MEM_VOLATILE_P (operands[0]) = 1;
22061 })
22062
22063 (define_insn "*sfence_insn"
22064   [(set (match_operand:BLK 0 "" "")
22065         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22066   "TARGET_SSE || TARGET_3DNOW_A"
22067   "sfence"
22068   [(set_attr "type" "sse")
22069    (set_attr "memory" "unknown")])
22070
22071 (define_expand "sse_prologue_save"
22072   [(parallel [(set (match_operand:BLK 0 "" "")
22073                    (unspec:BLK [(reg:DI 21)
22074                                 (reg:DI 22)
22075                                 (reg:DI 23)
22076                                 (reg:DI 24)
22077                                 (reg:DI 25)
22078                                 (reg:DI 26)
22079                                 (reg:DI 27)
22080                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22081               (use (match_operand:DI 1 "register_operand" ""))
22082               (use (match_operand:DI 2 "immediate_operand" ""))
22083               (use (label_ref:DI (match_operand 3 "" "")))])]
22084   "TARGET_64BIT"
22085   "")
22086
22087 (define_insn "*sse_prologue_save_insn"
22088   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22089                           (match_operand:DI 4 "const_int_operand" "n")))
22090         (unspec:BLK [(reg:DI 21)
22091                      (reg:DI 22)
22092                      (reg:DI 23)
22093                      (reg:DI 24)
22094                      (reg:DI 25)
22095                      (reg:DI 26)
22096                      (reg:DI 27)
22097                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22098    (use (match_operand:DI 1 "register_operand" "r"))
22099    (use (match_operand:DI 2 "const_int_operand" "i"))
22100    (use (label_ref:DI (match_operand 3 "" "X")))]
22101   "TARGET_64BIT
22102    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22103    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22104   "*
22105 {
22106   int i;
22107   operands[0] = gen_rtx_MEM (Pmode,
22108                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22109   output_asm_insn (\"jmp\\t%A1\", operands);
22110   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22111     {
22112       operands[4] = adjust_address (operands[0], DImode, i*16);
22113       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22114       PUT_MODE (operands[4], TImode);
22115       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22116         output_asm_insn (\"rex\", operands);
22117       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22118     }
22119   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22120                              CODE_LABEL_NUMBER (operands[3]));
22121   RET;
22122 }
22123   "
22124   [(set_attr "type" "other")
22125    (set_attr "length_immediate" "0")
22126    (set_attr "length_address" "0")
22127    (set_attr "length" "135")
22128    (set_attr "memory" "store")
22129    (set_attr "modrm" "0")
22130    (set_attr "mode" "DI")])
22131
22132 ;; 3Dnow! instructions
22133
22134 (define_insn "addv2sf3"
22135   [(set (match_operand:V2SF 0 "register_operand" "=y")
22136         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22137                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22138   "TARGET_3DNOW"
22139   "pfadd\\t{%2, %0|%0, %2}"
22140   [(set_attr "type" "mmxadd")
22141    (set_attr "mode" "V2SF")])
22142
22143 (define_insn "subv2sf3"
22144   [(set (match_operand:V2SF 0 "register_operand" "=y")
22145         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22146                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22147   "TARGET_3DNOW"
22148   "pfsub\\t{%2, %0|%0, %2}"
22149   [(set_attr "type" "mmxadd")
22150    (set_attr "mode" "V2SF")])
22151
22152 (define_insn "subrv2sf3"
22153   [(set (match_operand:V2SF 0 "register_operand" "=y")
22154         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22155                     (match_operand:V2SF 1 "register_operand" "0")))]
22156   "TARGET_3DNOW"
22157   "pfsubr\\t{%2, %0|%0, %2}"
22158   [(set_attr "type" "mmxadd")
22159    (set_attr "mode" "V2SF")])
22160
22161 (define_insn "gtv2sf3"
22162   [(set (match_operand:V2SI 0 "register_operand" "=y")
22163         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22164                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22165  "TARGET_3DNOW"
22166   "pfcmpgt\\t{%2, %0|%0, %2}"
22167   [(set_attr "type" "mmxcmp")
22168    (set_attr "mode" "V2SF")])
22169
22170 (define_insn "gev2sf3"
22171   [(set (match_operand:V2SI 0 "register_operand" "=y")
22172         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22173                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22174   "TARGET_3DNOW"
22175   "pfcmpge\\t{%2, %0|%0, %2}"
22176   [(set_attr "type" "mmxcmp")
22177    (set_attr "mode" "V2SF")])
22178
22179 (define_insn "eqv2sf3"
22180   [(set (match_operand:V2SI 0 "register_operand" "=y")
22181         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22182                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22183   "TARGET_3DNOW"
22184   "pfcmpeq\\t{%2, %0|%0, %2}"
22185   [(set_attr "type" "mmxcmp")
22186    (set_attr "mode" "V2SF")])
22187
22188 (define_insn "pfmaxv2sf3"
22189   [(set (match_operand:V2SF 0 "register_operand" "=y")
22190         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22191                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22192   "TARGET_3DNOW"
22193   "pfmax\\t{%2, %0|%0, %2}"
22194   [(set_attr "type" "mmxadd")
22195    (set_attr "mode" "V2SF")])
22196
22197 (define_insn "pfminv2sf3"
22198   [(set (match_operand:V2SF 0 "register_operand" "=y")
22199         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22200                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22201   "TARGET_3DNOW"
22202   "pfmin\\t{%2, %0|%0, %2}"
22203   [(set_attr "type" "mmxadd")
22204    (set_attr "mode" "V2SF")])
22205
22206 (define_insn "mulv2sf3"
22207   [(set (match_operand:V2SF 0 "register_operand" "=y")
22208         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22209                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22210   "TARGET_3DNOW"
22211   "pfmul\\t{%2, %0|%0, %2}"
22212   [(set_attr "type" "mmxmul")
22213    (set_attr "mode" "V2SF")])
22214
22215 (define_insn "femms"
22216   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22217    (clobber (reg:XF 8))
22218    (clobber (reg:XF 9))
22219    (clobber (reg:XF 10))
22220    (clobber (reg:XF 11))
22221    (clobber (reg:XF 12))
22222    (clobber (reg:XF 13))
22223    (clobber (reg:XF 14))
22224    (clobber (reg:XF 15))
22225    (clobber (reg:DI 29))
22226    (clobber (reg:DI 30))
22227    (clobber (reg:DI 31))
22228    (clobber (reg:DI 32))
22229    (clobber (reg:DI 33))
22230    (clobber (reg:DI 34))
22231    (clobber (reg:DI 35))
22232    (clobber (reg:DI 36))]
22233   "TARGET_3DNOW"
22234   "femms"
22235   [(set_attr "type" "mmx")
22236    (set_attr "memory" "none")]) 
22237
22238 (define_insn "pf2id"
22239   [(set (match_operand:V2SI 0 "register_operand" "=y")
22240         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22241   "TARGET_3DNOW"
22242   "pf2id\\t{%1, %0|%0, %1}"
22243   [(set_attr "type" "mmxcvt")
22244    (set_attr "mode" "V2SF")])
22245
22246 (define_insn "pf2iw"
22247   [(set (match_operand:V2SI 0 "register_operand" "=y")
22248         (sign_extend:V2SI
22249            (ss_truncate:V2HI
22250               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22251   "TARGET_3DNOW_A"
22252   "pf2iw\\t{%1, %0|%0, %1}"
22253   [(set_attr "type" "mmxcvt")
22254    (set_attr "mode" "V2SF")])
22255
22256 (define_insn "pfacc"
22257   [(set (match_operand:V2SF 0 "register_operand" "=y")
22258         (vec_concat:V2SF
22259            (plus:SF
22260               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22261                              (parallel [(const_int  0)]))
22262               (vec_select:SF (match_dup 1)
22263                              (parallel [(const_int 1)])))
22264            (plus:SF
22265               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22266                              (parallel [(const_int  0)]))
22267               (vec_select:SF (match_dup 2)
22268                              (parallel [(const_int 1)])))))]
22269   "TARGET_3DNOW"
22270   "pfacc\\t{%2, %0|%0, %2}"
22271   [(set_attr "type" "mmxadd")
22272    (set_attr "mode" "V2SF")])
22273
22274 (define_insn "pfnacc"
22275   [(set (match_operand:V2SF 0 "register_operand" "=y")
22276         (vec_concat:V2SF
22277            (minus:SF
22278               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22279                              (parallel [(const_int 0)]))
22280               (vec_select:SF (match_dup 1)
22281                              (parallel [(const_int 1)])))
22282            (minus:SF
22283               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22284                              (parallel [(const_int  0)]))
22285               (vec_select:SF (match_dup 2)
22286                              (parallel [(const_int 1)])))))]
22287   "TARGET_3DNOW_A"
22288   "pfnacc\\t{%2, %0|%0, %2}"
22289   [(set_attr "type" "mmxadd")
22290    (set_attr "mode" "V2SF")])
22291
22292 (define_insn "pfpnacc"
22293   [(set (match_operand:V2SF 0 "register_operand" "=y")
22294         (vec_concat:V2SF
22295            (minus:SF
22296               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22297                              (parallel [(const_int 0)]))
22298               (vec_select:SF (match_dup 1)
22299                              (parallel [(const_int 1)])))
22300            (plus:SF
22301               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22302                              (parallel [(const_int 0)]))
22303               (vec_select:SF (match_dup 2)
22304                              (parallel [(const_int 1)])))))]
22305   "TARGET_3DNOW_A"
22306   "pfpnacc\\t{%2, %0|%0, %2}"
22307   [(set_attr "type" "mmxadd")
22308    (set_attr "mode" "V2SF")])
22309
22310 (define_insn "pi2fw"
22311   [(set (match_operand:V2SF 0 "register_operand" "=y")
22312         (float:V2SF
22313            (vec_concat:V2SI
22314               (sign_extend:SI
22315                  (truncate:HI
22316                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22317                                    (parallel [(const_int 0)]))))
22318               (sign_extend:SI
22319                  (truncate:HI
22320                     (vec_select:SI (match_dup 1)
22321                                    (parallel [(const_int  1)])))))))]
22322   "TARGET_3DNOW_A"
22323   "pi2fw\\t{%1, %0|%0, %1}"
22324   [(set_attr "type" "mmxcvt")
22325    (set_attr "mode" "V2SF")])
22326
22327 (define_insn "floatv2si2"
22328   [(set (match_operand:V2SF 0 "register_operand" "=y")
22329         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22330   "TARGET_3DNOW"
22331   "pi2fd\\t{%1, %0|%0, %1}"
22332   [(set_attr "type" "mmxcvt")
22333    (set_attr "mode" "V2SF")])
22334
22335 ;; This insn is identical to pavgb in operation, but the opcode is
22336 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22337
22338 (define_insn "pavgusb"
22339  [(set (match_operand:V8QI 0 "register_operand" "=y")
22340        (unspec:V8QI
22341           [(match_operand:V8QI 1 "register_operand" "0")
22342            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22343           UNSPEC_PAVGUSB))]
22344   "TARGET_3DNOW"
22345   "pavgusb\\t{%2, %0|%0, %2}"
22346   [(set_attr "type" "mmxshft")
22347    (set_attr "mode" "TI")])
22348
22349 ;; 3DNow reciprocal and sqrt
22350  
22351 (define_insn "pfrcpv2sf2"
22352   [(set (match_operand:V2SF 0 "register_operand" "=y")
22353         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22354         UNSPEC_PFRCP))]
22355   "TARGET_3DNOW"
22356   "pfrcp\\t{%1, %0|%0, %1}"
22357   [(set_attr "type" "mmx")
22358    (set_attr "mode" "TI")])
22359
22360 (define_insn "pfrcpit1v2sf3"
22361   [(set (match_operand:V2SF 0 "register_operand" "=y")
22362         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22363                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22364                      UNSPEC_PFRCPIT1))]
22365   "TARGET_3DNOW"
22366   "pfrcpit1\\t{%2, %0|%0, %2}"
22367   [(set_attr "type" "mmx")
22368    (set_attr "mode" "TI")])
22369
22370 (define_insn "pfrcpit2v2sf3"
22371   [(set (match_operand:V2SF 0 "register_operand" "=y")
22372         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22373                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22374                      UNSPEC_PFRCPIT2))]
22375   "TARGET_3DNOW"
22376   "pfrcpit2\\t{%2, %0|%0, %2}"
22377   [(set_attr "type" "mmx")
22378    (set_attr "mode" "TI")])
22379
22380 (define_insn "pfrsqrtv2sf2"
22381   [(set (match_operand:V2SF 0 "register_operand" "=y")
22382         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22383                      UNSPEC_PFRSQRT))]
22384   "TARGET_3DNOW"
22385   "pfrsqrt\\t{%1, %0|%0, %1}"
22386   [(set_attr "type" "mmx")
22387    (set_attr "mode" "TI")])
22388                 
22389 (define_insn "pfrsqit1v2sf3"
22390   [(set (match_operand:V2SF 0 "register_operand" "=y")
22391         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22392                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22393                      UNSPEC_PFRSQIT1))]
22394   "TARGET_3DNOW"
22395   "pfrsqit1\\t{%2, %0|%0, %2}"
22396   [(set_attr "type" "mmx")
22397    (set_attr "mode" "TI")])
22398
22399 (define_insn "pmulhrwv4hi3"
22400   [(set (match_operand:V4HI 0 "register_operand" "=y")
22401         (truncate:V4HI
22402            (lshiftrt:V4SI
22403               (plus:V4SI
22404                  (mult:V4SI
22405                     (sign_extend:V4SI
22406                        (match_operand:V4HI 1 "register_operand" "0"))
22407                     (sign_extend:V4SI
22408                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22409                  (const_vector:V4SI [(const_int 32768)
22410                                      (const_int 32768)
22411                                      (const_int 32768)
22412                                      (const_int 32768)]))
22413               (const_int 16))))]
22414   "TARGET_3DNOW"
22415   "pmulhrw\\t{%2, %0|%0, %2}"
22416   [(set_attr "type" "mmxmul")
22417    (set_attr "mode" "TI")])
22418
22419 (define_insn "pswapdv2si2"
22420   [(set (match_operand:V2SI 0 "register_operand" "=y")
22421         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22422                          (parallel [(const_int 1) (const_int 0)])))]
22423   "TARGET_3DNOW_A"
22424   "pswapd\\t{%1, %0|%0, %1}"
22425   [(set_attr "type" "mmxcvt")
22426    (set_attr "mode" "TI")])
22427
22428 (define_insn "pswapdv2sf2"
22429   [(set (match_operand:V2SF 0 "register_operand" "=y")
22430         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22431                          (parallel [(const_int 1) (const_int 0)])))]
22432   "TARGET_3DNOW_A"
22433   "pswapd\\t{%1, %0|%0, %1}"
22434   [(set_attr "type" "mmxcvt")
22435    (set_attr "mode" "TI")])
22436
22437 (define_expand "prefetch"
22438   [(prefetch (match_operand 0 "address_operand" "")
22439              (match_operand:SI 1 "const_int_operand" "")
22440              (match_operand:SI 2 "const_int_operand" ""))]
22441   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22442 {
22443   int rw = INTVAL (operands[1]);
22444   int locality = INTVAL (operands[2]);
22445
22446   if (rw != 0 && rw != 1)
22447     abort ();
22448   if (locality < 0 || locality > 3)
22449     abort ();
22450   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22451     abort ();
22452
22453   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22454      suported by SSE counterpart or the SSE prefetch is not available
22455      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22456      of locality.  */
22457   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22458     operands[2] = GEN_INT (3);
22459   else
22460     operands[1] = const0_rtx;
22461 })
22462
22463 (define_insn "*prefetch_sse"
22464   [(prefetch (match_operand:SI 0 "address_operand" "p")
22465              (const_int 0)
22466              (match_operand:SI 1 "const_int_operand" ""))]
22467   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22468 {
22469   static const char * const patterns[4] = {
22470    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22471   };
22472
22473   int locality = INTVAL (operands[1]);
22474   if (locality < 0 || locality > 3)
22475     abort ();
22476
22477   return patterns[locality];  
22478 }
22479   [(set_attr "type" "sse")
22480    (set_attr "memory" "none")])
22481
22482 (define_insn "*prefetch_sse_rex"
22483   [(prefetch (match_operand:DI 0 "address_operand" "p")
22484              (const_int 0)
22485              (match_operand:SI 1 "const_int_operand" ""))]
22486   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22487 {
22488   static const char * const patterns[4] = {
22489    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22490   };
22491
22492   int locality = INTVAL (operands[1]);
22493   if (locality < 0 || locality > 3)
22494     abort ();
22495
22496   return patterns[locality];  
22497 }
22498   [(set_attr "type" "sse")
22499    (set_attr "memory" "none")])
22500
22501 (define_insn "*prefetch_3dnow"
22502   [(prefetch (match_operand:SI 0 "address_operand" "p")
22503              (match_operand:SI 1 "const_int_operand" "n")
22504              (const_int 3))]
22505   "TARGET_3DNOW && !TARGET_64BIT"
22506 {
22507   if (INTVAL (operands[1]) == 0)
22508     return "prefetch\t%a0";
22509   else
22510     return "prefetchw\t%a0";
22511 }
22512   [(set_attr "type" "mmx")
22513    (set_attr "memory" "none")])
22514
22515 (define_insn "*prefetch_3dnow_rex"
22516   [(prefetch (match_operand:DI 0 "address_operand" "p")
22517              (match_operand:SI 1 "const_int_operand" "n")
22518              (const_int 3))]
22519   "TARGET_3DNOW && TARGET_64BIT"
22520 {
22521   if (INTVAL (operands[1]) == 0)
22522     return "prefetch\t%a0";
22523   else
22524     return "prefetchw\t%a0";
22525 }
22526   [(set_attr "type" "mmx")
22527    (set_attr "memory" "none")])
22528
22529 ;; SSE2 support
22530
22531 (define_insn "addv2df3"
22532   [(set (match_operand:V2DF 0 "register_operand" "=x")
22533         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22534                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22535   "TARGET_SSE2"
22536   "addpd\t{%2, %0|%0, %2}"
22537   [(set_attr "type" "sseadd")
22538    (set_attr "mode" "V2DF")])
22539
22540 (define_insn "vmaddv2df3"
22541   [(set (match_operand:V2DF 0 "register_operand" "=x")
22542         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22543                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22544                         (match_dup 1)
22545                         (const_int 1)))]
22546   "TARGET_SSE2"
22547   "addsd\t{%2, %0|%0, %2}"
22548   [(set_attr "type" "sseadd")
22549    (set_attr "mode" "DF")])
22550
22551 (define_insn "subv2df3"
22552   [(set (match_operand:V2DF 0 "register_operand" "=x")
22553         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22554                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22555   "TARGET_SSE2"
22556   "subpd\t{%2, %0|%0, %2}"
22557   [(set_attr "type" "sseadd")
22558    (set_attr "mode" "V2DF")])
22559
22560 (define_insn "vmsubv2df3"
22561   [(set (match_operand:V2DF 0 "register_operand" "=x")
22562         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22563                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22564                         (match_dup 1)
22565                         (const_int 1)))]
22566   "TARGET_SSE2"
22567   "subsd\t{%2, %0|%0, %2}"
22568   [(set_attr "type" "sseadd")
22569    (set_attr "mode" "DF")])
22570
22571 (define_insn "mulv2df3"
22572   [(set (match_operand:V2DF 0 "register_operand" "=x")
22573         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22574                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22575   "TARGET_SSE2"
22576   "mulpd\t{%2, %0|%0, %2}"
22577   [(set_attr "type" "ssemul")
22578    (set_attr "mode" "V2DF")])
22579
22580 (define_insn "vmmulv2df3"
22581   [(set (match_operand:V2DF 0 "register_operand" "=x")
22582         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22583                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22584                         (match_dup 1)
22585                         (const_int 1)))]
22586   "TARGET_SSE2"
22587   "mulsd\t{%2, %0|%0, %2}"
22588   [(set_attr "type" "ssemul")
22589    (set_attr "mode" "DF")])
22590
22591 (define_insn "divv2df3"
22592   [(set (match_operand:V2DF 0 "register_operand" "=x")
22593         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22594                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22595   "TARGET_SSE2"
22596   "divpd\t{%2, %0|%0, %2}"
22597   [(set_attr "type" "ssediv")
22598    (set_attr "mode" "V2DF")])
22599
22600 (define_insn "vmdivv2df3"
22601   [(set (match_operand:V2DF 0 "register_operand" "=x")
22602         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22603                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22604                         (match_dup 1)
22605                         (const_int 1)))]
22606   "TARGET_SSE2"
22607   "divsd\t{%2, %0|%0, %2}"
22608   [(set_attr "type" "ssediv")
22609    (set_attr "mode" "DF")])
22610
22611 ;; SSE min/max
22612
22613 (define_insn "smaxv2df3"
22614   [(set (match_operand:V2DF 0 "register_operand" "=x")
22615         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22616                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22617   "TARGET_SSE2"
22618   "maxpd\t{%2, %0|%0, %2}"
22619   [(set_attr "type" "sseadd")
22620    (set_attr "mode" "V2DF")])
22621
22622 (define_insn "vmsmaxv2df3"
22623   [(set (match_operand:V2DF 0 "register_operand" "=x")
22624         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22625                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22626                         (match_dup 1)
22627                         (const_int 1)))]
22628   "TARGET_SSE2"
22629   "maxsd\t{%2, %0|%0, %2}"
22630   [(set_attr "type" "sseadd")
22631    (set_attr "mode" "DF")])
22632
22633 (define_insn "sminv2df3"
22634   [(set (match_operand:V2DF 0 "register_operand" "=x")
22635         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22636                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22637   "TARGET_SSE2"
22638   "minpd\t{%2, %0|%0, %2}"
22639   [(set_attr "type" "sseadd")
22640    (set_attr "mode" "V2DF")])
22641
22642 (define_insn "vmsminv2df3"
22643   [(set (match_operand:V2DF 0 "register_operand" "=x")
22644         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22645                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22646                         (match_dup 1)
22647                         (const_int 1)))]
22648   "TARGET_SSE2"
22649   "minsd\t{%2, %0|%0, %2}"
22650   [(set_attr "type" "sseadd")
22651    (set_attr "mode" "DF")])
22652 ;; SSE2 square root.  There doesn't appear to be an extension for the
22653 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22654
22655 (define_insn "sqrtv2df2"
22656   [(set (match_operand:V2DF 0 "register_operand" "=x")
22657         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22658   "TARGET_SSE2"
22659   "sqrtpd\t{%1, %0|%0, %1}"
22660   [(set_attr "type" "sse")
22661    (set_attr "mode" "V2DF")])
22662
22663 (define_insn "vmsqrtv2df2"
22664   [(set (match_operand:V2DF 0 "register_operand" "=x")
22665         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22666                         (match_operand:V2DF 2 "register_operand" "0")
22667                         (const_int 1)))]
22668   "TARGET_SSE2"
22669   "sqrtsd\t{%1, %0|%0, %1}"
22670   [(set_attr "type" "sse")
22671    (set_attr "mode" "SF")])
22672
22673 ;; SSE mask-generating compares
22674
22675 (define_insn "maskcmpv2df3"
22676   [(set (match_operand:V2DI 0 "register_operand" "=x")
22677         (match_operator:V2DI 3 "sse_comparison_operator"
22678                              [(match_operand:V2DF 1 "register_operand" "0")
22679                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22680   "TARGET_SSE2"
22681   "cmp%D3pd\t{%2, %0|%0, %2}"
22682   [(set_attr "type" "ssecmp")
22683    (set_attr "mode" "V2DF")])
22684
22685 (define_insn "maskncmpv2df3"
22686   [(set (match_operand:V2DI 0 "register_operand" "=x")
22687         (not:V2DI
22688          (match_operator:V2DI 3 "sse_comparison_operator"
22689                               [(match_operand:V2DF 1 "register_operand" "0")
22690                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22691   "TARGET_SSE2"
22692 {
22693   if (GET_CODE (operands[3]) == UNORDERED)
22694     return "cmpordps\t{%2, %0|%0, %2}";
22695   else
22696     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22697 }
22698   [(set_attr "type" "ssecmp")
22699    (set_attr "mode" "V2DF")])
22700
22701 (define_insn "vmmaskcmpv2df3"
22702   [(set (match_operand:V2DI 0 "register_operand" "=x")
22703         (vec_merge:V2DI
22704          (match_operator:V2DI 3 "sse_comparison_operator"
22705                               [(match_operand:V2DF 1 "register_operand" "0")
22706                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22707          (subreg:V2DI (match_dup 1) 0)
22708          (const_int 1)))]
22709   "TARGET_SSE2"
22710   "cmp%D3sd\t{%2, %0|%0, %2}"
22711   [(set_attr "type" "ssecmp")
22712    (set_attr "mode" "DF")])
22713
22714 (define_insn "vmmaskncmpv2df3"
22715   [(set (match_operand:V2DI 0 "register_operand" "=x")
22716         (vec_merge:V2DI
22717          (not:V2DI
22718           (match_operator:V2DI 3 "sse_comparison_operator"
22719                                [(match_operand:V2DF 1 "register_operand" "0")
22720                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22721          (subreg:V2DI (match_dup 1) 0)
22722          (const_int 1)))]
22723   "TARGET_SSE2"
22724 {
22725   if (GET_CODE (operands[3]) == UNORDERED)
22726     return "cmpordsd\t{%2, %0|%0, %2}";
22727   else
22728     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22729 }
22730   [(set_attr "type" "ssecmp")
22731    (set_attr "mode" "DF")])
22732
22733 (define_insn "sse2_comi"
22734   [(set (reg:CCFP FLAGS_REG)
22735         (compare:CCFP (vec_select:DF
22736                        (match_operand:V2DF 0 "register_operand" "x")
22737                        (parallel [(const_int 0)]))
22738                       (vec_select:DF
22739                        (match_operand:V2DF 1 "register_operand" "x")
22740                        (parallel [(const_int 0)]))))]
22741   "TARGET_SSE2"
22742   "comisd\t{%1, %0|%0, %1}"
22743   [(set_attr "type" "ssecomi")
22744    (set_attr "mode" "DF")])
22745
22746 (define_insn "sse2_ucomi"
22747   [(set (reg:CCFPU FLAGS_REG)
22748         (compare:CCFPU (vec_select:DF
22749                          (match_operand:V2DF 0 "register_operand" "x")
22750                          (parallel [(const_int 0)]))
22751                         (vec_select:DF
22752                          (match_operand:V2DF 1 "register_operand" "x")
22753                          (parallel [(const_int 0)]))))]
22754   "TARGET_SSE2"
22755   "ucomisd\t{%1, %0|%0, %1}"
22756   [(set_attr "type" "ssecomi")
22757    (set_attr "mode" "DF")])
22758
22759 ;; SSE Strange Moves.
22760
22761 (define_insn "sse2_movmskpd"
22762   [(set (match_operand:SI 0 "register_operand" "=r")
22763         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22764                    UNSPEC_MOVMSK))]
22765   "TARGET_SSE2"
22766   "movmskpd\t{%1, %0|%0, %1}"
22767   [(set_attr "type" "ssecvt")
22768    (set_attr "mode" "V2DF")])
22769
22770 (define_insn "sse2_pmovmskb"
22771   [(set (match_operand:SI 0 "register_operand" "=r")
22772         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22773                    UNSPEC_MOVMSK))]
22774   "TARGET_SSE2"
22775   "pmovmskb\t{%1, %0|%0, %1}"
22776   [(set_attr "type" "ssecvt")
22777    (set_attr "mode" "V2DF")])
22778
22779 (define_insn "sse2_maskmovdqu"
22780   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22781         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22782                        (match_operand:V16QI 2 "register_operand" "x")]
22783                       UNSPEC_MASKMOV))]
22784   "TARGET_SSE2"
22785   ;; @@@ check ordering of operands in intel/nonintel syntax
22786   "maskmovdqu\t{%2, %1|%1, %2}"
22787   [(set_attr "type" "ssecvt")
22788    (set_attr "mode" "TI")])
22789
22790 (define_insn "sse2_maskmovdqu_rex64"
22791   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22792         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22793                        (match_operand:V16QI 2 "register_operand" "x")]
22794                       UNSPEC_MASKMOV))]
22795   "TARGET_SSE2"
22796   ;; @@@ check ordering of operands in intel/nonintel syntax
22797   "maskmovdqu\t{%2, %1|%1, %2}"
22798   [(set_attr "type" "ssecvt")
22799    (set_attr "mode" "TI")])
22800
22801 (define_insn "sse2_movntv2df"
22802   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22803         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22804                      UNSPEC_MOVNT))]
22805   "TARGET_SSE2"
22806   "movntpd\t{%1, %0|%0, %1}"
22807   [(set_attr "type" "ssecvt")
22808    (set_attr "mode" "V2DF")])
22809
22810 (define_insn "sse2_movntv2di"
22811   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22812         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22813                      UNSPEC_MOVNT))]
22814   "TARGET_SSE2"
22815   "movntdq\t{%1, %0|%0, %1}"
22816   [(set_attr "type" "ssecvt")
22817    (set_attr "mode" "TI")])
22818
22819 (define_insn "sse2_movntsi"
22820   [(set (match_operand:SI 0 "memory_operand" "=m")
22821         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22822                    UNSPEC_MOVNT))]
22823   "TARGET_SSE2"
22824   "movnti\t{%1, %0|%0, %1}"
22825   [(set_attr "type" "ssecvt")
22826    (set_attr "mode" "V2DF")])
22827
22828 ;; SSE <-> integer/MMX conversions
22829
22830 ;; Conversions between SI and SF
22831
22832 (define_insn "cvtdq2ps"
22833   [(set (match_operand:V4SF 0 "register_operand" "=x")
22834         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22835   "TARGET_SSE2"
22836   "cvtdq2ps\t{%1, %0|%0, %1}"
22837   [(set_attr "type" "ssecvt")
22838    (set_attr "mode" "V2DF")])
22839
22840 (define_insn "cvtps2dq"
22841   [(set (match_operand:V4SI 0 "register_operand" "=x")
22842         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22843   "TARGET_SSE2"
22844   "cvtps2dq\t{%1, %0|%0, %1}"
22845   [(set_attr "type" "ssecvt")
22846    (set_attr "mode" "TI")])
22847
22848 (define_insn "cvttps2dq"
22849   [(set (match_operand:V4SI 0 "register_operand" "=x")
22850         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22851                      UNSPEC_FIX))]
22852   "TARGET_SSE2"
22853   "cvttps2dq\t{%1, %0|%0, %1}"
22854   [(set_attr "type" "ssecvt")
22855    (set_attr "mode" "TI")])
22856
22857 ;; Conversions between SI and DF
22858
22859 (define_insn "cvtdq2pd"
22860   [(set (match_operand:V2DF 0 "register_operand" "=x")
22861         (float:V2DF (vec_select:V2SI
22862                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22863                      (parallel
22864                       [(const_int 0)
22865                        (const_int 1)]))))]
22866   "TARGET_SSE2"
22867   "cvtdq2pd\t{%1, %0|%0, %1}"
22868   [(set_attr "type" "ssecvt")
22869    (set_attr "mode" "V2DF")])
22870
22871 (define_insn "cvtpd2dq"
22872   [(set (match_operand:V4SI 0 "register_operand" "=x")
22873         (vec_concat:V4SI
22874          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22875          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22876   "TARGET_SSE2"
22877   "cvtpd2dq\t{%1, %0|%0, %1}"
22878   [(set_attr "type" "ssecvt")
22879    (set_attr "mode" "TI")])
22880
22881 (define_insn "cvttpd2dq"
22882   [(set (match_operand:V4SI 0 "register_operand" "=x")
22883         (vec_concat:V4SI
22884          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22885                       UNSPEC_FIX)
22886          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22887   "TARGET_SSE2"
22888   "cvttpd2dq\t{%1, %0|%0, %1}"
22889   [(set_attr "type" "ssecvt")
22890    (set_attr "mode" "TI")])
22891
22892 (define_insn "cvtpd2pi"
22893   [(set (match_operand:V2SI 0 "register_operand" "=y")
22894         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22895   "TARGET_SSE2"
22896   "cvtpd2pi\t{%1, %0|%0, %1}"
22897   [(set_attr "type" "ssecvt")
22898    (set_attr "mode" "TI")])
22899
22900 (define_insn "cvttpd2pi"
22901   [(set (match_operand:V2SI 0 "register_operand" "=y")
22902         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22903                      UNSPEC_FIX))]
22904   "TARGET_SSE2"
22905   "cvttpd2pi\t{%1, %0|%0, %1}"
22906   [(set_attr "type" "ssecvt")
22907    (set_attr "mode" "TI")])
22908
22909 (define_insn "cvtpi2pd"
22910   [(set (match_operand:V2DF 0 "register_operand" "=x")
22911         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22912   "TARGET_SSE2"
22913   "cvtpi2pd\t{%1, %0|%0, %1}"
22914   [(set_attr "type" "ssecvt")
22915    (set_attr "mode" "TI")])
22916
22917 ;; Conversions between SI and DF
22918
22919 (define_insn "cvtsd2si"
22920   [(set (match_operand:SI 0 "register_operand" "=r,r")
22921         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22922                                (parallel [(const_int 0)]))))]
22923   "TARGET_SSE2"
22924   "cvtsd2si\t{%1, %0|%0, %1}"
22925   [(set_attr "type" "sseicvt")
22926    (set_attr "athlon_decode" "double,vector")
22927    (set_attr "mode" "SI")])
22928
22929 (define_insn "cvtsd2siq"
22930   [(set (match_operand:DI 0 "register_operand" "=r,r")
22931         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22932                                (parallel [(const_int 0)]))))]
22933   "TARGET_SSE2 && TARGET_64BIT"
22934   "cvtsd2siq\t{%1, %0|%0, %1}"
22935   [(set_attr "type" "sseicvt")
22936    (set_attr "athlon_decode" "double,vector")
22937    (set_attr "mode" "DI")])
22938
22939 (define_insn "cvttsd2si"
22940   [(set (match_operand:SI 0 "register_operand" "=r,r")
22941         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22942                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22943   "TARGET_SSE2"
22944   "cvttsd2si\t{%1, %0|%0, %1}"
22945   [(set_attr "type" "sseicvt")
22946    (set_attr "mode" "SI")
22947    (set_attr "athlon_decode" "double,vector")])
22948
22949 (define_insn "cvttsd2siq"
22950   [(set (match_operand:DI 0 "register_operand" "=r,r")
22951         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22952                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22953   "TARGET_SSE2 && TARGET_64BIT"
22954   "cvttsd2siq\t{%1, %0|%0, %1}"
22955   [(set_attr "type" "sseicvt")
22956    (set_attr "mode" "DI")
22957    (set_attr "athlon_decode" "double,vector")])
22958
22959 (define_insn "cvtsi2sd"
22960   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22961         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22962                         (vec_duplicate:V2DF
22963                           (float:DF
22964                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22965                         (const_int 2)))]
22966   "TARGET_SSE2"
22967   "cvtsi2sd\t{%2, %0|%0, %2}"
22968   [(set_attr "type" "sseicvt")
22969    (set_attr "mode" "DF")
22970    (set_attr "athlon_decode" "double,direct")])
22971
22972 (define_insn "cvtsi2sdq"
22973   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22974         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22975                         (vec_duplicate:V2DF
22976                           (float:DF
22977                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22978                         (const_int 2)))]
22979   "TARGET_SSE2 && TARGET_64BIT"
22980   "cvtsi2sdq\t{%2, %0|%0, %2}"
22981   [(set_attr "type" "sseicvt")
22982    (set_attr "mode" "DF")
22983    (set_attr "athlon_decode" "double,direct")])
22984
22985 ;; Conversions between SF and DF
22986
22987 (define_insn "cvtsd2ss"
22988   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22989         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22990                         (vec_duplicate:V4SF
22991                           (float_truncate:V2SF
22992                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22993                         (const_int 14)))]
22994   "TARGET_SSE2"
22995   "cvtsd2ss\t{%2, %0|%0, %2}"
22996   [(set_attr "type" "ssecvt")
22997    (set_attr "athlon_decode" "vector,double")
22998    (set_attr "mode" "SF")])
22999
23000 (define_insn "cvtss2sd"
23001   [(set (match_operand:V2DF 0 "register_operand" "=x")
23002         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23003                         (float_extend:V2DF
23004                           (vec_select:V2SF
23005                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23006                             (parallel [(const_int 0)
23007                                        (const_int 1)])))
23008                         (const_int 2)))]
23009   "TARGET_SSE2"
23010   "cvtss2sd\t{%2, %0|%0, %2}"
23011   [(set_attr "type" "ssecvt")
23012    (set_attr "mode" "DF")])
23013
23014 (define_insn "cvtpd2ps"
23015   [(set (match_operand:V4SF 0 "register_operand" "=x")
23016         (subreg:V4SF
23017           (vec_concat:V4SI
23018             (subreg:V2SI (float_truncate:V2SF
23019                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23020             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23021   "TARGET_SSE2"
23022   "cvtpd2ps\t{%1, %0|%0, %1}"
23023   [(set_attr "type" "ssecvt")
23024    (set_attr "mode" "V4SF")])
23025
23026 (define_insn "cvtps2pd"
23027   [(set (match_operand:V2DF 0 "register_operand" "=x")
23028         (float_extend:V2DF
23029           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23030                            (parallel [(const_int 0)
23031                                       (const_int 1)]))))]
23032   "TARGET_SSE2"
23033   "cvtps2pd\t{%1, %0|%0, %1}"
23034   [(set_attr "type" "ssecvt")
23035    (set_attr "mode" "V2DF")])
23036
23037 ;; SSE2 variants of MMX insns
23038
23039 ;; MMX arithmetic
23040
23041 (define_insn "addv16qi3"
23042   [(set (match_operand:V16QI 0 "register_operand" "=x")
23043         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23044                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23045   "TARGET_SSE2"
23046   "paddb\t{%2, %0|%0, %2}"
23047   [(set_attr "type" "sseiadd")
23048    (set_attr "mode" "TI")])
23049
23050 (define_insn "addv8hi3"
23051   [(set (match_operand:V8HI 0 "register_operand" "=x")
23052         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23053                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23054   "TARGET_SSE2"
23055   "paddw\t{%2, %0|%0, %2}"
23056   [(set_attr "type" "sseiadd")
23057    (set_attr "mode" "TI")])
23058
23059 (define_insn "addv4si3"
23060   [(set (match_operand:V4SI 0 "register_operand" "=x")
23061         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23062                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23063   "TARGET_SSE2"
23064   "paddd\t{%2, %0|%0, %2}"
23065   [(set_attr "type" "sseiadd")
23066    (set_attr "mode" "TI")])
23067
23068 (define_insn "addv2di3"
23069   [(set (match_operand:V2DI 0 "register_operand" "=x")
23070         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23071                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23072   "TARGET_SSE2"
23073   "paddq\t{%2, %0|%0, %2}"
23074   [(set_attr "type" "sseiadd")
23075    (set_attr "mode" "TI")])
23076
23077 (define_insn "ssaddv16qi3"
23078   [(set (match_operand:V16QI 0 "register_operand" "=x")
23079         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23080                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23081   "TARGET_SSE2"
23082   "paddsb\t{%2, %0|%0, %2}"
23083   [(set_attr "type" "sseiadd")
23084    (set_attr "mode" "TI")])
23085
23086 (define_insn "ssaddv8hi3"
23087   [(set (match_operand:V8HI 0 "register_operand" "=x")
23088         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23089                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23090   "TARGET_SSE2"
23091   "paddsw\t{%2, %0|%0, %2}"
23092   [(set_attr "type" "sseiadd")
23093    (set_attr "mode" "TI")])
23094
23095 (define_insn "usaddv16qi3"
23096   [(set (match_operand:V16QI 0 "register_operand" "=x")
23097         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23098                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23099   "TARGET_SSE2"
23100   "paddusb\t{%2, %0|%0, %2}"
23101   [(set_attr "type" "sseiadd")
23102    (set_attr "mode" "TI")])
23103
23104 (define_insn "usaddv8hi3"
23105   [(set (match_operand:V8HI 0 "register_operand" "=x")
23106         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23107                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23108   "TARGET_SSE2"
23109   "paddusw\t{%2, %0|%0, %2}"
23110   [(set_attr "type" "sseiadd")
23111    (set_attr "mode" "TI")])
23112
23113 (define_insn "subv16qi3"
23114   [(set (match_operand:V16QI 0 "register_operand" "=x")
23115         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23116                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23117   "TARGET_SSE2"
23118   "psubb\t{%2, %0|%0, %2}"
23119   [(set_attr "type" "sseiadd")
23120    (set_attr "mode" "TI")])
23121
23122 (define_insn "subv8hi3"
23123   [(set (match_operand:V8HI 0 "register_operand" "=x")
23124         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23125                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23126   "TARGET_SSE2"
23127   "psubw\t{%2, %0|%0, %2}"
23128   [(set_attr "type" "sseiadd")
23129    (set_attr "mode" "TI")])
23130
23131 (define_insn "subv4si3"
23132   [(set (match_operand:V4SI 0 "register_operand" "=x")
23133         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23134                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23135   "TARGET_SSE2"
23136   "psubd\t{%2, %0|%0, %2}"
23137   [(set_attr "type" "sseiadd")
23138    (set_attr "mode" "TI")])
23139
23140 (define_insn "subv2di3"
23141   [(set (match_operand:V2DI 0 "register_operand" "=x")
23142         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23143                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23144   "TARGET_SSE2"
23145   "psubq\t{%2, %0|%0, %2}"
23146   [(set_attr "type" "sseiadd")
23147    (set_attr "mode" "TI")])
23148
23149 (define_insn "sssubv16qi3"
23150   [(set (match_operand:V16QI 0 "register_operand" "=x")
23151         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23152                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23153   "TARGET_SSE2"
23154   "psubsb\t{%2, %0|%0, %2}"
23155   [(set_attr "type" "sseiadd")
23156    (set_attr "mode" "TI")])
23157
23158 (define_insn "sssubv8hi3"
23159   [(set (match_operand:V8HI 0 "register_operand" "=x")
23160         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23161                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23162   "TARGET_SSE2"
23163   "psubsw\t{%2, %0|%0, %2}"
23164   [(set_attr "type" "sseiadd")
23165    (set_attr "mode" "TI")])
23166
23167 (define_insn "ussubv16qi3"
23168   [(set (match_operand:V16QI 0 "register_operand" "=x")
23169         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23170                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23171   "TARGET_SSE2"
23172   "psubusb\t{%2, %0|%0, %2}"
23173   [(set_attr "type" "sseiadd")
23174    (set_attr "mode" "TI")])
23175
23176 (define_insn "ussubv8hi3"
23177   [(set (match_operand:V8HI 0 "register_operand" "=x")
23178         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23179                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23180   "TARGET_SSE2"
23181   "psubusw\t{%2, %0|%0, %2}"
23182   [(set_attr "type" "sseiadd")
23183    (set_attr "mode" "TI")])
23184
23185 (define_insn "mulv8hi3"
23186   [(set (match_operand:V8HI 0 "register_operand" "=x")
23187         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23188                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23189   "TARGET_SSE2"
23190   "pmullw\t{%2, %0|%0, %2}"
23191   [(set_attr "type" "sseimul")
23192    (set_attr "mode" "TI")])
23193
23194 (define_insn "smulv8hi3_highpart"
23195   [(set (match_operand:V8HI 0 "register_operand" "=x")
23196         (truncate:V8HI
23197          (lshiftrt:V8SI
23198           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23199                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23200           (const_int 16))))]
23201   "TARGET_SSE2"
23202   "pmulhw\t{%2, %0|%0, %2}"
23203   [(set_attr "type" "sseimul")
23204    (set_attr "mode" "TI")])
23205
23206 (define_insn "umulv8hi3_highpart"
23207   [(set (match_operand:V8HI 0 "register_operand" "=x")
23208         (truncate:V8HI
23209          (lshiftrt:V8SI
23210           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23211                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23212           (const_int 16))))]
23213   "TARGET_SSE2"
23214   "pmulhuw\t{%2, %0|%0, %2}"
23215   [(set_attr "type" "sseimul")
23216    (set_attr "mode" "TI")])
23217
23218 (define_insn "sse2_umulsidi3"
23219   [(set (match_operand:DI 0 "register_operand" "=y")
23220         (mult:DI (zero_extend:DI (vec_select:SI
23221                                   (match_operand:V2SI 1 "register_operand" "0")
23222                                   (parallel [(const_int 0)])))
23223                  (zero_extend:DI (vec_select:SI
23224                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23225                                   (parallel [(const_int 0)])))))]
23226   "TARGET_SSE2"
23227   "pmuludq\t{%2, %0|%0, %2}"
23228   [(set_attr "type" "mmxmul")
23229    (set_attr "mode" "DI")])
23230
23231 (define_insn "sse2_umulv2siv2di3"
23232   [(set (match_operand:V2DI 0 "register_operand" "=x")
23233         (mult:V2DI (zero_extend:V2DI
23234                      (vec_select:V2SI
23235                        (match_operand:V4SI 1 "register_operand" "0")
23236                        (parallel [(const_int 0) (const_int 2)])))
23237                    (zero_extend:V2DI
23238                      (vec_select:V2SI
23239                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23240                        (parallel [(const_int 0) (const_int 2)])))))]
23241   "TARGET_SSE2"
23242   "pmuludq\t{%2, %0|%0, %2}"
23243   [(set_attr "type" "sseimul")
23244    (set_attr "mode" "TI")])
23245
23246 (define_insn "sse2_pmaddwd"
23247   [(set (match_operand:V4SI 0 "register_operand" "=x")
23248         (plus:V4SI
23249          (mult:V4SI
23250           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23251                                              (parallel [(const_int 0)
23252                                                         (const_int 2)
23253                                                         (const_int 4)
23254                                                         (const_int 6)])))
23255           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23256                                              (parallel [(const_int 0)
23257                                                         (const_int 2)
23258                                                         (const_int 4)
23259                                                         (const_int 6)]))))
23260          (mult:V4SI
23261           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23262                                              (parallel [(const_int 1)
23263                                                         (const_int 3)
23264                                                         (const_int 5)
23265                                                         (const_int 7)])))
23266           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23267                                              (parallel [(const_int 1)
23268                                                         (const_int 3)
23269                                                         (const_int 5)
23270                                                         (const_int 7)]))))))]
23271   "TARGET_SSE2"
23272   "pmaddwd\t{%2, %0|%0, %2}"
23273   [(set_attr "type" "sseiadd")
23274    (set_attr "mode" "TI")])
23275
23276 ;; Same as pxor, but don't show input operands so that we don't think
23277 ;; they are live.
23278 (define_insn "sse2_clrti"
23279   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23280   "TARGET_SSE2"
23281 {
23282   if (get_attr_mode (insn) == MODE_TI)
23283     return "pxor\t%0, %0";
23284   else
23285     return "xorps\t%0, %0";
23286 }
23287   [(set_attr "type" "ssemov")
23288    (set_attr "memory" "none")
23289    (set (attr "mode")
23290               (if_then_else
23291                 (ne (symbol_ref "optimize_size")
23292                     (const_int 0))
23293                 (const_string "V4SF")
23294                 (const_string "TI")))])
23295
23296 ;; MMX unsigned averages/sum of absolute differences
23297
23298 (define_insn "sse2_uavgv16qi3"
23299   [(set (match_operand:V16QI 0 "register_operand" "=x")
23300         (ashiftrt:V16QI
23301          (plus:V16QI (plus:V16QI
23302                      (match_operand:V16QI 1 "register_operand" "0")
23303                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23304                      (const_vector:V16QI [(const_int 1) (const_int 1)
23305                                           (const_int 1) (const_int 1)
23306                                           (const_int 1) (const_int 1)
23307                                           (const_int 1) (const_int 1)
23308                                           (const_int 1) (const_int 1)
23309                                           (const_int 1) (const_int 1)
23310                                           (const_int 1) (const_int 1)
23311                                           (const_int 1) (const_int 1)]))
23312          (const_int 1)))]
23313   "TARGET_SSE2"
23314   "pavgb\t{%2, %0|%0, %2}"
23315   [(set_attr "type" "sseiadd")
23316    (set_attr "mode" "TI")])
23317
23318 (define_insn "sse2_uavgv8hi3"
23319   [(set (match_operand:V8HI 0 "register_operand" "=x")
23320         (ashiftrt:V8HI
23321          (plus:V8HI (plus:V8HI
23322                      (match_operand:V8HI 1 "register_operand" "0")
23323                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23324                     (const_vector:V8HI [(const_int 1) (const_int 1)
23325                                         (const_int 1) (const_int 1)
23326                                         (const_int 1) (const_int 1)
23327                                         (const_int 1) (const_int 1)]))
23328          (const_int 1)))]
23329   "TARGET_SSE2"
23330   "pavgw\t{%2, %0|%0, %2}"
23331   [(set_attr "type" "sseiadd")
23332    (set_attr "mode" "TI")])
23333
23334 ;; @@@ this isn't the right representation.
23335 (define_insn "sse2_psadbw"
23336   [(set (match_operand:V2DI 0 "register_operand" "=x")
23337         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23338                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23339                      UNSPEC_PSADBW))]
23340   "TARGET_SSE2"
23341   "psadbw\t{%2, %0|%0, %2}"
23342   [(set_attr "type" "sseiadd")
23343    (set_attr "mode" "TI")])
23344
23345
23346 ;; MMX insert/extract/shuffle
23347
23348 (define_insn "sse2_pinsrw"
23349   [(set (match_operand:V8HI 0 "register_operand" "=x")
23350         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23351                         (vec_duplicate:V8HI
23352                          (truncate:HI
23353                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23354                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23355   "TARGET_SSE2"
23356   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23357   [(set_attr "type" "ssecvt")
23358    (set_attr "mode" "TI")])
23359
23360 (define_insn "sse2_pextrw"
23361   [(set (match_operand:SI 0 "register_operand" "=r")
23362         (zero_extend:SI
23363           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23364                          (parallel
23365                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23366   "TARGET_SSE2"
23367   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23368   [(set_attr "type" "ssecvt")
23369    (set_attr "mode" "TI")])
23370
23371 (define_insn "sse2_pshufd"
23372   [(set (match_operand:V4SI 0 "register_operand" "=x")
23373         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23374                       (match_operand:SI 2 "immediate_operand" "i")]
23375                      UNSPEC_SHUFFLE))]
23376   "TARGET_SSE2"
23377   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23378   [(set_attr "type" "ssecvt")
23379    (set_attr "mode" "TI")])
23380
23381 (define_insn "sse2_pshuflw"
23382   [(set (match_operand:V8HI 0 "register_operand" "=x")
23383         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23384                       (match_operand:SI 2 "immediate_operand" "i")]
23385                      UNSPEC_PSHUFLW))]
23386   "TARGET_SSE2"
23387   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23388   [(set_attr "type" "ssecvt")
23389    (set_attr "mode" "TI")])
23390
23391 (define_insn "sse2_pshufhw"
23392   [(set (match_operand:V8HI 0 "register_operand" "=x")
23393         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23394                       (match_operand:SI 2 "immediate_operand" "i")]
23395                      UNSPEC_PSHUFHW))]
23396   "TARGET_SSE2"
23397   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23398   [(set_attr "type" "ssecvt")
23399    (set_attr "mode" "TI")])
23400
23401 ;; MMX mask-generating comparisons
23402
23403 (define_insn "eqv16qi3"
23404   [(set (match_operand:V16QI 0 "register_operand" "=x")
23405         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23406                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23407   "TARGET_SSE2"
23408   "pcmpeqb\t{%2, %0|%0, %2}"
23409   [(set_attr "type" "ssecmp")
23410    (set_attr "mode" "TI")])
23411
23412 (define_insn "eqv8hi3"
23413   [(set (match_operand:V8HI 0 "register_operand" "=x")
23414         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23415                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23416   "TARGET_SSE2"
23417   "pcmpeqw\t{%2, %0|%0, %2}"
23418   [(set_attr "type" "ssecmp")
23419    (set_attr "mode" "TI")])
23420
23421 (define_insn "eqv4si3"
23422   [(set (match_operand:V4SI 0 "register_operand" "=x")
23423         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23424                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23425   "TARGET_SSE2"
23426   "pcmpeqd\t{%2, %0|%0, %2}"
23427   [(set_attr "type" "ssecmp")
23428    (set_attr "mode" "TI")])
23429
23430 (define_insn "gtv16qi3"
23431   [(set (match_operand:V16QI 0 "register_operand" "=x")
23432         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23433                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23434   "TARGET_SSE2"
23435   "pcmpgtb\t{%2, %0|%0, %2}"
23436   [(set_attr "type" "ssecmp")
23437    (set_attr "mode" "TI")])
23438
23439 (define_insn "gtv8hi3"
23440   [(set (match_operand:V8HI 0 "register_operand" "=x")
23441         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23442                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23443   "TARGET_SSE2"
23444   "pcmpgtw\t{%2, %0|%0, %2}"
23445   [(set_attr "type" "ssecmp")
23446    (set_attr "mode" "TI")])
23447
23448 (define_insn "gtv4si3"
23449   [(set (match_operand:V4SI 0 "register_operand" "=x")
23450         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23451                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23452   "TARGET_SSE2"
23453   "pcmpgtd\t{%2, %0|%0, %2}"
23454   [(set_attr "type" "ssecmp")
23455    (set_attr "mode" "TI")])
23456
23457
23458 ;; MMX max/min insns
23459
23460 (define_insn "umaxv16qi3"
23461   [(set (match_operand:V16QI 0 "register_operand" "=x")
23462         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23463                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23464   "TARGET_SSE2"
23465   "pmaxub\t{%2, %0|%0, %2}"
23466   [(set_attr "type" "sseiadd")
23467    (set_attr "mode" "TI")])
23468
23469 (define_insn "smaxv8hi3"
23470   [(set (match_operand:V8HI 0 "register_operand" "=x")
23471         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23472                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23473   "TARGET_SSE2"
23474   "pmaxsw\t{%2, %0|%0, %2}"
23475   [(set_attr "type" "sseiadd")
23476    (set_attr "mode" "TI")])
23477
23478 (define_insn "uminv16qi3"
23479   [(set (match_operand:V16QI 0 "register_operand" "=x")
23480         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23481                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23482   "TARGET_SSE2"
23483   "pminub\t{%2, %0|%0, %2}"
23484   [(set_attr "type" "sseiadd")
23485    (set_attr "mode" "TI")])
23486
23487 (define_insn "sminv8hi3"
23488   [(set (match_operand:V8HI 0 "register_operand" "=x")
23489         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23490                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23491   "TARGET_SSE2"
23492   "pminsw\t{%2, %0|%0, %2}"
23493   [(set_attr "type" "sseiadd")
23494    (set_attr "mode" "TI")])
23495
23496
23497 ;; MMX shifts
23498
23499 (define_insn "ashrv8hi3"
23500   [(set (match_operand:V8HI 0 "register_operand" "=x")
23501         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23502                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23503   "TARGET_SSE2"
23504   "psraw\t{%2, %0|%0, %2}"
23505   [(set_attr "type" "sseishft")
23506    (set_attr "mode" "TI")])
23507
23508 (define_insn "ashrv4si3"
23509   [(set (match_operand:V4SI 0 "register_operand" "=x")
23510         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23511                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23512   "TARGET_SSE2"
23513   "psrad\t{%2, %0|%0, %2}"
23514   [(set_attr "type" "sseishft")
23515    (set_attr "mode" "TI")])
23516
23517 (define_insn "lshrv8hi3"
23518   [(set (match_operand:V8HI 0 "register_operand" "=x")
23519         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23520                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23521   "TARGET_SSE2"
23522   "psrlw\t{%2, %0|%0, %2}"
23523   [(set_attr "type" "sseishft")
23524    (set_attr "mode" "TI")])
23525
23526 (define_insn "lshrv4si3"
23527   [(set (match_operand:V4SI 0 "register_operand" "=x")
23528         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23529                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23530   "TARGET_SSE2"
23531   "psrld\t{%2, %0|%0, %2}"
23532   [(set_attr "type" "sseishft")
23533    (set_attr "mode" "TI")])
23534
23535 (define_insn "lshrv2di3"
23536   [(set (match_operand:V2DI 0 "register_operand" "=x")
23537         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23538                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23539   "TARGET_SSE2"
23540   "psrlq\t{%2, %0|%0, %2}"
23541   [(set_attr "type" "sseishft")
23542    (set_attr "mode" "TI")])
23543
23544 (define_insn "ashlv8hi3"
23545   [(set (match_operand:V8HI 0 "register_operand" "=x")
23546         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23547                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23548   "TARGET_SSE2"
23549   "psllw\t{%2, %0|%0, %2}"
23550   [(set_attr "type" "sseishft")
23551    (set_attr "mode" "TI")])
23552
23553 (define_insn "ashlv4si3"
23554   [(set (match_operand:V4SI 0 "register_operand" "=x")
23555         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23556                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23557   "TARGET_SSE2"
23558   "pslld\t{%2, %0|%0, %2}"
23559   [(set_attr "type" "sseishft")
23560    (set_attr "mode" "TI")])
23561
23562 (define_insn "ashlv2di3"
23563   [(set (match_operand:V2DI 0 "register_operand" "=x")
23564         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23565                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23566   "TARGET_SSE2"
23567   "psllq\t{%2, %0|%0, %2}"
23568   [(set_attr "type" "sseishft")
23569    (set_attr "mode" "TI")])
23570
23571 (define_insn "ashrv8hi3_ti"
23572   [(set (match_operand:V8HI 0 "register_operand" "=x")
23573         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23574                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23575   "TARGET_SSE2"
23576   "psraw\t{%2, %0|%0, %2}"
23577   [(set_attr "type" "sseishft")
23578    (set_attr "mode" "TI")])
23579
23580 (define_insn "ashrv4si3_ti"
23581   [(set (match_operand:V4SI 0 "register_operand" "=x")
23582         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23583                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23584   "TARGET_SSE2"
23585   "psrad\t{%2, %0|%0, %2}"
23586   [(set_attr "type" "sseishft")
23587    (set_attr "mode" "TI")])
23588
23589 (define_insn "lshrv8hi3_ti"
23590   [(set (match_operand:V8HI 0 "register_operand" "=x")
23591         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23592                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23593   "TARGET_SSE2"
23594   "psrlw\t{%2, %0|%0, %2}"
23595   [(set_attr "type" "sseishft")
23596    (set_attr "mode" "TI")])
23597
23598 (define_insn "lshrv4si3_ti"
23599   [(set (match_operand:V4SI 0 "register_operand" "=x")
23600         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23601                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23602   "TARGET_SSE2"
23603   "psrld\t{%2, %0|%0, %2}"
23604   [(set_attr "type" "sseishft")
23605    (set_attr "mode" "TI")])
23606
23607 (define_insn "lshrv2di3_ti"
23608   [(set (match_operand:V2DI 0 "register_operand" "=x")
23609         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23610                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23611   "TARGET_SSE2"
23612   "psrlq\t{%2, %0|%0, %2}"
23613   [(set_attr "type" "sseishft")
23614    (set_attr "mode" "TI")])
23615
23616 (define_insn "ashlv8hi3_ti"
23617   [(set (match_operand:V8HI 0 "register_operand" "=x")
23618         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23619                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23620   "TARGET_SSE2"
23621   "psllw\t{%2, %0|%0, %2}"
23622   [(set_attr "type" "sseishft")
23623    (set_attr "mode" "TI")])
23624
23625 (define_insn "ashlv4si3_ti"
23626   [(set (match_operand:V4SI 0 "register_operand" "=x")
23627         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23628                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23629   "TARGET_SSE2"
23630   "pslld\t{%2, %0|%0, %2}"
23631   [(set_attr "type" "sseishft")
23632    (set_attr "mode" "TI")])
23633
23634 (define_insn "ashlv2di3_ti"
23635   [(set (match_operand:V2DI 0 "register_operand" "=x")
23636         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23637                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23638   "TARGET_SSE2"
23639   "psllq\t{%2, %0|%0, %2}"
23640   [(set_attr "type" "sseishft")
23641    (set_attr "mode" "TI")])
23642
23643 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23644 ;; we wouldn't need here it since we never generate TImode arithmetic.
23645
23646 ;; There has to be some kind of prize for the weirdest new instruction...
23647 (define_insn "sse2_ashlti3"
23648   [(set (match_operand:TI 0 "register_operand" "=x")
23649         (unspec:TI
23650          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23651                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23652                                (const_int 8)))] UNSPEC_NOP))]
23653   "TARGET_SSE2"
23654   "pslldq\t{%2, %0|%0, %2}"
23655   [(set_attr "type" "sseishft")
23656    (set_attr "mode" "TI")])
23657
23658 (define_insn "sse2_lshrti3"
23659   [(set (match_operand:TI 0 "register_operand" "=x")
23660         (unspec:TI
23661          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23662                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23663                                 (const_int 8)))] UNSPEC_NOP))]
23664   "TARGET_SSE2"
23665   "psrldq\t{%2, %0|%0, %2}"
23666   [(set_attr "type" "sseishft")
23667    (set_attr "mode" "TI")])
23668
23669 ;; SSE unpack
23670
23671 (define_insn "sse2_unpckhpd"
23672   [(set (match_operand:V2DF 0 "register_operand" "=x")
23673         (vec_concat:V2DF
23674          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23675                         (parallel [(const_int 1)]))
23676          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23677                         (parallel [(const_int 1)]))))]
23678   "TARGET_SSE2"
23679   "unpckhpd\t{%2, %0|%0, %2}"
23680   [(set_attr "type" "ssecvt")
23681    (set_attr "mode" "V2DF")])
23682
23683 (define_insn "sse2_unpcklpd"
23684   [(set (match_operand:V2DF 0 "register_operand" "=x")
23685         (vec_concat:V2DF
23686          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23687                         (parallel [(const_int 0)]))
23688          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23689                         (parallel [(const_int 0)]))))]
23690   "TARGET_SSE2"
23691   "unpcklpd\t{%2, %0|%0, %2}"
23692   [(set_attr "type" "ssecvt")
23693    (set_attr "mode" "V2DF")])
23694
23695 ;; MMX pack/unpack insns.
23696
23697 (define_insn "sse2_packsswb"
23698   [(set (match_operand:V16QI 0 "register_operand" "=x")
23699         (vec_concat:V16QI
23700          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23701          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23702   "TARGET_SSE2"
23703   "packsswb\t{%2, %0|%0, %2}"
23704   [(set_attr "type" "ssecvt")
23705    (set_attr "mode" "TI")])
23706
23707 (define_insn "sse2_packssdw"
23708   [(set (match_operand:V8HI 0 "register_operand" "=x")
23709         (vec_concat:V8HI
23710          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23711          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23712   "TARGET_SSE2"
23713   "packssdw\t{%2, %0|%0, %2}"
23714   [(set_attr "type" "ssecvt")
23715    (set_attr "mode" "TI")])
23716
23717 (define_insn "sse2_packuswb"
23718   [(set (match_operand:V16QI 0 "register_operand" "=x")
23719         (vec_concat:V16QI
23720          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23721          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23722   "TARGET_SSE2"
23723   "packuswb\t{%2, %0|%0, %2}"
23724   [(set_attr "type" "ssecvt")
23725    (set_attr "mode" "TI")])
23726
23727 (define_insn "sse2_punpckhbw"
23728   [(set (match_operand:V16QI 0 "register_operand" "=x")
23729         (vec_merge:V16QI
23730          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23731                            (parallel [(const_int 8) (const_int 0)
23732                                       (const_int 9) (const_int 1)
23733                                       (const_int 10) (const_int 2)
23734                                       (const_int 11) (const_int 3)
23735                                       (const_int 12) (const_int 4)
23736                                       (const_int 13) (const_int 5)
23737                                       (const_int 14) (const_int 6)
23738                                       (const_int 15) (const_int 7)]))
23739          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23740                            (parallel [(const_int 0) (const_int 8)
23741                                       (const_int 1) (const_int 9)
23742                                       (const_int 2) (const_int 10)
23743                                       (const_int 3) (const_int 11)
23744                                       (const_int 4) (const_int 12)
23745                                       (const_int 5) (const_int 13)
23746                                       (const_int 6) (const_int 14)
23747                                       (const_int 7) (const_int 15)]))
23748          (const_int 21845)))]
23749   "TARGET_SSE2"
23750   "punpckhbw\t{%2, %0|%0, %2}"
23751   [(set_attr "type" "ssecvt")
23752    (set_attr "mode" "TI")])
23753
23754 (define_insn "sse2_punpckhwd"
23755   [(set (match_operand:V8HI 0 "register_operand" "=x")
23756         (vec_merge:V8HI
23757          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23758                           (parallel [(const_int 4) (const_int 0)
23759                                      (const_int 5) (const_int 1)
23760                                      (const_int 6) (const_int 2)
23761                                      (const_int 7) (const_int 3)]))
23762          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23763                           (parallel [(const_int 0) (const_int 4)
23764                                      (const_int 1) (const_int 5)
23765                                      (const_int 2) (const_int 6)
23766                                      (const_int 3) (const_int 7)]))
23767          (const_int 85)))]
23768   "TARGET_SSE2"
23769   "punpckhwd\t{%2, %0|%0, %2}"
23770   [(set_attr "type" "ssecvt")
23771    (set_attr "mode" "TI")])
23772
23773 (define_insn "sse2_punpckhdq"
23774   [(set (match_operand:V4SI 0 "register_operand" "=x")
23775         (vec_merge:V4SI
23776          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23777                           (parallel [(const_int 2) (const_int 0)
23778                                      (const_int 3) (const_int 1)]))
23779          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23780                           (parallel [(const_int 0) (const_int 2)
23781                                      (const_int 1) (const_int 3)]))
23782          (const_int 5)))]
23783   "TARGET_SSE2"
23784   "punpckhdq\t{%2, %0|%0, %2}"
23785   [(set_attr "type" "ssecvt")
23786    (set_attr "mode" "TI")])
23787
23788 (define_insn "sse2_punpcklbw"
23789   [(set (match_operand:V16QI 0 "register_operand" "=x")
23790         (vec_merge:V16QI
23791          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23792                            (parallel [(const_int 0) (const_int 8)
23793                                       (const_int 1) (const_int 9)
23794                                       (const_int 2) (const_int 10)
23795                                       (const_int 3) (const_int 11)
23796                                       (const_int 4) (const_int 12)
23797                                       (const_int 5) (const_int 13)
23798                                       (const_int 6) (const_int 14)
23799                                       (const_int 7) (const_int 15)]))
23800          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23801                            (parallel [(const_int 8) (const_int 0)
23802                                       (const_int 9) (const_int 1)
23803                                       (const_int 10) (const_int 2)
23804                                       (const_int 11) (const_int 3)
23805                                       (const_int 12) (const_int 4)
23806                                       (const_int 13) (const_int 5)
23807                                       (const_int 14) (const_int 6)
23808                                       (const_int 15) (const_int 7)]))
23809          (const_int 21845)))]
23810   "TARGET_SSE2"
23811   "punpcklbw\t{%2, %0|%0, %2}"
23812   [(set_attr "type" "ssecvt")
23813    (set_attr "mode" "TI")])
23814
23815 (define_insn "sse2_punpcklwd"
23816   [(set (match_operand:V8HI 0 "register_operand" "=x")
23817         (vec_merge:V8HI
23818          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23819                           (parallel [(const_int 0) (const_int 4)
23820                                      (const_int 1) (const_int 5)
23821                                      (const_int 2) (const_int 6)
23822                                      (const_int 3) (const_int 7)]))
23823          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23824                           (parallel [(const_int 4) (const_int 0)
23825                                      (const_int 5) (const_int 1)
23826                                      (const_int 6) (const_int 2)
23827                                      (const_int 7) (const_int 3)]))
23828          (const_int 85)))]
23829   "TARGET_SSE2"
23830   "punpcklwd\t{%2, %0|%0, %2}"
23831   [(set_attr "type" "ssecvt")
23832    (set_attr "mode" "TI")])
23833
23834 (define_insn "sse2_punpckldq"
23835   [(set (match_operand:V4SI 0 "register_operand" "=x")
23836         (vec_merge:V4SI
23837          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23838                           (parallel [(const_int 0) (const_int 2)
23839                                      (const_int 1) (const_int 3)]))
23840          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23841                           (parallel [(const_int 2) (const_int 0)
23842                                      (const_int 3) (const_int 1)]))
23843          (const_int 5)))]
23844   "TARGET_SSE2"
23845   "punpckldq\t{%2, %0|%0, %2}"
23846   [(set_attr "type" "ssecvt")
23847    (set_attr "mode" "TI")])
23848
23849 (define_insn "sse2_punpcklqdq"
23850   [(set (match_operand:V2DI 0 "register_operand" "=x")
23851         (vec_merge:V2DI
23852          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23853                           (parallel [(const_int 1)
23854                                      (const_int 0)]))
23855          (match_operand:V2DI 1 "register_operand" "0")
23856          (const_int 1)))]
23857   "TARGET_SSE2"
23858   "punpcklqdq\t{%2, %0|%0, %2}"
23859   [(set_attr "type" "ssecvt")
23860    (set_attr "mode" "TI")])
23861
23862 (define_insn "sse2_punpckhqdq"
23863   [(set (match_operand:V2DI 0 "register_operand" "=x")
23864         (vec_merge:V2DI
23865          (match_operand:V2DI 1 "register_operand" "0")
23866          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23867                           (parallel [(const_int 1)
23868                                      (const_int 0)]))
23869          (const_int 1)))]
23870   "TARGET_SSE2"
23871   "punpckhqdq\t{%2, %0|%0, %2}"
23872   [(set_attr "type" "ssecvt")
23873    (set_attr "mode" "TI")])
23874
23875 ;; SSE2 moves
23876
23877 (define_insn "sse2_movapd"
23878   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23879         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23880                      UNSPEC_MOVA))]
23881   "TARGET_SSE2
23882    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23883   "movapd\t{%1, %0|%0, %1}"
23884   [(set_attr "type" "ssemov")
23885    (set_attr "mode" "V2DF")])
23886
23887 (define_insn "sse2_movupd"
23888   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23889         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23890                      UNSPEC_MOVU))]
23891   "TARGET_SSE2
23892    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23893   "movupd\t{%1, %0|%0, %1}"
23894   [(set_attr "type" "ssecvt")
23895    (set_attr "mode" "V2DF")])
23896
23897 (define_insn "sse2_movdqa"
23898   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23899         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23900                        UNSPEC_MOVA))]
23901   "TARGET_SSE2
23902    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23903   "movdqa\t{%1, %0|%0, %1}"
23904   [(set_attr "type" "ssemov")
23905    (set_attr "mode" "TI")])
23906
23907 (define_insn "sse2_movdqu"
23908   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23909         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23910                        UNSPEC_MOVU))]
23911   "TARGET_SSE2
23912    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23913   "movdqu\t{%1, %0|%0, %1}"
23914   [(set_attr "type" "ssecvt")
23915    (set_attr "mode" "TI")])
23916
23917 (define_insn "sse2_movdq2q"
23918   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23919         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23920                        (parallel [(const_int 0)])))]
23921   "TARGET_SSE2 && !TARGET_64BIT"
23922   "@
23923    movq\t{%1, %0|%0, %1}
23924    movdq2q\t{%1, %0|%0, %1}"
23925   [(set_attr "type" "ssecvt")
23926    (set_attr "mode" "TI")])
23927
23928 (define_insn "sse2_movdq2q_rex64"
23929   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23930         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23931                        (parallel [(const_int 0)])))]
23932   "TARGET_SSE2 && TARGET_64BIT"
23933   "@
23934    movq\t{%1, %0|%0, %1}
23935    movdq2q\t{%1, %0|%0, %1}
23936    movd\t{%1, %0|%0, %1}"
23937   [(set_attr "type" "ssecvt")
23938    (set_attr "mode" "TI")])
23939
23940 (define_insn "sse2_movq2dq"
23941   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23942         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23943                          (const_int 0)))]
23944   "TARGET_SSE2 && !TARGET_64BIT"
23945   "@
23946    movq\t{%1, %0|%0, %1}
23947    movq2dq\t{%1, %0|%0, %1}"
23948   [(set_attr "type" "ssecvt,ssemov")
23949    (set_attr "mode" "TI")])
23950
23951 (define_insn "sse2_movq2dq_rex64"
23952   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23953         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23954                          (const_int 0)))]
23955   "TARGET_SSE2 && TARGET_64BIT"
23956   "@
23957    movq\t{%1, %0|%0, %1}
23958    movq2dq\t{%1, %0|%0, %1}
23959    movd\t{%1, %0|%0, %1}"
23960   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23961    (set_attr "mode" "TI")])
23962
23963 (define_insn "sse2_movq"
23964   [(set (match_operand:V2DI 0 "register_operand" "=x")
23965         (vec_concat:V2DI (vec_select:DI
23966                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23967                           (parallel [(const_int 0)]))
23968                          (const_int 0)))]
23969   "TARGET_SSE2"
23970   "movq\t{%1, %0|%0, %1}"
23971   [(set_attr "type" "ssemov")
23972    (set_attr "mode" "TI")])
23973
23974 (define_insn "sse2_loadd"
23975   [(set (match_operand:V4SI 0 "register_operand" "=x")
23976         (vec_merge:V4SI
23977          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23978          (const_vector:V4SI [(const_int 0)
23979                              (const_int 0)
23980                              (const_int 0)
23981                              (const_int 0)])
23982          (const_int 1)))]
23983   "TARGET_SSE2"
23984   "movd\t{%1, %0|%0, %1}"
23985   [(set_attr "type" "ssemov")
23986    (set_attr "mode" "TI")])
23987
23988 (define_insn "sse2_stored"
23989   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23990         (vec_select:SI
23991          (match_operand:V4SI 1 "register_operand" "x")
23992          (parallel [(const_int 0)])))]
23993   "TARGET_SSE2"
23994   "movd\t{%1, %0|%0, %1}"
23995   [(set_attr "type" "ssemov")
23996    (set_attr "mode" "TI")])
23997
23998 (define_insn "sse2_movhpd"
23999   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24000         (vec_merge:V2DF
24001          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24002          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24003          (const_int 1)))]
24004   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24005   "movhpd\t{%2, %0|%0, %2}"
24006   [(set_attr "type" "ssecvt")
24007    (set_attr "mode" "V2DF")])
24008
24009 (define_expand "sse2_loadsd"
24010   [(match_operand:V2DF 0 "register_operand" "")
24011    (match_operand:DF 1 "memory_operand" "")]
24012   "TARGET_SSE2"
24013 {
24014   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24015                                 CONST0_RTX (V2DFmode)));
24016   DONE;
24017 })
24018
24019 (define_insn "sse2_loadsd_1"
24020   [(set (match_operand:V2DF 0 "register_operand" "=x")
24021         (vec_merge:V2DF
24022          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24023          (match_operand:V2DF 2 "const0_operand" "X")
24024          (const_int 1)))]
24025   "TARGET_SSE2"
24026   "movsd\t{%1, %0|%0, %1}"
24027   [(set_attr "type" "ssecvt")
24028    (set_attr "mode" "DF")])
24029
24030 (define_insn "sse2_movsd"
24031   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24032         (vec_merge:V2DF
24033          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24034          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24035          (const_int 2)))]
24036   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24037   "@movsd\t{%2, %0|%0, %2}
24038     movlpd\t{%2, %0|%0, %2}
24039     movlpd\t{%2, %0|%0, %2}"
24040   [(set_attr "type" "ssecvt")
24041    (set_attr "mode" "DF,V2DF,V2DF")])
24042
24043 (define_insn "sse2_storesd"
24044   [(set (match_operand:DF 0 "memory_operand" "=m")
24045         (vec_select:DF
24046          (match_operand:V2DF 1 "register_operand" "x")
24047          (parallel [(const_int 0)])))]
24048   "TARGET_SSE2"
24049   "movsd\t{%1, %0|%0, %1}"
24050   [(set_attr "type" "ssecvt")
24051    (set_attr "mode" "DF")])
24052
24053 (define_insn "sse2_shufpd"
24054   [(set (match_operand:V2DF 0 "register_operand" "=x")
24055         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24056                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24057                       (match_operand:SI 3 "immediate_operand" "i")]
24058                      UNSPEC_SHUFFLE))]
24059   "TARGET_SSE2"
24060   ;; @@@ check operand order for intel/nonintel syntax
24061   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24062   [(set_attr "type" "ssecvt")
24063    (set_attr "mode" "V2DF")])
24064
24065 (define_insn "sse2_clflush"
24066   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24067                     UNSPECV_CLFLUSH)]
24068   "TARGET_SSE2"
24069   "clflush\t%a0"
24070   [(set_attr "type" "sse")
24071    (set_attr "memory" "unknown")])
24072
24073 (define_expand "sse2_mfence"
24074   [(set (match_dup 0)
24075         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24076   "TARGET_SSE2"
24077 {
24078   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24079   MEM_VOLATILE_P (operands[0]) = 1;
24080 })
24081
24082 (define_insn "*mfence_insn"
24083   [(set (match_operand:BLK 0 "" "")
24084         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24085   "TARGET_SSE2"
24086   "mfence"
24087   [(set_attr "type" "sse")
24088    (set_attr "memory" "unknown")])
24089
24090 (define_expand "sse2_lfence"
24091   [(set (match_dup 0)
24092         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24093   "TARGET_SSE2"
24094 {
24095   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24096   MEM_VOLATILE_P (operands[0]) = 1;
24097 })
24098
24099 (define_insn "*lfence_insn"
24100   [(set (match_operand:BLK 0 "" "")
24101         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24102   "TARGET_SSE2"
24103   "lfence"
24104   [(set_attr "type" "sse")
24105    (set_attr "memory" "unknown")])
24106
24107 ;; SSE3
24108
24109 (define_insn "mwait"
24110   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24111                      (match_operand:SI 1 "register_operand" "c")]
24112                     UNSPECV_MWAIT)]
24113   "TARGET_SSE3"
24114   "mwait\t%0, %1"
24115   [(set_attr "length" "3")])
24116
24117 (define_insn "monitor"
24118   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24119                      (match_operand:SI 1 "register_operand" "c")
24120                      (match_operand:SI 2 "register_operand" "d")]
24121                     UNSPECV_MONITOR)]
24122   "TARGET_SSE3"
24123   "monitor\t%0, %1, %2"
24124   [(set_attr "length" "3")])
24125
24126 ;; SSE3 arithmetic
24127
24128 (define_insn "addsubv4sf3"
24129   [(set (match_operand:V4SF 0 "register_operand" "=x")
24130         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24131                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24132                      UNSPEC_ADDSUB))]
24133   "TARGET_SSE3"
24134   "addsubps\t{%2, %0|%0, %2}"
24135   [(set_attr "type" "sseadd")
24136    (set_attr "mode" "V4SF")])
24137
24138 (define_insn "addsubv2df3"
24139   [(set (match_operand:V2DF 0 "register_operand" "=x")
24140         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24141                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24142                      UNSPEC_ADDSUB))]
24143   "TARGET_SSE3"
24144   "addsubpd\t{%2, %0|%0, %2}"
24145   [(set_attr "type" "sseadd")
24146    (set_attr "mode" "V2DF")])
24147
24148 (define_insn "haddv4sf3"
24149   [(set (match_operand:V4SF 0 "register_operand" "=x")
24150         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24151                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24152                      UNSPEC_HADD))]
24153   "TARGET_SSE3"
24154   "haddps\t{%2, %0|%0, %2}"
24155   [(set_attr "type" "sseadd")
24156    (set_attr "mode" "V4SF")])
24157
24158 (define_insn "haddv2df3"
24159   [(set (match_operand:V2DF 0 "register_operand" "=x")
24160         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24161                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24162                      UNSPEC_HADD))]
24163   "TARGET_SSE3"
24164   "haddpd\t{%2, %0|%0, %2}"
24165   [(set_attr "type" "sseadd")
24166    (set_attr "mode" "V2DF")])
24167
24168 (define_insn "hsubv4sf3"
24169   [(set (match_operand:V4SF 0 "register_operand" "=x")
24170         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24171                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24172                      UNSPEC_HSUB))]
24173   "TARGET_SSE3"
24174   "hsubps\t{%2, %0|%0, %2}"
24175   [(set_attr "type" "sseadd")
24176    (set_attr "mode" "V4SF")])
24177
24178 (define_insn "hsubv2df3"
24179   [(set (match_operand:V2DF 0 "register_operand" "=x")
24180         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24181                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24182                      UNSPEC_HSUB))]
24183   "TARGET_SSE3"
24184   "hsubpd\t{%2, %0|%0, %2}"
24185   [(set_attr "type" "sseadd")
24186    (set_attr "mode" "V2DF")])
24187
24188 (define_insn "movshdup"
24189   [(set (match_operand:V4SF 0 "register_operand" "=x")
24190         (unspec:V4SF
24191          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24192   "TARGET_SSE3"
24193   "movshdup\t{%1, %0|%0, %1}"
24194   [(set_attr "type" "sse")
24195    (set_attr "mode" "V4SF")])
24196
24197 (define_insn "movsldup"
24198   [(set (match_operand:V4SF 0 "register_operand" "=x")
24199         (unspec:V4SF
24200          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24201   "TARGET_SSE3"
24202   "movsldup\t{%1, %0|%0, %1}"
24203   [(set_attr "type" "sse")
24204    (set_attr "mode" "V4SF")])
24205
24206 (define_insn "lddqu"
24207   [(set (match_operand:V16QI 0 "register_operand" "=x")
24208         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24209                        UNSPEC_LDQQU))]
24210   "TARGET_SSE3"
24211   "lddqu\t{%1, %0|%0, %1}"
24212   [(set_attr "type" "ssecvt")
24213    (set_attr "mode" "TI")])
24214
24215 (define_insn "loadddup"
24216   [(set (match_operand:V2DF 0 "register_operand" "=x")
24217         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24218   "TARGET_SSE3"
24219   "movddup\t{%1, %0|%0, %1}"
24220   [(set_attr "type" "ssecvt")
24221    (set_attr "mode" "DF")])
24222
24223 (define_insn "movddup"
24224   [(set (match_operand:V2DF 0 "register_operand" "=x")
24225         (vec_duplicate:V2DF
24226          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24227                         (parallel [(const_int 0)]))))]
24228   "TARGET_SSE3"
24229   "movddup\t{%1, %0|%0, %1}"
24230   [(set_attr "type" "ssecvt")
24231    (set_attr "mode" "DF")])