OSDN Git Service

* config/i386/i386.md (sse_loadhps splitter): Fix operand number typo.
[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, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1108  
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1116 {
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand"
1126                         "=r  ,m  ,!*y,!rm,!*y,!*x,!rm,!*x")
1127         (match_operand:SI 1 "general_operand"
1128                         "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1129   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1131 {
1132   switch (get_attr_type (insn))
1133     {
1134     case TYPE_SSEMOV:
1135       if (get_attr_mode (insn) == MODE_TI)
1136         return "movdqa\t{%1, %0|%0, %1}";
1137       return "movd\t{%1, %0|%0, %1}";
1138
1139     case TYPE_MMXMOV:
1140       if (get_attr_mode (insn) == MODE_DI)
1141         return "movq\t{%1, %0|%0, %1}";
1142       return "movd\t{%1, %0|%0, %1}";
1143
1144     case TYPE_LEA:
1145       return "lea{l}\t{%1, %0|%0, %1}";
1146
1147     default:
1148       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1149         abort();
1150       return "mov{l}\t{%1, %0|%0, %1}";
1151     }
1152 }
1153   [(set (attr "type")
1154      (cond [(eq_attr "alternative" "2,3,4")
1155               (const_string "mmxmov")
1156             (eq_attr "alternative" "5,6,7")
1157               (const_string "ssemov")
1158             (and (ne (symbol_ref "flag_pic") (const_int 0))
1159                  (match_operand:SI 1 "symbolic_operand" ""))
1160               (const_string "lea")
1161            ]
1162            (const_string "imov")))
1163    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1164
1165 (define_insn "*movsi_1_nointernunit"
1166   [(set (match_operand:SI 0 "nonimmediate_operand"
1167                         "=r  ,m  ,!*y,!m,!*y,!*x,!m,!*x")
1168         (match_operand:SI 1 "general_operand"
1169                         "rinm,rin,*y ,*y,m  ,*x ,*x,m"))]
1170   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1172 {
1173   switch (get_attr_type (insn))
1174     {
1175     case TYPE_SSEMOV:
1176       if (get_attr_mode (insn) == MODE_TI)
1177         return "movdqa\t{%1, %0|%0, %1}";
1178       return "movd\t{%1, %0|%0, %1}";
1179
1180     case TYPE_MMXMOV:
1181       if (get_attr_mode (insn) == MODE_DI)
1182         return "movq\t{%1, %0|%0, %1}";
1183       return "movd\t{%1, %0|%0, %1}";
1184
1185     case TYPE_LEA:
1186       return "lea{l}\t{%1, %0|%0, %1}";
1187
1188     default:
1189       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1190         abort();
1191       return "mov{l}\t{%1, %0|%0, %1}";
1192     }
1193 }
1194   [(set (attr "type")
1195      (cond [(eq_attr "alternative" "2,3,4")
1196               (const_string "mmxmov")
1197             (eq_attr "alternative" "5,6,7")
1198               (const_string "ssemov")
1199             (and (ne (symbol_ref "flag_pic") (const_int 0))
1200                  (match_operand:SI 1 "symbolic_operand" ""))
1201               (const_string "lea")
1202            ]
1203            (const_string "imov")))
1204    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1205
1206 ;; Stores and loads of ax to arbitrary constant address.
1207 ;; We fake an second form of instruction to force reload to load address
1208 ;; into register when rax is not available
1209 (define_insn "*movabssi_1_rex64"
1210   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1211         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1212   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1213   "@
1214    movabs{l}\t{%1, %P0|%P0, %1}
1215    mov{l}\t{%1, %a0|%a0, %1}"
1216   [(set_attr "type" "imov")
1217    (set_attr "modrm" "0,*")
1218    (set_attr "length_address" "8,0")
1219    (set_attr "length_immediate" "0,*")
1220    (set_attr "memory" "store")
1221    (set_attr "mode" "SI")])
1222
1223 (define_insn "*movabssi_2_rex64"
1224   [(set (match_operand:SI 0 "register_operand" "=a,r")
1225         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1226   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1227   "@
1228    movabs{l}\t{%P1, %0|%0, %P1}
1229    mov{l}\t{%a1, %0|%0, %a1}"
1230   [(set_attr "type" "imov")
1231    (set_attr "modrm" "0,*")
1232    (set_attr "length_address" "8,0")
1233    (set_attr "length_immediate" "0")
1234    (set_attr "memory" "load")
1235    (set_attr "mode" "SI")])
1236
1237 (define_insn "*swapsi"
1238   [(set (match_operand:SI 0 "register_operand" "+r")
1239         (match_operand:SI 1 "register_operand" "+r"))
1240    (set (match_dup 1)
1241         (match_dup 0))]
1242   ""
1243   "xchg{l}\t%1, %0"
1244   [(set_attr "type" "imov")
1245    (set_attr "mode" "SI")
1246    (set_attr "pent_pair" "np")
1247    (set_attr "athlon_decode" "vector")])
1248
1249 (define_expand "movhi"
1250   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1251         (match_operand:HI 1 "general_operand" ""))]
1252   ""
1253   "ix86_expand_move (HImode, operands); DONE;")
1254
1255 (define_insn "*pushhi2"
1256   [(set (match_operand:HI 0 "push_operand" "=<,<")
1257         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1258   "!TARGET_64BIT"
1259   "@
1260    push{w}\t{|WORD PTR }%1
1261    push{w}\t%1"
1262   [(set_attr "type" "push")
1263    (set_attr "mode" "HI")])
1264
1265 ;; For 64BIT abi we always round up to 8 bytes.
1266 (define_insn "*pushhi2_rex64"
1267   [(set (match_operand:HI 0 "push_operand" "=X")
1268         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1269   "TARGET_64BIT"
1270   "push{q}\t%q1"
1271   [(set_attr "type" "push")
1272    (set_attr "mode" "QI")])
1273
1274 (define_insn "*movhi_1"
1275   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1276         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1277   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1278 {
1279   switch (get_attr_type (insn))
1280     {
1281     case TYPE_IMOVX:
1282       /* movzwl is faster than movw on p2 due to partial word stalls,
1283          though not as fast as an aligned movl.  */
1284       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1285     default:
1286       if (get_attr_mode (insn) == MODE_SI)
1287         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1288       else
1289         return "mov{w}\t{%1, %0|%0, %1}";
1290     }
1291 }
1292   [(set (attr "type")
1293      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1294               (const_string "imov")
1295             (and (eq_attr "alternative" "0")
1296                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1297                           (const_int 0))
1298                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1299                           (const_int 0))))
1300               (const_string "imov")
1301             (and (eq_attr "alternative" "1,2")
1302                  (match_operand:HI 1 "aligned_operand" ""))
1303               (const_string "imov")
1304             (and (ne (symbol_ref "TARGET_MOVX")
1305                      (const_int 0))
1306                  (eq_attr "alternative" "0,2"))
1307               (const_string "imovx")
1308            ]
1309            (const_string "imov")))
1310     (set (attr "mode")
1311       (cond [(eq_attr "type" "imovx")
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "1,2")
1314                   (match_operand:HI 1 "aligned_operand" ""))
1315                (const_string "SI")
1316              (and (eq_attr "alternative" "0")
1317                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                            (const_int 0))
1319                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                            (const_int 0))))
1321                (const_string "SI")
1322             ]
1323             (const_string "HI")))])
1324
1325 ;; Stores and loads of ax to arbitrary constant address.
1326 ;; We fake an second form of instruction to force reload to load address
1327 ;; into register when rax is not available
1328 (define_insn "*movabshi_1_rex64"
1329   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1330         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1331   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1332   "@
1333    movabs{w}\t{%1, %P0|%P0, %1}
1334    mov{w}\t{%1, %a0|%a0, %1}"
1335   [(set_attr "type" "imov")
1336    (set_attr "modrm" "0,*")
1337    (set_attr "length_address" "8,0")
1338    (set_attr "length_immediate" "0,*")
1339    (set_attr "memory" "store")
1340    (set_attr "mode" "HI")])
1341
1342 (define_insn "*movabshi_2_rex64"
1343   [(set (match_operand:HI 0 "register_operand" "=a,r")
1344         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1345   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1346   "@
1347    movabs{w}\t{%P1, %0|%0, %P1}
1348    mov{w}\t{%a1, %0|%0, %a1}"
1349   [(set_attr "type" "imov")
1350    (set_attr "modrm" "0,*")
1351    (set_attr "length_address" "8,0")
1352    (set_attr "length_immediate" "0")
1353    (set_attr "memory" "load")
1354    (set_attr "mode" "HI")])
1355
1356 (define_insn "*swaphi_1"
1357   [(set (match_operand:HI 0 "register_operand" "+r")
1358         (match_operand:HI 1 "register_operand" "+r"))
1359    (set (match_dup 1)
1360         (match_dup 0))]
1361   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1362   "xchg{l}\t%k1, %k0"
1363   [(set_attr "type" "imov")
1364    (set_attr "mode" "SI")
1365    (set_attr "pent_pair" "np")
1366    (set_attr "athlon_decode" "vector")])
1367
1368 (define_insn "*swaphi_2"
1369   [(set (match_operand:HI 0 "register_operand" "+r")
1370         (match_operand:HI 1 "register_operand" "+r"))
1371    (set (match_dup 1)
1372         (match_dup 0))]
1373   "TARGET_PARTIAL_REG_STALL"
1374   "xchg{w}\t%1, %0"
1375   [(set_attr "type" "imov")
1376    (set_attr "mode" "HI")
1377    (set_attr "pent_pair" "np")
1378    (set_attr "athlon_decode" "vector")])
1379
1380 (define_expand "movstricthi"
1381   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1382         (match_operand:HI 1 "general_operand" ""))]
1383   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1384 {
1385   /* Don't generate memory->memory moves, go through a register */
1386   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1387     operands[1] = force_reg (HImode, operands[1]);
1388 })
1389
1390 (define_insn "*movstricthi_1"
1391   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1392         (match_operand:HI 1 "general_operand" "rn,m"))]
1393   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1394    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1395   "mov{w}\t{%1, %0|%0, %1}"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")])
1398
1399 (define_insn "*movstricthi_xor"
1400   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1401         (match_operand:HI 1 "const0_operand" "i"))
1402    (clobber (reg:CC FLAGS_REG))]
1403   "reload_completed
1404    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1405   "xor{w}\t{%0, %0|%0, %0}"
1406   [(set_attr "type" "alu1")
1407    (set_attr "mode" "HI")
1408    (set_attr "length_immediate" "0")])
1409
1410 (define_expand "movqi"
1411   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1412         (match_operand:QI 1 "general_operand" ""))]
1413   ""
1414   "ix86_expand_move (QImode, operands); DONE;")
1415
1416 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1417 ;; "push a byte".  But actually we use pushw, which has the effect
1418 ;; of rounding the amount pushed up to a halfword.
1419
1420 (define_insn "*pushqi2"
1421   [(set (match_operand:QI 0 "push_operand" "=X,X")
1422         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1423   "!TARGET_64BIT"
1424   "@
1425    push{w}\t{|word ptr }%1
1426    push{w}\t%w1"
1427   [(set_attr "type" "push")
1428    (set_attr "mode" "HI")])
1429
1430 ;; For 64BIT abi we always round up to 8 bytes.
1431 (define_insn "*pushqi2_rex64"
1432   [(set (match_operand:QI 0 "push_operand" "=X")
1433         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1434   "TARGET_64BIT"
1435   "push{q}\t%q1"
1436   [(set_attr "type" "push")
1437    (set_attr "mode" "QI")])
1438
1439 ;; Situation is quite tricky about when to choose full sized (SImode) move
1440 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1441 ;; partial register dependency machines (such as AMD Athlon), where QImode
1442 ;; moves issue extra dependency and for partial register stalls machines
1443 ;; that don't use QImode patterns (and QImode move cause stall on the next
1444 ;; instruction).
1445 ;;
1446 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1447 ;; register stall machines with, where we use QImode instructions, since
1448 ;; partial register stall can be caused there.  Then we use movzx.
1449 (define_insn "*movqi_1"
1450   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1451         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1452   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1453 {
1454   switch (get_attr_type (insn))
1455     {
1456     case TYPE_IMOVX:
1457       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1458         abort ();
1459       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1460     default:
1461       if (get_attr_mode (insn) == MODE_SI)
1462         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1463       else
1464         return "mov{b}\t{%1, %0|%0, %1}";
1465     }
1466 }
1467   [(set (attr "type")
1468      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1469               (const_string "imov")
1470             (and (eq_attr "alternative" "3")
1471                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1472                           (const_int 0))
1473                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1474                           (const_int 0))))
1475               (const_string "imov")
1476             (eq_attr "alternative" "3,5")
1477               (const_string "imovx")
1478             (and (ne (symbol_ref "TARGET_MOVX")
1479                      (const_int 0))
1480                  (eq_attr "alternative" "2"))
1481               (const_string "imovx")
1482            ]
1483            (const_string "imov")))
1484    (set (attr "mode")
1485       (cond [(eq_attr "alternative" "3,4,5")
1486                (const_string "SI")
1487              (eq_attr "alternative" "6")
1488                (const_string "QI")
1489              (eq_attr "type" "imovx")
1490                (const_string "SI")
1491              (and (eq_attr "type" "imov")
1492                   (and (eq_attr "alternative" "0,1")
1493                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1494                            (const_int 0))))
1495                (const_string "SI")
1496              ;; Avoid partial register stalls when not using QImode arithmetic
1497              (and (eq_attr "type" "imov")
1498                   (and (eq_attr "alternative" "0,1")
1499                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500                                 (const_int 0))
1501                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1502                                 (const_int 0)))))
1503                (const_string "SI")
1504            ]
1505            (const_string "QI")))])
1506
1507 (define_expand "reload_outqi"
1508   [(parallel [(match_operand:QI 0 "" "=m")
1509               (match_operand:QI 1 "register_operand" "r")
1510               (match_operand:QI 2 "register_operand" "=&q")])]
1511   ""
1512 {
1513   rtx op0, op1, op2;
1514   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1515
1516   if (reg_overlap_mentioned_p (op2, op0))
1517     abort ();
1518   if (! q_regs_operand (op1, QImode))
1519     {
1520       emit_insn (gen_movqi (op2, op1));
1521       op1 = op2;
1522     }
1523   emit_insn (gen_movqi (op0, op1));
1524   DONE;
1525 })
1526
1527 (define_insn "*swapqi_1"
1528   [(set (match_operand:QI 0 "register_operand" "+r")
1529         (match_operand:QI 1 "register_operand" "+r"))
1530    (set (match_dup 1)
1531         (match_dup 0))]
1532   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1533   "xchg{l}\t%k1, %k0"
1534   [(set_attr "type" "imov")
1535    (set_attr "mode" "SI")
1536    (set_attr "pent_pair" "np")
1537    (set_attr "athlon_decode" "vector")])
1538
1539 (define_insn "*swapqi_2"
1540   [(set (match_operand:QI 0 "register_operand" "+q")
1541         (match_operand:QI 1 "register_operand" "+q"))
1542    (set (match_dup 1)
1543         (match_dup 0))]
1544   "TARGET_PARTIAL_REG_STALL"
1545   "xchg{b}\t%1, %0"
1546   [(set_attr "type" "imov")
1547    (set_attr "mode" "QI")
1548    (set_attr "pent_pair" "np")
1549    (set_attr "athlon_decode" "vector")])
1550
1551 (define_expand "movstrictqi"
1552   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1553         (match_operand:QI 1 "general_operand" ""))]
1554   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1555 {
1556   /* Don't generate memory->memory moves, go through a register.  */
1557   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1558     operands[1] = force_reg (QImode, operands[1]);
1559 })
1560
1561 (define_insn "*movstrictqi_1"
1562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1563         (match_operand:QI 1 "general_operand" "*qn,m"))]
1564   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1566   "mov{b}\t{%1, %0|%0, %1}"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "QI")])
1569
1570 (define_insn "*movstrictqi_xor"
1571   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1572         (match_operand:QI 1 "const0_operand" "i"))
1573    (clobber (reg:CC FLAGS_REG))]
1574   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1575   "xor{b}\t{%0, %0|%0, %0}"
1576   [(set_attr "type" "alu1")
1577    (set_attr "mode" "QI")
1578    (set_attr "length_immediate" "0")])
1579
1580 (define_insn "*movsi_extv_1"
1581   [(set (match_operand:SI 0 "register_operand" "=R")
1582         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1583                          (const_int 8)
1584                          (const_int 8)))]
1585   ""
1586   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1587   [(set_attr "type" "imovx")
1588    (set_attr "mode" "SI")])
1589
1590 (define_insn "*movhi_extv_1"
1591   [(set (match_operand:HI 0 "register_operand" "=R")
1592         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1593                          (const_int 8)
1594                          (const_int 8)))]
1595   ""
1596   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1597   [(set_attr "type" "imovx")
1598    (set_attr "mode" "SI")])
1599
1600 (define_insn "*movqi_extv_1"
1601   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1602         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1603                          (const_int 8)
1604                          (const_int 8)))]
1605   "!TARGET_64BIT"
1606 {
1607   switch (get_attr_type (insn))
1608     {
1609     case TYPE_IMOVX:
1610       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1611     default:
1612       return "mov{b}\t{%h1, %0|%0, %h1}";
1613     }
1614 }
1615   [(set (attr "type")
1616      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1617                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1618                              (ne (symbol_ref "TARGET_MOVX")
1619                                  (const_int 0))))
1620         (const_string "imovx")
1621         (const_string "imov")))
1622    (set (attr "mode")
1623      (if_then_else (eq_attr "type" "imovx")
1624         (const_string "SI")
1625         (const_string "QI")))])
1626
1627 (define_insn "*movqi_extv_1_rex64"
1628   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1629         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1630                          (const_int 8)
1631                          (const_int 8)))]
1632   "TARGET_64BIT"
1633 {
1634   switch (get_attr_type (insn))
1635     {
1636     case TYPE_IMOVX:
1637       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1638     default:
1639       return "mov{b}\t{%h1, %0|%0, %h1}";
1640     }
1641 }
1642   [(set (attr "type")
1643      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1644                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1645                              (ne (symbol_ref "TARGET_MOVX")
1646                                  (const_int 0))))
1647         (const_string "imovx")
1648         (const_string "imov")))
1649    (set (attr "mode")
1650      (if_then_else (eq_attr "type" "imovx")
1651         (const_string "SI")
1652         (const_string "QI")))])
1653
1654 ;; Stores and loads of ax to arbitrary constant address.
1655 ;; We fake an second form of instruction to force reload to load address
1656 ;; into register when rax is not available
1657 (define_insn "*movabsqi_1_rex64"
1658   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1659         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1660   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1661   "@
1662    movabs{b}\t{%1, %P0|%P0, %1}
1663    mov{b}\t{%1, %a0|%a0, %1}"
1664   [(set_attr "type" "imov")
1665    (set_attr "modrm" "0,*")
1666    (set_attr "length_address" "8,0")
1667    (set_attr "length_immediate" "0,*")
1668    (set_attr "memory" "store")
1669    (set_attr "mode" "QI")])
1670
1671 (define_insn "*movabsqi_2_rex64"
1672   [(set (match_operand:QI 0 "register_operand" "=a,r")
1673         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1675   "@
1676    movabs{b}\t{%P1, %0|%0, %P1}
1677    mov{b}\t{%a1, %0|%0, %a1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0")
1682    (set_attr "memory" "load")
1683    (set_attr "mode" "QI")])
1684
1685 (define_insn "*movsi_extzv_1"
1686   [(set (match_operand:SI 0 "register_operand" "=R")
1687         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1688                          (const_int 8)
1689                          (const_int 8)))]
1690   ""
1691   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1692   [(set_attr "type" "imovx")
1693    (set_attr "mode" "SI")])
1694
1695 (define_insn "*movqi_extzv_2"
1696   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1697         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1698                                     (const_int 8)
1699                                     (const_int 8)) 0))]
1700   "!TARGET_64BIT"
1701 {
1702   switch (get_attr_type (insn))
1703     {
1704     case TYPE_IMOVX:
1705       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1706     default:
1707       return "mov{b}\t{%h1, %0|%0, %h1}";
1708     }
1709 }
1710   [(set (attr "type")
1711      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1712                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1713                              (ne (symbol_ref "TARGET_MOVX")
1714                                  (const_int 0))))
1715         (const_string "imovx")
1716         (const_string "imov")))
1717    (set (attr "mode")
1718      (if_then_else (eq_attr "type" "imovx")
1719         (const_string "SI")
1720         (const_string "QI")))])
1721
1722 (define_insn "*movqi_extzv_2_rex64"
1723   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1724         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1725                                     (const_int 8)
1726                                     (const_int 8)) 0))]
1727   "TARGET_64BIT"
1728 {
1729   switch (get_attr_type (insn))
1730     {
1731     case TYPE_IMOVX:
1732       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733     default:
1734       return "mov{b}\t{%h1, %0|%0, %h1}";
1735     }
1736 }
1737   [(set (attr "type")
1738      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739                         (ne (symbol_ref "TARGET_MOVX")
1740                             (const_int 0)))
1741         (const_string "imovx")
1742         (const_string "imov")))
1743    (set (attr "mode")
1744      (if_then_else (eq_attr "type" "imovx")
1745         (const_string "SI")
1746         (const_string "QI")))])
1747
1748 (define_insn "movsi_insv_1"
1749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1750                          (const_int 8)
1751                          (const_int 8))
1752         (match_operand:SI 1 "general_operand" "Qmn"))]
1753   "!TARGET_64BIT"
1754   "mov{b}\t{%b1, %h0|%h0, %b1}"
1755   [(set_attr "type" "imov")
1756    (set_attr "mode" "QI")])
1757
1758 (define_insn "movdi_insv_1_rex64"
1759   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1760                          (const_int 8)
1761                          (const_int 8))
1762         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1763   "TARGET_64BIT"
1764   "mov{b}\t{%b1, %h0|%h0, %b1}"
1765   [(set_attr "type" "imov")
1766    (set_attr "mode" "QI")])
1767
1768 (define_insn "*movqi_insv_2"
1769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770                          (const_int 8)
1771                          (const_int 8))
1772         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1773                      (const_int 8)))]
1774   ""
1775   "mov{b}\t{%h1, %h0|%h0, %h1}"
1776   [(set_attr "type" "imov")
1777    (set_attr "mode" "QI")])
1778
1779 (define_expand "movdi"
1780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1781         (match_operand:DI 1 "general_operand" ""))]
1782   ""
1783   "ix86_expand_move (DImode, operands); DONE;")
1784
1785 (define_insn "*pushdi"
1786   [(set (match_operand:DI 0 "push_operand" "=<")
1787         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1788   "!TARGET_64BIT"
1789   "#")
1790
1791 (define_insn "*pushdi2_rex64"
1792   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1793         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1794   "TARGET_64BIT"
1795   "@
1796    push{q}\t%1
1797    #"
1798   [(set_attr "type" "push,multi")
1799    (set_attr "mode" "DI")])
1800
1801 ;; Convert impossible pushes of immediate to existing instructions.
1802 ;; First try to get scratch register and go through it.  In case this
1803 ;; fails, push sign extended lower part first and then overwrite
1804 ;; upper part by 32bit move.
1805 (define_peephole2
1806   [(match_scratch:DI 2 "r")
1807    (set (match_operand:DI 0 "push_operand" "")
1808         (match_operand:DI 1 "immediate_operand" ""))]
1809   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1810    && !x86_64_immediate_operand (operands[1], DImode)"
1811   [(set (match_dup 2) (match_dup 1))
1812    (set (match_dup 0) (match_dup 2))]
1813   "")
1814
1815 ;; We need to define this as both peepholer and splitter for case
1816 ;; peephole2 pass is not run.
1817 ;; "&& 1" is needed to keep it from matching the previous pattern.
1818 (define_peephole2
1819   [(set (match_operand:DI 0 "push_operand" "")
1820         (match_operand:DI 1 "immediate_operand" ""))]
1821   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1823   [(set (match_dup 0) (match_dup 1))
1824    (set (match_dup 2) (match_dup 3))]
1825   "split_di (operands + 1, 1, operands + 2, operands + 3);
1826    operands[1] = gen_lowpart (DImode, operands[2]);
1827    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1828                                                     GEN_INT (4)));
1829   ")
1830
1831 (define_split
1832   [(set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1835    && !symbolic_operand (operands[1], DImode)
1836    && !x86_64_immediate_operand (operands[1], DImode)"
1837   [(set (match_dup 0) (match_dup 1))
1838    (set (match_dup 2) (match_dup 3))]
1839   "split_di (operands + 1, 1, operands + 2, operands + 3);
1840    operands[1] = gen_lowpart (DImode, operands[2]);
1841    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842                                                     GEN_INT (4)));
1843   ")
1844
1845 (define_insn "*pushdi2_prologue_rex64"
1846   [(set (match_operand:DI 0 "push_operand" "=<")
1847         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1848    (clobber (mem:BLK (scratch)))]
1849   "TARGET_64BIT"
1850   "push{q}\t%1"
1851   [(set_attr "type" "push")
1852    (set_attr "mode" "DI")])
1853
1854 (define_insn "*popdi1_epilogue_rex64"
1855   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1856         (mem:DI (reg:DI SP_REG)))
1857    (set (reg:DI SP_REG)
1858         (plus:DI (reg:DI SP_REG) (const_int 8)))
1859    (clobber (mem:BLK (scratch)))]
1860   "TARGET_64BIT"
1861   "pop{q}\t%0"
1862   [(set_attr "type" "pop")
1863    (set_attr "mode" "DI")])
1864
1865 (define_insn "popdi1"
1866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867         (mem:DI (reg:DI SP_REG)))
1868    (set (reg:DI SP_REG)
1869         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1870   "TARGET_64BIT"
1871   "pop{q}\t%0"
1872   [(set_attr "type" "pop")
1873    (set_attr "mode" "DI")])
1874
1875 (define_insn "*movdi_xor_rex64"
1876   [(set (match_operand:DI 0 "register_operand" "=r")
1877         (match_operand:DI 1 "const0_operand" "i"))
1878    (clobber (reg:CC FLAGS_REG))]
1879   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1880    && reload_completed"
1881   "xor{l}\t{%k0, %k0|%k0, %k0}"
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "SI")
1884    (set_attr "length_immediate" "0")])
1885
1886 (define_insn "*movdi_or_rex64"
1887   [(set (match_operand:DI 0 "register_operand" "=r")
1888         (match_operand:DI 1 "const_int_operand" "i"))
1889    (clobber (reg:CC FLAGS_REG))]
1890   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1891    && reload_completed
1892    && operands[1] == constm1_rtx"
1893 {
1894   operands[1] = constm1_rtx;
1895   return "or{q}\t{%1, %0|%0, %1}";
1896 }
1897   [(set_attr "type" "alu1")
1898    (set_attr "mode" "DI")
1899    (set_attr "length_immediate" "1")])
1900
1901 (define_insn "*movdi_2"
1902   [(set (match_operand:DI 0 "nonimmediate_operand"
1903                                         "=r  ,o  ,m*y,*y,m ,*Y,*Y,m ,*x,*x")
1904         (match_operand:DI 1 "general_operand"
1905                                         "riFo,riF,*y ,m ,*Y,*Y,m ,*x,*x,m "))]
1906   "!TARGET_64BIT
1907    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1908   "@
1909    #
1910    #
1911    movq\t{%1, %0|%0, %1}
1912    movq\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}
1914    movdqa\t{%1, %0|%0, %1}
1915    movq\t{%1, %0|%0, %1}
1916    movlps\t{%1, %0|%0, %1}
1917    movaps\t{%1, %0|%0, %1}
1918    movlps\t{%1, %0|%0, %1}"
1919   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
1920    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,V2SF,V4SF,V2SF")])
1921
1922 (define_split
1923   [(set (match_operand:DI 0 "push_operand" "")
1924         (match_operand:DI 1 "general_operand" ""))]
1925   "!TARGET_64BIT && reload_completed
1926    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1927   [(const_int 0)]
1928   "ix86_split_long_move (operands); DONE;")
1929
1930 ;; %%% This multiword shite has got to go.
1931 (define_split
1932   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1933         (match_operand:DI 1 "general_operand" ""))]
1934   "!TARGET_64BIT && reload_completed
1935    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1936    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1937   [(const_int 0)]
1938   "ix86_split_long_move (operands); DONE;")
1939
1940 (define_insn "*movdi_1_rex64"
1941   [(set (match_operand:DI 0 "nonimmediate_operand"
1942                 "=r,r  ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1943         (match_operand:DI 1 "general_operand"
1944                 "Z ,rem,i,re,n  ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1945   "TARGET_64BIT
1946    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1947    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1948 {
1949   switch (get_attr_type (insn))
1950     {
1951     case TYPE_SSECVT:
1952       if (which_alternative == 11)
1953         return "movq2dq\t{%1, %0|%0, %1}";
1954       else
1955         return "movdq2q\t{%1, %0|%0, %1}";
1956     case TYPE_SSEMOV:
1957       if (get_attr_mode (insn) == MODE_TI)
1958           return "movdqa\t{%1, %0|%0, %1}";
1959       /* FALLTHRU */
1960     case TYPE_MMXMOV:
1961       /* Moves from and into integer register is done using movd opcode with
1962          REX prefix.  */
1963       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1964           return "movd\t{%1, %0|%0, %1}";
1965       return "movq\t{%1, %0|%0, %1}";
1966     case TYPE_MULTI:
1967       return "#";
1968     case TYPE_LEA:
1969       return "lea{q}\t{%a1, %0|%0, %a1}";
1970     default:
1971       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1972         abort ();
1973       if (get_attr_mode (insn) == MODE_SI)
1974         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1975       else if (which_alternative == 2)
1976         return "movabs{q}\t{%1, %0|%0, %1}";
1977       else
1978         return "mov{q}\t{%1, %0|%0, %1}";
1979     }
1980 }
1981   [(set (attr "type")
1982      (cond [(eq_attr "alternative" "5,6,7")
1983               (const_string "mmxmov")
1984             (eq_attr "alternative" "8,9,10")
1985               (const_string "ssemov")
1986             (eq_attr "alternative" "11,12")
1987               (const_string "ssecvt")
1988             (eq_attr "alternative" "4")
1989               (const_string "multi")
1990             (and (ne (symbol_ref "flag_pic") (const_int 0))
1991                  (match_operand:DI 1 "symbolic_operand" ""))
1992               (const_string "lea")
1993            ]
1994            (const_string "imov")))
1995    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1996    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1997    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1998
1999 (define_insn "*movdi_1_rex64_nointerunit"
2000   [(set (match_operand:DI 0 "nonimmediate_operand"
2001                 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2002         (match_operand:DI 1 "general_operand"
2003                 "Z,rem,i,re,n  ,*y ,*y,m  ,*Y ,*Y,m"))]
2004   "TARGET_64BIT
2005    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2006    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2007 {
2008   switch (get_attr_type (insn))
2009     {
2010     case TYPE_SSEMOV:
2011       if (get_attr_mode (insn) == MODE_TI)
2012           return "movdqa\t{%1, %0|%0, %1}";
2013       /* FALLTHRU */
2014     case TYPE_MMXMOV:
2015       return "movq\t{%1, %0|%0, %1}";
2016     case TYPE_MULTI:
2017       return "#";
2018     case TYPE_LEA:
2019       return "lea{q}\t{%a1, %0|%0, %a1}";
2020     default:
2021       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2022         abort ();
2023       if (get_attr_mode (insn) == MODE_SI)
2024         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2025       else if (which_alternative == 2)
2026         return "movabs{q}\t{%1, %0|%0, %1}";
2027       else
2028         return "mov{q}\t{%1, %0|%0, %1}";
2029     }
2030 }
2031   [(set (attr "type")
2032      (cond [(eq_attr "alternative" "5,6,7")
2033               (const_string "mmxmov")
2034             (eq_attr "alternative" "8,9,10")
2035               (const_string "ssemov")
2036             (eq_attr "alternative" "4")
2037               (const_string "multi")
2038             (and (ne (symbol_ref "flag_pic") (const_int 0))
2039                  (match_operand:DI 1 "symbolic_operand" ""))
2040               (const_string "lea")
2041            ]
2042            (const_string "imov")))
2043    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2044    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2045    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2046
2047 ;; Stores and loads of ax to arbitrary constant address.
2048 ;; We fake an second form of instruction to force reload to load address
2049 ;; into register when rax is not available
2050 (define_insn "*movabsdi_1_rex64"
2051   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2052         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2053   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2054   "@
2055    movabs{q}\t{%1, %P0|%P0, %1}
2056    mov{q}\t{%1, %a0|%a0, %1}"
2057   [(set_attr "type" "imov")
2058    (set_attr "modrm" "0,*")
2059    (set_attr "length_address" "8,0")
2060    (set_attr "length_immediate" "0,*")
2061    (set_attr "memory" "store")
2062    (set_attr "mode" "DI")])
2063
2064 (define_insn "*movabsdi_2_rex64"
2065   [(set (match_operand:DI 0 "register_operand" "=a,r")
2066         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2067   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2068   "@
2069    movabs{q}\t{%P1, %0|%0, %P1}
2070    mov{q}\t{%a1, %0|%0, %a1}"
2071   [(set_attr "type" "imov")
2072    (set_attr "modrm" "0,*")
2073    (set_attr "length_address" "8,0")
2074    (set_attr "length_immediate" "0")
2075    (set_attr "memory" "load")
2076    (set_attr "mode" "DI")])
2077
2078 ;; Convert impossible stores of immediate to existing instructions.
2079 ;; First try to get scratch register and go through it.  In case this
2080 ;; fails, move by 32bit parts.
2081 (define_peephole2
2082   [(match_scratch:DI 2 "r")
2083    (set (match_operand:DI 0 "memory_operand" "")
2084         (match_operand:DI 1 "immediate_operand" ""))]
2085   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2086    && !x86_64_immediate_operand (operands[1], DImode)"
2087   [(set (match_dup 2) (match_dup 1))
2088    (set (match_dup 0) (match_dup 2))]
2089   "")
2090
2091 ;; We need to define this as both peepholer and splitter for case
2092 ;; peephole2 pass is not run.
2093 ;; "&& 1" is needed to keep it from matching the previous pattern.
2094 (define_peephole2
2095   [(set (match_operand:DI 0 "memory_operand" "")
2096         (match_operand:DI 1 "immediate_operand" ""))]
2097   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2098    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2099   [(set (match_dup 2) (match_dup 3))
2100    (set (match_dup 4) (match_dup 5))]
2101   "split_di (operands, 2, operands + 2, operands + 4);")
2102
2103 (define_split
2104   [(set (match_operand:DI 0 "memory_operand" "")
2105         (match_operand:DI 1 "immediate_operand" ""))]
2106   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2107    && !symbolic_operand (operands[1], DImode)
2108    && !x86_64_immediate_operand (operands[1], DImode)"
2109   [(set (match_dup 2) (match_dup 3))
2110    (set (match_dup 4) (match_dup 5))]
2111   "split_di (operands, 2, operands + 2, operands + 4);")
2112
2113 (define_insn "*swapdi_rex64"
2114   [(set (match_operand:DI 0 "register_operand" "+r")
2115         (match_operand:DI 1 "register_operand" "+r"))
2116    (set (match_dup 1)
2117         (match_dup 0))]
2118   "TARGET_64BIT"
2119   "xchg{q}\t%1, %0"
2120   [(set_attr "type" "imov")
2121    (set_attr "mode" "DI")
2122    (set_attr "pent_pair" "np")
2123    (set_attr "athlon_decode" "vector")])
2124
2125 (define_expand "movsf"
2126   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2127         (match_operand:SF 1 "general_operand" ""))]
2128   ""
2129   "ix86_expand_move (SFmode, operands); DONE;")
2130
2131 (define_insn "*pushsf"
2132   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2133         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2134   "!TARGET_64BIT"
2135 {
2136   switch (which_alternative)
2137     {
2138     case 1:
2139       return "push{l}\t%1";
2140
2141     default:
2142       /* This insn should be already split before reg-stack.  */
2143       abort ();
2144     }
2145 }
2146   [(set_attr "type" "multi,push,multi")
2147    (set_attr "mode" "SF,SI,SF")])
2148
2149 (define_insn "*pushsf_rex64"
2150   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2151         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2152   "TARGET_64BIT"
2153 {
2154   switch (which_alternative)
2155     {
2156     case 1:
2157       return "push{q}\t%q1";
2158
2159     default:
2160       /* This insn should be already split before reg-stack.  */
2161       abort ();
2162     }
2163 }
2164   [(set_attr "type" "multi,push,multi")
2165    (set_attr "mode" "SF,DI,SF")])
2166
2167 (define_split
2168   [(set (match_operand:SF 0 "push_operand" "")
2169         (match_operand:SF 1 "memory_operand" ""))]
2170   "reload_completed
2171    && GET_CODE (operands[1]) == MEM
2172    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2173    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2174   [(set (match_dup 0)
2175         (match_dup 1))]
2176   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2177
2178
2179 ;; %%% Kill this when call knows how to work this out.
2180 (define_split
2181   [(set (match_operand:SF 0 "push_operand" "")
2182         (match_operand:SF 1 "any_fp_register_operand" ""))]
2183   "!TARGET_64BIT"
2184   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2185    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2186
2187 (define_split
2188   [(set (match_operand:SF 0 "push_operand" "")
2189         (match_operand:SF 1 "any_fp_register_operand" ""))]
2190   "TARGET_64BIT"
2191   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2192    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2193
2194 (define_insn "*movsf_1"
2195   [(set (match_operand:SF 0 "nonimmediate_operand"
2196           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2197         (match_operand:SF 1 "general_operand"
2198           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2199   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2200    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2201    && (reload_in_progress || reload_completed
2202        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2203        || GET_CODE (operands[1]) != CONST_DOUBLE
2204        || memory_operand (operands[0], SFmode))" 
2205 {
2206   switch (which_alternative)
2207     {
2208     case 0:
2209       return output_387_reg_move (insn, operands);
2210
2211     case 1:
2212       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2213         return "fstp%z0\t%y0";
2214       else
2215         return "fst%z0\t%y0";
2216
2217     case 2:
2218       return standard_80387_constant_opcode (operands[1]);
2219
2220     case 3:
2221     case 4:
2222       return "mov{l}\t{%1, %0|%0, %1}";
2223     case 5:
2224       if (get_attr_mode (insn) == MODE_TI)
2225         return "pxor\t%0, %0";
2226       else
2227         return "xorps\t%0, %0";
2228     case 6:
2229       if (get_attr_mode (insn) == MODE_V4SF)
2230         return "movaps\t{%1, %0|%0, %1}";
2231       else
2232         return "movss\t{%1, %0|%0, %1}";
2233     case 7:
2234     case 8:
2235       return "movss\t{%1, %0|%0, %1}";
2236
2237     case 9:
2238     case 10:
2239       return "movd\t{%1, %0|%0, %1}";
2240
2241     case 11:
2242       return "movq\t{%1, %0|%0, %1}";
2243
2244     default:
2245       abort();
2246     }
2247 }
2248   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2249    (set (attr "mode")
2250         (cond [(eq_attr "alternative" "3,4,9,10")
2251                  (const_string "SI")
2252                (eq_attr "alternative" "5")
2253                  (if_then_else
2254                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2255                                  (const_int 0))
2256                              (ne (symbol_ref "TARGET_SSE2")
2257                                  (const_int 0)))
2258                         (eq (symbol_ref "optimize_size")
2259                             (const_int 0)))
2260                    (const_string "TI")
2261                    (const_string "V4SF"))
2262                /* For architectures resolving dependencies on
2263                   whole SSE registers use APS move to break dependency
2264                   chains, otherwise use short move to avoid extra work. 
2265
2266                   Do the same for architectures resolving dependencies on
2267                   the parts.  While in DF mode it is better to always handle
2268                   just register parts, the SF mode is different due to lack
2269                   of instructions to load just part of the register.  It is
2270                   better to maintain the whole registers in single format
2271                   to avoid problems on using packed logical operations.  */
2272                (eq_attr "alternative" "6")
2273                  (if_then_else
2274                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2275                             (const_int 0))
2276                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2277                             (const_int 0)))
2278                    (const_string "V4SF")
2279                    (const_string "SF"))
2280                (eq_attr "alternative" "11")
2281                  (const_string "DI")]
2282                (const_string "SF")))])
2283
2284 (define_insn "*movsf_1_nointerunit"
2285   [(set (match_operand:SF 0 "nonimmediate_operand"
2286           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!m,!*y")
2287         (match_operand:SF 1 "general_operand"
2288           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,m  ,*y,*y"))]
2289   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2290    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2291    && (reload_in_progress || reload_completed
2292        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2293        || GET_CODE (operands[1]) != CONST_DOUBLE
2294        || memory_operand (operands[0], SFmode))" 
2295 {
2296   switch (which_alternative)
2297     {
2298     case 0:
2299       return output_387_reg_move (insn, operands);
2300
2301     case 1:
2302       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2303         return "fstp%z0\t%y0";
2304       else
2305         return "fst%z0\t%y0";
2306
2307     case 2:
2308       return standard_80387_constant_opcode (operands[1]);
2309
2310     case 3:
2311     case 4:
2312       return "mov{l}\t{%1, %0|%0, %1}";
2313     case 5:
2314       if (get_attr_mode (insn) == MODE_TI)
2315         return "pxor\t%0, %0";
2316       else
2317         return "xorps\t%0, %0";
2318     case 6:
2319       if (get_attr_mode (insn) == MODE_V4SF)
2320         return "movaps\t{%1, %0|%0, %1}";
2321       else
2322         return "movss\t{%1, %0|%0, %1}";
2323     case 7:
2324     case 8:
2325       return "movss\t{%1, %0|%0, %1}";
2326
2327     case 9:
2328     case 10:
2329       return "movd\t{%1, %0|%0, %1}";
2330
2331     case 11:
2332       return "movq\t{%1, %0|%0, %1}";
2333
2334     default:
2335       abort();
2336     }
2337 }
2338   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2339    (set (attr "mode")
2340         (cond [(eq_attr "alternative" "3,4,9,10")
2341                  (const_string "SI")
2342                (eq_attr "alternative" "5")
2343                  (if_then_else
2344                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2345                                  (const_int 0))
2346                              (ne (symbol_ref "TARGET_SSE2")
2347                                  (const_int 0)))
2348                         (eq (symbol_ref "optimize_size")
2349                             (const_int 0)))
2350                    (const_string "TI")
2351                    (const_string "V4SF"))
2352                /* For architectures resolving dependencies on
2353                   whole SSE registers use APS move to break dependency
2354                   chains, otherwise use short move to avoid extra work. 
2355
2356                   Do the same for architectures resolving dependencies on
2357                   the parts.  While in DF mode it is better to always handle
2358                   just register parts, the SF mode is different due to lack
2359                   of instructions to load just part of the register.  It is
2360                   better to maintain the whole registers in single format
2361                   to avoid problems on using packed logical operations.  */
2362                (eq_attr "alternative" "6")
2363                  (if_then_else
2364                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2365                             (const_int 0))
2366                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2367                             (const_int 0)))
2368                    (const_string "V4SF")
2369                    (const_string "SF"))
2370                (eq_attr "alternative" "11")
2371                  (const_string "DI")]
2372                (const_string "SF")))])
2373
2374 (define_insn "*swapsf"
2375   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2376         (match_operand:SF 1 "fp_register_operand" "+f"))
2377    (set (match_dup 1)
2378         (match_dup 0))]
2379   "reload_completed || TARGET_80387"
2380 {
2381   if (STACK_TOP_P (operands[0]))
2382     return "fxch\t%1";
2383   else
2384     return "fxch\t%0";
2385 }
2386   [(set_attr "type" "fxch")
2387    (set_attr "mode" "SF")])
2388
2389 (define_expand "movdf"
2390   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2391         (match_operand:DF 1 "general_operand" ""))]
2392   ""
2393   "ix86_expand_move (DFmode, operands); DONE;")
2394
2395 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2396 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2397 ;; On the average, pushdf using integers can be still shorter.  Allow this
2398 ;; pattern for optimize_size too.
2399
2400 (define_insn "*pushdf_nointeger"
2401   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2402         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2403   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2404 {
2405   /* This insn should be already split before reg-stack.  */
2406   abort ();
2407 }
2408   [(set_attr "type" "multi")
2409    (set_attr "mode" "DF,SI,SI,DF")])
2410
2411 (define_insn "*pushdf_integer"
2412   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2413         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2414   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2415 {
2416   /* This insn should be already split before reg-stack.  */
2417   abort ();
2418 }
2419   [(set_attr "type" "multi")
2420    (set_attr "mode" "DF,SI,DF")])
2421
2422 ;; %%% Kill this when call knows how to work this out.
2423 (define_split
2424   [(set (match_operand:DF 0 "push_operand" "")
2425         (match_operand:DF 1 "any_fp_register_operand" ""))]
2426   "!TARGET_64BIT && reload_completed"
2427   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2428    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2429   "")
2430
2431 (define_split
2432   [(set (match_operand:DF 0 "push_operand" "")
2433         (match_operand:DF 1 "any_fp_register_operand" ""))]
2434   "TARGET_64BIT && reload_completed"
2435   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2436    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2437   "")
2438
2439 (define_split
2440   [(set (match_operand:DF 0 "push_operand" "")
2441         (match_operand:DF 1 "general_operand" ""))]
2442   "reload_completed"
2443   [(const_int 0)]
2444   "ix86_split_long_move (operands); DONE;")
2445
2446 ;; Moving is usually shorter when only FP registers are used. This separate
2447 ;; movdf pattern avoids the use of integer registers for FP operations
2448 ;; when optimizing for size.
2449
2450 (define_insn "*movdf_nointeger"
2451   [(set (match_operand:DF 0 "nonimmediate_operand"
2452                         "=f#Y,m  ,f#Y,*r  ,o  ,Y#f*x,Y#f*x,Y#f*x  ,m    ")
2453         (match_operand:DF 1 "general_operand"
2454                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y#f*x,HmY#f*x,Y#f*x"))]
2455   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2456    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2457    && (reload_in_progress || reload_completed
2458        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2459        || GET_CODE (operands[1]) != CONST_DOUBLE
2460        || memory_operand (operands[0], DFmode))" 
2461 {
2462   switch (which_alternative)
2463     {
2464     case 0:
2465       return output_387_reg_move (insn, operands);
2466
2467     case 1:
2468       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2469         return "fstp%z0\t%y0";
2470       else
2471         return "fst%z0\t%y0";
2472
2473     case 2:
2474       return standard_80387_constant_opcode (operands[1]);
2475
2476     case 3:
2477     case 4:
2478       return "#";
2479     case 5:
2480       switch (get_attr_mode (insn))
2481         {
2482         case MODE_V4SF:
2483           return "xorps\t%0, %0";
2484         case MODE_V2DF:
2485           return "xorpd\t%0, %0";
2486         case MODE_TI:
2487           return "pxor\t%0, %0";
2488         default:
2489           abort ();
2490         }
2491     case 6:
2492     case 7:
2493     case 8:
2494       switch (get_attr_mode (insn))
2495         {
2496         case MODE_V4SF:
2497           return "movaps\t{%1, %0|%0, %1}";
2498         case MODE_V2DF:
2499           return "movapd\t{%1, %0|%0, %1}";
2500         case MODE_TI:
2501           return "movdqa\t{%1, %0|%0, %1}";
2502         case MODE_DI:
2503           return "movq\t{%1, %0|%0, %1}";
2504         case MODE_DF:
2505           return "movsd\t{%1, %0|%0, %1}";
2506         case MODE_V1DF:
2507           return "movlpd\t{%1, %0|%0, %1}";
2508         case MODE_V2SF:
2509           return "movlps\t{%1, %0|%0, %1}";
2510         default:
2511           abort ();
2512         }
2513
2514     default:
2515       abort();
2516     }
2517 }
2518   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2519    (set (attr "mode")
2520         (cond [(eq_attr "alternative" "0,1,2")
2521                  (const_string "DF")
2522                (eq_attr "alternative" "3,4")
2523                  (const_string "SI")
2524
2525                /* For SSE1, we have many fewer alternatives.  */
2526                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2527                  (cond [(eq_attr "alternative" "5,6")
2528                           (const_string "V4SF")
2529                        ]
2530                    (const_string "V2SF"))
2531
2532                /* xorps is one byte shorter.  */
2533                (eq_attr "alternative" "5")
2534                  (cond [(ne (symbol_ref "optimize_size")
2535                             (const_int 0))
2536                           (const_string "V4SF")
2537                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2538                             (const_int 0))
2539                           (const_string "TI")
2540                        ]
2541                        (const_string "V2DF"))
2542
2543                /* For architectures resolving dependencies on
2544                   whole SSE registers use APD move to break dependency
2545                   chains, otherwise use short move to avoid extra work.
2546
2547                   movaps encodes one byte shorter.  */
2548                (eq_attr "alternative" "6")
2549                  (cond
2550                    [(ne (symbol_ref "optimize_size")
2551                         (const_int 0))
2552                       (const_string "V4SF")
2553                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2554                         (const_int 0))
2555                       (const_string "V2DF")
2556                    ]
2557                    (const_string "DF"))
2558                /* For architectures resolving dependencies on register
2559                   parts we may avoid extra work to zero out upper part
2560                   of register.  */
2561                (eq_attr "alternative" "7")
2562                  (if_then_else
2563                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2564                        (const_int 0))
2565                    (const_string "V1DF")
2566                    (const_string "DF"))
2567               ]
2568               (const_string "DF")))])
2569
2570 (define_insn "*movdf_integer"
2571   [(set (match_operand:DF 0 "nonimmediate_operand"
2572                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y#rf*x,Y#rf*x,Y#rf*x,m")
2573         (match_operand:DF 1 "general_operand"
2574                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y#rf*x,m     ,Y#rf*x"))]
2575   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2576    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2577    && (reload_in_progress || reload_completed
2578        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579        || GET_CODE (operands[1]) != CONST_DOUBLE
2580        || memory_operand (operands[0], DFmode))" 
2581 {
2582   switch (which_alternative)
2583     {
2584     case 0:
2585       return output_387_reg_move (insn, operands);
2586
2587     case 1:
2588       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2589         return "fstp%z0\t%y0";
2590       else
2591         return "fst%z0\t%y0";
2592
2593     case 2:
2594       return standard_80387_constant_opcode (operands[1]);
2595
2596     case 3:
2597     case 4:
2598       return "#";
2599
2600     case 5:
2601       switch (get_attr_mode (insn))
2602         {
2603         case MODE_V4SF:
2604           return "xorps\t%0, %0";
2605         case MODE_V2DF:
2606           return "xorpd\t%0, %0";
2607         case MODE_TI:
2608           return "pxor\t%0, %0";
2609         default:
2610           abort ();
2611         }
2612     case 6:
2613     case 7:
2614     case 8:
2615       switch (get_attr_mode (insn))
2616         {
2617         case MODE_V4SF:
2618           return "movaps\t{%1, %0|%0, %1}";
2619         case MODE_V2DF:
2620           return "movapd\t{%1, %0|%0, %1}";
2621         case MODE_TI:
2622           return "movdqa\t{%1, %0|%0, %1}";
2623         case MODE_DI:
2624           return "movq\t{%1, %0|%0, %1}";
2625         case MODE_DF:
2626           return "movsd\t{%1, %0|%0, %1}";
2627         case MODE_V1DF:
2628           return "movlpd\t{%1, %0|%0, %1}";
2629         case MODE_V2SF:
2630           return "movlps\t{%1, %0|%0, %1}";
2631         default:
2632           abort ();
2633         }
2634
2635     default:
2636       abort();
2637     }
2638 }
2639   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2640    (set (attr "mode")
2641         (cond [(eq_attr "alternative" "0,1,2")
2642                  (const_string "DF")
2643                (eq_attr "alternative" "3,4")
2644                  (const_string "SI")
2645
2646                /* For SSE1, we have many fewer alternatives.  */
2647                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2648                  (cond [(eq_attr "alternative" "5,6")
2649                           (const_string "V4SF")
2650                        ]
2651                    (const_string "V2SF"))
2652
2653                /* xorps is one byte shorter.  */
2654                (eq_attr "alternative" "5")
2655                  (cond [(ne (symbol_ref "optimize_size")
2656                             (const_int 0))
2657                           (const_string "V4SF")
2658                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2659                             (const_int 0))
2660                           (const_string "TI")
2661                        ]
2662                        (const_string "V2DF"))
2663
2664                /* For architectures resolving dependencies on
2665                   whole SSE registers use APD move to break dependency
2666                   chains, otherwise use short move to avoid extra work.
2667
2668                   movaps encodes one byte shorter.  */
2669                (eq_attr "alternative" "6")
2670                  (cond
2671                    [(ne (symbol_ref "optimize_size")
2672                         (const_int 0))
2673                       (const_string "V4SF")
2674                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2675                         (const_int 0))
2676                       (const_string "V2DF")
2677                    ]
2678                    (const_string "DF"))
2679                /* For architectures resolving dependencies on register
2680                   parts we may avoid extra work to zero out upper part
2681                   of register.  */
2682                (eq_attr "alternative" "7")
2683                  (if_then_else
2684                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2685                        (const_int 0))
2686                    (const_string "V1DF")
2687                    (const_string "DF"))
2688               ]
2689               (const_string "DF")))])
2690
2691 (define_split
2692   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2693         (match_operand:DF 1 "general_operand" ""))]
2694   "reload_completed
2695    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2696    && ! (ANY_FP_REG_P (operands[0]) || 
2697          (GET_CODE (operands[0]) == SUBREG
2698           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2699    && ! (ANY_FP_REG_P (operands[1]) || 
2700          (GET_CODE (operands[1]) == SUBREG
2701           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2702   [(const_int 0)]
2703   "ix86_split_long_move (operands); DONE;")
2704
2705 (define_insn "*swapdf"
2706   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2707         (match_operand:DF 1 "fp_register_operand" "+f"))
2708    (set (match_dup 1)
2709         (match_dup 0))]
2710   "reload_completed || TARGET_80387"
2711 {
2712   if (STACK_TOP_P (operands[0]))
2713     return "fxch\t%1";
2714   else
2715     return "fxch\t%0";
2716 }
2717   [(set_attr "type" "fxch")
2718    (set_attr "mode" "DF")])
2719
2720 (define_expand "movxf"
2721   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2722         (match_operand:XF 1 "general_operand" ""))]
2723   ""
2724   "ix86_expand_move (XFmode, operands); DONE;")
2725
2726 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2727 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2728 ;; Pushing using integer instructions is longer except for constants
2729 ;; and direct memory references.
2730 ;; (assuming that any given constant is pushed only once, but this ought to be
2731 ;;  handled elsewhere).
2732
2733 (define_insn "*pushxf_nointeger"
2734   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2735         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2736   "optimize_size"
2737 {
2738   /* This insn should be already split before reg-stack.  */
2739   abort ();
2740 }
2741   [(set_attr "type" "multi")
2742    (set_attr "mode" "XF,SI,SI")])
2743
2744 (define_insn "*pushxf_integer"
2745   [(set (match_operand:XF 0 "push_operand" "=<,<")
2746         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2747   "!optimize_size"
2748 {
2749   /* This insn should be already split before reg-stack.  */
2750   abort ();
2751 }
2752   [(set_attr "type" "multi")
2753    (set_attr "mode" "XF,SI")])
2754
2755 (define_split
2756   [(set (match_operand 0 "push_operand" "")
2757         (match_operand 1 "general_operand" ""))]
2758   "reload_completed
2759    && (GET_MODE (operands[0]) == XFmode
2760        || GET_MODE (operands[0]) == DFmode)
2761    && !ANY_FP_REG_P (operands[1])"
2762   [(const_int 0)]
2763   "ix86_split_long_move (operands); DONE;")
2764
2765 (define_split
2766   [(set (match_operand:XF 0 "push_operand" "")
2767         (match_operand:XF 1 "any_fp_register_operand" ""))]
2768   "!TARGET_64BIT"
2769   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2770    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2771   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772
2773 (define_split
2774   [(set (match_operand:XF 0 "push_operand" "")
2775         (match_operand:XF 1 "any_fp_register_operand" ""))]
2776   "TARGET_64BIT"
2777   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2778    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2779   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2780
2781 ;; Do not use integer registers when optimizing for size
2782 (define_insn "*movxf_nointeger"
2783   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2784         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2785   "optimize_size
2786    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2787    && (reload_in_progress || reload_completed
2788        || GET_CODE (operands[1]) != CONST_DOUBLE
2789        || memory_operand (operands[0], XFmode))" 
2790 {
2791   switch (which_alternative)
2792     {
2793     case 0:
2794       return output_387_reg_move (insn, operands);
2795
2796     case 1:
2797       /* There is no non-popping store to memory for XFmode.  So if
2798          we need one, follow the store with a load.  */
2799       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2800         return "fstp%z0\t%y0\;fld%z0\t%y0";
2801       else
2802         return "fstp%z0\t%y0";
2803
2804     case 2:
2805       return standard_80387_constant_opcode (operands[1]);
2806
2807     case 3: case 4:
2808       return "#";
2809     }
2810   abort();
2811 }
2812   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2813    (set_attr "mode" "XF,XF,XF,SI,SI")])
2814
2815 (define_insn "*movxf_integer"
2816   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2817         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2818   "!optimize_size
2819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2820    && (reload_in_progress || reload_completed
2821        || GET_CODE (operands[1]) != CONST_DOUBLE
2822        || memory_operand (operands[0], XFmode))" 
2823 {
2824   switch (which_alternative)
2825     {
2826     case 0:
2827       return output_387_reg_move (insn, operands);
2828
2829     case 1:
2830       /* There is no non-popping store to memory for XFmode.  So if
2831          we need one, follow the store with a load.  */
2832       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2833         return "fstp%z0\t%y0\;fld%z0\t%y0";
2834       else
2835         return "fstp%z0\t%y0";
2836
2837     case 2:
2838       return standard_80387_constant_opcode (operands[1]);
2839
2840     case 3: case 4:
2841       return "#";
2842     }
2843   abort();
2844 }
2845   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2846    (set_attr "mode" "XF,XF,XF,SI,SI")])
2847
2848 (define_split
2849   [(set (match_operand 0 "nonimmediate_operand" "")
2850         (match_operand 1 "general_operand" ""))]
2851   "reload_completed
2852    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2853    && GET_MODE (operands[0]) == XFmode
2854    && ! (ANY_FP_REG_P (operands[0]) || 
2855          (GET_CODE (operands[0]) == SUBREG
2856           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2857    && ! (ANY_FP_REG_P (operands[1]) || 
2858          (GET_CODE (operands[1]) == SUBREG
2859           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2860   [(const_int 0)]
2861   "ix86_split_long_move (operands); DONE;")
2862
2863 (define_split
2864   [(set (match_operand 0 "register_operand" "")
2865         (match_operand 1 "memory_operand" ""))]
2866   "reload_completed
2867    && GET_CODE (operands[1]) == MEM
2868    && (GET_MODE (operands[0]) == XFmode
2869        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2870    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2871    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2872   [(set (match_dup 0) (match_dup 1))]
2873 {
2874   rtx c = get_pool_constant (XEXP (operands[1], 0));
2875   rtx r = operands[0];
2876
2877   if (GET_CODE (r) == SUBREG)
2878     r = SUBREG_REG (r);
2879
2880   if (SSE_REG_P (r))
2881     {
2882       if (!standard_sse_constant_p (c))
2883         FAIL;
2884     }
2885   else if (FP_REG_P (r))
2886     {
2887       if (!standard_80387_constant_p (c))
2888         FAIL;
2889     }
2890   else if (MMX_REG_P (r))
2891     FAIL;
2892
2893   operands[1] = c;
2894 })
2895
2896 (define_insn "swapxf"
2897   [(set (match_operand:XF 0 "register_operand" "+f")
2898         (match_operand:XF 1 "register_operand" "+f"))
2899    (set (match_dup 1)
2900         (match_dup 0))]
2901   "TARGET_80387"
2902 {
2903   if (STACK_TOP_P (operands[0]))
2904     return "fxch\t%1";
2905   else
2906     return "fxch\t%0";
2907 }
2908   [(set_attr "type" "fxch")
2909    (set_attr "mode" "XF")])
2910 \f
2911 ;; Zero extension instructions
2912
2913 (define_expand "zero_extendhisi2"
2914   [(set (match_operand:SI 0 "register_operand" "")
2915      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2916   ""
2917 {
2918   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2919     {
2920       operands[1] = force_reg (HImode, operands[1]);
2921       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2922       DONE;
2923     }
2924 })
2925
2926 (define_insn "zero_extendhisi2_and"
2927   [(set (match_operand:SI 0 "register_operand" "=r")
2928      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2929    (clobber (reg:CC FLAGS_REG))]
2930   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2931   "#"
2932   [(set_attr "type" "alu1")
2933    (set_attr "mode" "SI")])
2934
2935 (define_split
2936   [(set (match_operand:SI 0 "register_operand" "")
2937         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2938    (clobber (reg:CC FLAGS_REG))]
2939   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2940   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2941               (clobber (reg:CC FLAGS_REG))])]
2942   "")
2943
2944 (define_insn "*zero_extendhisi2_movzwl"
2945   [(set (match_operand:SI 0 "register_operand" "=r")
2946      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2947   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2948   "movz{wl|x}\t{%1, %0|%0, %1}"
2949   [(set_attr "type" "imovx")
2950    (set_attr "mode" "SI")])
2951
2952 (define_expand "zero_extendqihi2"
2953   [(parallel
2954     [(set (match_operand:HI 0 "register_operand" "")
2955        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2956      (clobber (reg:CC FLAGS_REG))])]
2957   ""
2958   "")
2959
2960 (define_insn "*zero_extendqihi2_and"
2961   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2962      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2963    (clobber (reg:CC FLAGS_REG))]
2964   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2965   "#"
2966   [(set_attr "type" "alu1")
2967    (set_attr "mode" "HI")])
2968
2969 (define_insn "*zero_extendqihi2_movzbw_and"
2970   [(set (match_operand:HI 0 "register_operand" "=r,r")
2971      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2972    (clobber (reg:CC FLAGS_REG))]
2973   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2974   "#"
2975   [(set_attr "type" "imovx,alu1")
2976    (set_attr "mode" "HI")])
2977
2978 (define_insn "*zero_extendqihi2_movzbw"
2979   [(set (match_operand:HI 0 "register_operand" "=r")
2980      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2981   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2982   "movz{bw|x}\t{%1, %0|%0, %1}"
2983   [(set_attr "type" "imovx")
2984    (set_attr "mode" "HI")])
2985
2986 ;; For the movzbw case strip only the clobber
2987 (define_split
2988   [(set (match_operand:HI 0 "register_operand" "")
2989         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2990    (clobber (reg:CC FLAGS_REG))]
2991   "reload_completed 
2992    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2993    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2994   [(set (match_operand:HI 0 "register_operand" "")
2995         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2996
2997 ;; When source and destination does not overlap, clear destination
2998 ;; first and then do the movb
2999 (define_split
3000   [(set (match_operand:HI 0 "register_operand" "")
3001         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3002    (clobber (reg:CC FLAGS_REG))]
3003   "reload_completed
3004    && ANY_QI_REG_P (operands[0])
3005    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3006    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3007   [(set (match_dup 0) (const_int 0))
3008    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3009   "operands[2] = gen_lowpart (QImode, operands[0]);")
3010
3011 ;; Rest is handled by single and.
3012 (define_split
3013   [(set (match_operand:HI 0 "register_operand" "")
3014         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3015    (clobber (reg:CC FLAGS_REG))]
3016   "reload_completed
3017    && true_regnum (operands[0]) == true_regnum (operands[1])"
3018   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3019               (clobber (reg:CC FLAGS_REG))])]
3020   "")
3021
3022 (define_expand "zero_extendqisi2"
3023   [(parallel
3024     [(set (match_operand:SI 0 "register_operand" "")
3025        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3026      (clobber (reg:CC FLAGS_REG))])]
3027   ""
3028   "")
3029
3030 (define_insn "*zero_extendqisi2_and"
3031   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3032      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3033    (clobber (reg:CC FLAGS_REG))]
3034   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3035   "#"
3036   [(set_attr "type" "alu1")
3037    (set_attr "mode" "SI")])
3038
3039 (define_insn "*zero_extendqisi2_movzbw_and"
3040   [(set (match_operand:SI 0 "register_operand" "=r,r")
3041      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3042    (clobber (reg:CC FLAGS_REG))]
3043   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3044   "#"
3045   [(set_attr "type" "imovx,alu1")
3046    (set_attr "mode" "SI")])
3047
3048 (define_insn "*zero_extendqisi2_movzbw"
3049   [(set (match_operand:SI 0 "register_operand" "=r")
3050      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3051   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3052   "movz{bl|x}\t{%1, %0|%0, %1}"
3053   [(set_attr "type" "imovx")
3054    (set_attr "mode" "SI")])
3055
3056 ;; For the movzbl case strip only the clobber
3057 (define_split
3058   [(set (match_operand:SI 0 "register_operand" "")
3059         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3060    (clobber (reg:CC FLAGS_REG))]
3061   "reload_completed 
3062    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3063    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3064   [(set (match_dup 0)
3065         (zero_extend:SI (match_dup 1)))])
3066
3067 ;; When source and destination does not overlap, clear destination
3068 ;; first and then do the movb
3069 (define_split
3070   [(set (match_operand:SI 0 "register_operand" "")
3071         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "reload_completed
3074    && ANY_QI_REG_P (operands[0])
3075    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3076    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3077    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3078   [(set (match_dup 0) (const_int 0))
3079    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3080   "operands[2] = gen_lowpart (QImode, operands[0]);")
3081
3082 ;; Rest is handled by single and.
3083 (define_split
3084   [(set (match_operand:SI 0 "register_operand" "")
3085         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3086    (clobber (reg:CC FLAGS_REG))]
3087   "reload_completed
3088    && true_regnum (operands[0]) == true_regnum (operands[1])"
3089   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3090               (clobber (reg:CC FLAGS_REG))])]
3091   "")
3092
3093 ;; %%% Kill me once multi-word ops are sane.
3094 (define_expand "zero_extendsidi2"
3095   [(set (match_operand:DI 0 "register_operand" "=r")
3096      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3097   ""
3098   "if (!TARGET_64BIT)
3099      {
3100        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3101        DONE;
3102      }
3103   ")
3104
3105 (define_insn "zero_extendsidi2_32"
3106   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3107         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3108    (clobber (reg:CC FLAGS_REG))]
3109   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3110   "@
3111    #
3112    #
3113    #
3114    movd\t{%1, %0|%0, %1}
3115    movd\t{%1, %0|%0, %1}"
3116   [(set_attr "mode" "SI,SI,SI,DI,TI")
3117    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3118
3119 (define_insn "*zero_extendsidi2_32_1"
3120   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3121         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3122    (clobber (reg:CC FLAGS_REG))]
3123   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3124   "@
3125    #
3126    #
3127    #
3128    movd\t{%1, %0|%0, %1}
3129    movd\t{%1, %0|%0, %1}"
3130   [(set_attr "mode" "SI,SI,SI,DI,TI")
3131    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3132
3133 (define_insn "zero_extendsidi2_rex64"
3134   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3135      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3136   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3137   "@
3138    mov\t{%k1, %k0|%k0, %k1}
3139    #
3140    movd\t{%1, %0|%0, %1}
3141    movd\t{%1, %0|%0, %1}"
3142   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3143    (set_attr "mode" "SI,DI,DI,TI")])
3144
3145 (define_insn "*zero_extendsidi2_rex64_1"
3146   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3147      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3148   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3149   "@
3150    mov\t{%k1, %k0|%k0, %k1}
3151    #
3152    movd\t{%1, %0|%0, %1}
3153    movd\t{%1, %0|%0, %1}"
3154   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3155    (set_attr "mode" "SI,DI,SI,SI")])
3156
3157 (define_split
3158   [(set (match_operand:DI 0 "memory_operand" "")
3159      (zero_extend:DI (match_dup 0)))]
3160   "TARGET_64BIT"
3161   [(set (match_dup 4) (const_int 0))]
3162   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3163
3164 (define_split 
3165   [(set (match_operand:DI 0 "register_operand" "")
3166         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3167    (clobber (reg:CC FLAGS_REG))]
3168   "!TARGET_64BIT && reload_completed
3169    && true_regnum (operands[0]) == true_regnum (operands[1])"
3170   [(set (match_dup 4) (const_int 0))]
3171   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3172
3173 (define_split 
3174   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3175         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3176    (clobber (reg:CC FLAGS_REG))]
3177   "!TARGET_64BIT && reload_completed
3178    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3179   [(set (match_dup 3) (match_dup 1))
3180    (set (match_dup 4) (const_int 0))]
3181   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3182
3183 (define_insn "zero_extendhidi2"
3184   [(set (match_operand:DI 0 "register_operand" "=r,r")
3185      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3186   "TARGET_64BIT"
3187   "@
3188    movz{wl|x}\t{%1, %k0|%k0, %1}
3189    movz{wq|x}\t{%1, %0|%0, %1}"
3190   [(set_attr "type" "imovx")
3191    (set_attr "mode" "SI,DI")])
3192
3193 (define_insn "zero_extendqidi2"
3194   [(set (match_operand:DI 0 "register_operand" "=r,r")
3195      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3196   "TARGET_64BIT"
3197   "@
3198    movz{bl|x}\t{%1, %k0|%k0, %1}
3199    movz{bq|x}\t{%1, %0|%0, %1}"
3200   [(set_attr "type" "imovx")
3201    (set_attr "mode" "SI,DI")])
3202 \f
3203 ;; Sign extension instructions
3204
3205 (define_expand "extendsidi2"
3206   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3207                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3208               (clobber (reg:CC FLAGS_REG))
3209               (clobber (match_scratch:SI 2 ""))])]
3210   ""
3211 {
3212   if (TARGET_64BIT)
3213     {
3214       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3215       DONE;
3216     }
3217 })
3218
3219 (define_insn "*extendsidi2_1"
3220   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3221         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3222    (clobber (reg:CC FLAGS_REG))
3223    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3224   "!TARGET_64BIT"
3225   "#")
3226
3227 (define_insn "extendsidi2_rex64"
3228   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3229         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3230   "TARGET_64BIT"
3231   "@
3232    {cltq|cdqe}
3233    movs{lq|x}\t{%1,%0|%0, %1}"
3234   [(set_attr "type" "imovx")
3235    (set_attr "mode" "DI")
3236    (set_attr "prefix_0f" "0")
3237    (set_attr "modrm" "0,1")])
3238
3239 (define_insn "extendhidi2"
3240   [(set (match_operand:DI 0 "register_operand" "=r")
3241         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3242   "TARGET_64BIT"
3243   "movs{wq|x}\t{%1,%0|%0, %1}"
3244   [(set_attr "type" "imovx")
3245    (set_attr "mode" "DI")])
3246
3247 (define_insn "extendqidi2"
3248   [(set (match_operand:DI 0 "register_operand" "=r")
3249         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3250   "TARGET_64BIT"
3251   "movs{bq|x}\t{%1,%0|%0, %1}"
3252    [(set_attr "type" "imovx")
3253     (set_attr "mode" "DI")])
3254
3255 ;; Extend to memory case when source register does die.
3256 (define_split 
3257   [(set (match_operand:DI 0 "memory_operand" "")
3258         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3259    (clobber (reg:CC FLAGS_REG))
3260    (clobber (match_operand:SI 2 "register_operand" ""))]
3261   "(reload_completed
3262     && dead_or_set_p (insn, operands[1])
3263     && !reg_mentioned_p (operands[1], operands[0]))"
3264   [(set (match_dup 3) (match_dup 1))
3265    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3266               (clobber (reg:CC FLAGS_REG))])
3267    (set (match_dup 4) (match_dup 1))]
3268   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3269
3270 ;; Extend to memory case when source register does not die.
3271 (define_split 
3272   [(set (match_operand:DI 0 "memory_operand" "")
3273         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3274    (clobber (reg:CC FLAGS_REG))
3275    (clobber (match_operand:SI 2 "register_operand" ""))]
3276   "reload_completed"
3277   [(const_int 0)]
3278 {
3279   split_di (&operands[0], 1, &operands[3], &operands[4]);
3280
3281   emit_move_insn (operands[3], operands[1]);
3282
3283   /* Generate a cltd if possible and doing so it profitable.  */
3284   if (true_regnum (operands[1]) == 0
3285       && true_regnum (operands[2]) == 1
3286       && (optimize_size || TARGET_USE_CLTD))
3287     {
3288       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3289     }
3290   else
3291     {
3292       emit_move_insn (operands[2], operands[1]);
3293       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3294     }
3295   emit_move_insn (operands[4], operands[2]);
3296   DONE;
3297 })
3298
3299 ;; Extend to register case.  Optimize case where source and destination
3300 ;; registers match and cases where we can use cltd.
3301 (define_split 
3302   [(set (match_operand:DI 0 "register_operand" "")
3303         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3304    (clobber (reg:CC FLAGS_REG))
3305    (clobber (match_scratch:SI 2 ""))]
3306   "reload_completed"
3307   [(const_int 0)]
3308 {
3309   split_di (&operands[0], 1, &operands[3], &operands[4]);
3310
3311   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3312     emit_move_insn (operands[3], operands[1]);
3313
3314   /* Generate a cltd if possible and doing so it profitable.  */
3315   if (true_regnum (operands[3]) == 0
3316       && (optimize_size || TARGET_USE_CLTD))
3317     {
3318       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3319       DONE;
3320     }
3321
3322   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3323     emit_move_insn (operands[4], operands[1]);
3324
3325   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3326   DONE;
3327 })
3328
3329 (define_insn "extendhisi2"
3330   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3331         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3332   ""
3333 {
3334   switch (get_attr_prefix_0f (insn))
3335     {
3336     case 0:
3337       return "{cwtl|cwde}";
3338     default:
3339       return "movs{wl|x}\t{%1,%0|%0, %1}";
3340     }
3341 }
3342   [(set_attr "type" "imovx")
3343    (set_attr "mode" "SI")
3344    (set (attr "prefix_0f")
3345      ;; movsx is short decodable while cwtl is vector decoded.
3346      (if_then_else (and (eq_attr "cpu" "!k6")
3347                         (eq_attr "alternative" "0"))
3348         (const_string "0")
3349         (const_string "1")))
3350    (set (attr "modrm")
3351      (if_then_else (eq_attr "prefix_0f" "0")
3352         (const_string "0")
3353         (const_string "1")))])
3354
3355 (define_insn "*extendhisi2_zext"
3356   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3357         (zero_extend:DI
3358           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3359   "TARGET_64BIT"
3360 {
3361   switch (get_attr_prefix_0f (insn))
3362     {
3363     case 0:
3364       return "{cwtl|cwde}";
3365     default:
3366       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3367     }
3368 }
3369   [(set_attr "type" "imovx")
3370    (set_attr "mode" "SI")
3371    (set (attr "prefix_0f")
3372      ;; movsx is short decodable while cwtl is vector decoded.
3373      (if_then_else (and (eq_attr "cpu" "!k6")
3374                         (eq_attr "alternative" "0"))
3375         (const_string "0")
3376         (const_string "1")))
3377    (set (attr "modrm")
3378      (if_then_else (eq_attr "prefix_0f" "0")
3379         (const_string "0")
3380         (const_string "1")))])
3381
3382 (define_insn "extendqihi2"
3383   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3384         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3385   ""
3386 {
3387   switch (get_attr_prefix_0f (insn))
3388     {
3389     case 0:
3390       return "{cbtw|cbw}";
3391     default:
3392       return "movs{bw|x}\t{%1,%0|%0, %1}";
3393     }
3394 }
3395   [(set_attr "type" "imovx")
3396    (set_attr "mode" "HI")
3397    (set (attr "prefix_0f")
3398      ;; movsx is short decodable while cwtl is vector decoded.
3399      (if_then_else (and (eq_attr "cpu" "!k6")
3400                         (eq_attr "alternative" "0"))
3401         (const_string "0")
3402         (const_string "1")))
3403    (set (attr "modrm")
3404      (if_then_else (eq_attr "prefix_0f" "0")
3405         (const_string "0")
3406         (const_string "1")))])
3407
3408 (define_insn "extendqisi2"
3409   [(set (match_operand:SI 0 "register_operand" "=r")
3410         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3411   ""
3412   "movs{bl|x}\t{%1,%0|%0, %1}"
3413    [(set_attr "type" "imovx")
3414     (set_attr "mode" "SI")])
3415
3416 (define_insn "*extendqisi2_zext"
3417   [(set (match_operand:DI 0 "register_operand" "=r")
3418         (zero_extend:DI
3419           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3420   "TARGET_64BIT"
3421   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3422    [(set_attr "type" "imovx")
3423     (set_attr "mode" "SI")])
3424 \f
3425 ;; Conversions between float and double.
3426
3427 ;; These are all no-ops in the model used for the 80387.  So just
3428 ;; emit moves.
3429
3430 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3431 (define_insn "*dummy_extendsfdf2"
3432   [(set (match_operand:DF 0 "push_operand" "=<")
3433         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3434   "0"
3435   "#")
3436
3437 (define_split
3438   [(set (match_operand:DF 0 "push_operand" "")
3439         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3440   "!TARGET_64BIT"
3441   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3442    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3443
3444 (define_split
3445   [(set (match_operand:DF 0 "push_operand" "")
3446         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3447   "TARGET_64BIT"
3448   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3449    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3450
3451 (define_insn "*dummy_extendsfxf2"
3452   [(set (match_operand:XF 0 "push_operand" "=<")
3453         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3454   "0"
3455   "#")
3456
3457 (define_split
3458   [(set (match_operand:XF 0 "push_operand" "")
3459         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3460   ""
3461   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3462    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3463   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3464
3465 (define_split
3466   [(set (match_operand:XF 0 "push_operand" "")
3467         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3468   "TARGET_64BIT"
3469   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3470    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3471   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3472
3473 (define_split
3474   [(set (match_operand:XF 0 "push_operand" "")
3475         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3476   ""
3477   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3478    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3479   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3480
3481 (define_split
3482   [(set (match_operand:XF 0 "push_operand" "")
3483         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3484   "TARGET_64BIT"
3485   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3486    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3487   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3488
3489 (define_expand "extendsfdf2"
3490   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3491         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3492   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3493 {
3494   /* ??? Needed for compress_float_constant since all fp constants
3495      are LEGITIMATE_CONSTANT_P.  */
3496   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3497     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3498   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3499     operands[1] = force_reg (SFmode, operands[1]);
3500 })
3501
3502 (define_insn "*extendsfdf2_mixed"
3503   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3504         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3505   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3506    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3507 {
3508   switch (which_alternative)
3509     {
3510     case 0:
3511       return output_387_reg_move (insn, operands);
3512
3513     case 1:
3514       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3515         return "fstp%z0\t%y0";
3516       else
3517         return "fst%z0\t%y0";
3518
3519     case 2:
3520       return "cvtss2sd\t{%1, %0|%0, %1}";
3521
3522     default:
3523       abort ();
3524     }
3525 }
3526   [(set_attr "type" "fmov,fmov,ssecvt")
3527    (set_attr "mode" "SF,XF,DF")])
3528
3529 (define_insn "*extendsfdf2_sse"
3530   [(set (match_operand:DF 0 "register_operand" "=Y")
3531         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3532   "TARGET_SSE2 && TARGET_SSE_MATH
3533    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3534   "cvtss2sd\t{%1, %0|%0, %1}"
3535   [(set_attr "type" "ssecvt")
3536    (set_attr "mode" "DF")])
3537
3538 (define_insn "*extendsfdf2_i387"
3539   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3540         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3541   "TARGET_80387
3542    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3543 {
3544   switch (which_alternative)
3545     {
3546     case 0:
3547       return output_387_reg_move (insn, operands);
3548
3549     case 1:
3550       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3551         return "fstp%z0\t%y0";
3552       else
3553         return "fst%z0\t%y0";
3554
3555     default:
3556       abort ();
3557     }
3558 }
3559   [(set_attr "type" "fmov")
3560    (set_attr "mode" "SF,XF")])
3561
3562 (define_expand "extendsfxf2"
3563   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3564         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3565   "TARGET_80387"
3566 {
3567   /* ??? Needed for compress_float_constant since all fp constants
3568      are LEGITIMATE_CONSTANT_P.  */
3569   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3570     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3571   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3572     operands[1] = force_reg (SFmode, operands[1]);
3573 })
3574
3575 (define_insn "*extendsfxf2_i387"
3576   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3577         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3578   "TARGET_80387
3579    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3580 {
3581   switch (which_alternative)
3582     {
3583     case 0:
3584       return output_387_reg_move (insn, operands);
3585
3586     case 1:
3587       /* There is no non-popping store to memory for XFmode.  So if
3588          we need one, follow the store with a load.  */
3589       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3590         return "fstp%z0\t%y0";
3591       else
3592         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3593
3594     default:
3595       abort ();
3596     }
3597 }
3598   [(set_attr "type" "fmov")
3599    (set_attr "mode" "SF,XF")])
3600
3601 (define_expand "extenddfxf2"
3602   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3603         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3604   "TARGET_80387"
3605 {
3606   /* ??? Needed for compress_float_constant since all fp constants
3607      are LEGITIMATE_CONSTANT_P.  */
3608   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3609     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3610   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3611     operands[1] = force_reg (DFmode, operands[1]);
3612 })
3613
3614 (define_insn "*extenddfxf2_i387"
3615   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3616         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3617   "TARGET_80387
3618    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3619 {
3620   switch (which_alternative)
3621     {
3622     case 0:
3623       return output_387_reg_move (insn, operands);
3624
3625     case 1:
3626       /* There is no non-popping store to memory for XFmode.  So if
3627          we need one, follow the store with a load.  */
3628       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3629         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3630       else
3631         return "fstp%z0\t%y0";
3632
3633     default:
3634       abort ();
3635     }
3636 }
3637   [(set_attr "type" "fmov")
3638    (set_attr "mode" "DF,XF")])
3639
3640 ;; %%% This seems bad bad news.
3641 ;; This cannot output into an f-reg because there is no way to be sure
3642 ;; of truncating in that case.  Otherwise this is just like a simple move
3643 ;; insn.  So we pretend we can output to a reg in order to get better
3644 ;; register preferencing, but we really use a stack slot.
3645
3646 ;; Conversion from DFmode to SFmode.
3647
3648 (define_expand "truncdfsf2"
3649   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3650         (float_truncate:SF
3651           (match_operand:DF 1 "nonimmediate_operand" "")))]
3652   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3653 {
3654   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3655     operands[1] = force_reg (DFmode, operands[1]);
3656
3657   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3658     ;
3659   else if (flag_unsafe_math_optimizations)
3660     ;
3661   else
3662     {
3663       rtx temp = assign_386_stack_local (SFmode, 0);
3664       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3665       DONE;
3666     }
3667 })
3668
3669 (define_expand "truncdfsf2_with_temp"
3670   [(parallel [(set (match_operand:SF 0 "" "")
3671                    (float_truncate:SF (match_operand:DF 1 "" "")))
3672               (clobber (match_operand:SF 2 "" ""))])]
3673   "")
3674
3675 (define_insn "*truncdfsf_fast_mixed"
3676   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3677         (float_truncate:SF
3678           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3679   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3680 {
3681   switch (which_alternative)
3682     {
3683     case 0:
3684       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685         return "fstp%z0\t%y0";
3686       else
3687         return "fst%z0\t%y0";
3688     case 1:
3689       return output_387_reg_move (insn, operands);
3690     case 2:
3691       return "cvtsd2ss\t{%1, %0|%0, %1}";
3692     default:
3693       abort ();
3694     }
3695 }
3696   [(set_attr "type" "fmov,fmov,ssecvt")
3697    (set_attr "mode" "SF")])
3698
3699 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3700 ;; because nothing we do here is unsafe.
3701 (define_insn "*truncdfsf_fast_sse"
3702   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3703         (float_truncate:SF
3704           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3705   "TARGET_SSE2 && TARGET_SSE_MATH"
3706   "cvtsd2ss\t{%1, %0|%0, %1}"
3707   [(set_attr "type" "ssecvt")
3708    (set_attr "mode" "SF")])
3709
3710 (define_insn "*truncdfsf_fast_i387"
3711   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3712         (float_truncate:SF
3713           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3714   "TARGET_80387 && flag_unsafe_math_optimizations"
3715   "* return output_387_reg_move (insn, operands);"
3716   [(set_attr "type" "fmov")
3717    (set_attr "mode" "SF")])
3718
3719 (define_insn "*truncdfsf_mixed"
3720   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3721         (float_truncate:SF
3722           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3723    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3724   "TARGET_MIX_SSE_I387"
3725 {
3726   switch (which_alternative)
3727     {
3728     case 0:
3729       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3730         return "fstp%z0\t%y0";
3731       else
3732         return "fst%z0\t%y0";
3733     case 1:
3734       return "#";
3735     case 2:
3736       return "cvtsd2ss\t{%1, %0|%0, %1}";
3737     default:
3738       abort ();
3739     }
3740 }
3741   [(set_attr "type" "fmov,multi,ssecvt")
3742    (set_attr "mode" "SF")])
3743
3744 (define_insn "*truncdfsf_i387"
3745   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3746         (float_truncate:SF
3747           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3748    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3749   "TARGET_80387"
3750 {
3751   switch (which_alternative)
3752     {
3753     case 0:
3754       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3755         return "fstp%z0\t%y0";
3756       else
3757         return "fst%z0\t%y0";
3758     case 1:
3759       return "#";
3760     default:
3761       abort ();
3762     }
3763 }
3764   [(set_attr "type" "fmov,multi")
3765    (set_attr "mode" "SF")])
3766
3767 (define_split
3768   [(set (match_operand:SF 0 "register_operand" "")
3769         (float_truncate:SF
3770          (match_operand:DF 1 "fp_register_operand" "")))
3771    (clobber (match_operand 2 "" ""))]
3772   "reload_completed"
3773   [(set (match_dup 2) (match_dup 1))
3774    (set (match_dup 0) (match_dup 2))]
3775 {
3776   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3777 })
3778
3779 ;; Conversion from XFmode to SFmode.
3780
3781 (define_expand "truncxfsf2"
3782   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3783                    (float_truncate:SF
3784                     (match_operand:XF 1 "register_operand" "")))
3785               (clobber (match_dup 2))])]
3786   "TARGET_80387"
3787 {
3788   if (flag_unsafe_math_optimizations)
3789     {
3790       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3791       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3792       if (reg != operands[0])
3793         emit_move_insn (operands[0], reg);
3794       DONE;
3795     }
3796   else
3797     operands[2] = assign_386_stack_local (SFmode, 0);
3798 })
3799
3800 (define_insn "*truncxfsf2_mixed"
3801   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3802         (float_truncate:SF
3803          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3804    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3805   "TARGET_MIX_SSE_I387"
3806 {
3807   switch (which_alternative)
3808     {
3809     case 0:
3810       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811         return "fstp%z0\t%y0";
3812       else
3813         return "fst%z0\t%y0";
3814     default:
3815       abort();
3816     }
3817 }
3818   [(set_attr "type" "fmov,multi,multi,multi")
3819    (set_attr "mode" "SF")])
3820
3821 (define_insn "truncxfsf2_i387_noop"
3822   [(set (match_operand:SF 0 "register_operand" "=f")
3823         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3824   "TARGET_80387 && flag_unsafe_math_optimizations"
3825 {
3826   return output_387_reg_move (insn, operands);
3827 }
3828   [(set_attr "type" "fmov")
3829    (set_attr "mode" "SF")])
3830
3831 (define_insn "*truncxfsf2_i387"
3832   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3833         (float_truncate:SF
3834          (match_operand:XF 1 "register_operand" "f,f,f")))
3835    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3836   "TARGET_80387"
3837 {
3838   switch (which_alternative)
3839     {
3840     case 0:
3841       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3842         return "fstp%z0\t%y0";
3843       else
3844         return "fst%z0\t%y0";
3845     default:
3846       abort ();
3847     }
3848 }
3849   [(set_attr "type" "fmov,multi,multi")
3850    (set_attr "mode" "SF")])
3851
3852 (define_insn "*truncxfsf2_i387_1"
3853   [(set (match_operand:SF 0 "memory_operand" "=m")
3854         (float_truncate:SF
3855          (match_operand:XF 1 "register_operand" "f")))]
3856   "TARGET_80387"
3857 {
3858   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3859     return "fstp%z0\t%y0";
3860   else
3861     return "fst%z0\t%y0";
3862 }
3863   [(set_attr "type" "fmov")
3864    (set_attr "mode" "SF")])
3865
3866 (define_split
3867   [(set (match_operand:SF 0 "register_operand" "")
3868         (float_truncate:SF
3869          (match_operand:XF 1 "register_operand" "")))
3870    (clobber (match_operand:SF 2 "memory_operand" ""))]
3871   "TARGET_80387 && reload_completed"
3872   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3873    (set (match_dup 0) (match_dup 2))]
3874   "")
3875
3876 (define_split
3877   [(set (match_operand:SF 0 "memory_operand" "")
3878         (float_truncate:SF
3879          (match_operand:XF 1 "register_operand" "")))
3880    (clobber (match_operand:SF 2 "memory_operand" ""))]
3881   "TARGET_80387"
3882   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3883   "")
3884
3885 ;; Conversion from XFmode to DFmode.
3886
3887 (define_expand "truncxfdf2"
3888   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3889                    (float_truncate:DF
3890                     (match_operand:XF 1 "register_operand" "")))
3891               (clobber (match_dup 2))])]
3892   "TARGET_80387"
3893 {
3894   if (flag_unsafe_math_optimizations)
3895     {
3896       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3897       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3898       if (reg != operands[0])
3899         emit_move_insn (operands[0], reg);
3900       DONE;
3901     }
3902   else
3903     operands[2] = assign_386_stack_local (DFmode, 0);
3904 })
3905
3906 (define_insn "*truncxfdf2_mixed"
3907   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3908         (float_truncate:DF
3909          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3910    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3911   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3912 {
3913   switch (which_alternative)
3914     {
3915     case 0:
3916       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3917         return "fstp%z0\t%y0";
3918       else
3919         return "fst%z0\t%y0";
3920     default:
3921       abort();
3922     }
3923   abort ();
3924 }
3925   [(set_attr "type" "fmov,multi,multi,multi")
3926    (set_attr "mode" "DF")])
3927
3928 (define_insn "truncxfdf2_i387_noop"
3929   [(set (match_operand:DF 0 "register_operand" "=f")
3930         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3931   "TARGET_80387 && flag_unsafe_math_optimizations"
3932 {
3933   return output_387_reg_move (insn, operands);
3934 }
3935   [(set_attr "type" "fmov")
3936    (set_attr "mode" "DF")])
3937
3938 (define_insn "*truncxfdf2_i387"
3939   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3940         (float_truncate:DF
3941          (match_operand:XF 1 "register_operand" "f,f,f")))
3942    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3943   "TARGET_80387"
3944 {
3945   switch (which_alternative)
3946     {
3947     case 0:
3948       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3949         return "fstp%z0\t%y0";
3950       else
3951         return "fst%z0\t%y0";
3952     default:
3953       abort ();
3954     }
3955 }
3956   [(set_attr "type" "fmov,multi,multi")
3957    (set_attr "mode" "DF")])
3958
3959 (define_insn "*truncxfdf2_i387_1"
3960   [(set (match_operand:DF 0 "memory_operand" "=m")
3961         (float_truncate:DF
3962           (match_operand:XF 1 "register_operand" "f")))]
3963   "TARGET_80387"
3964 {
3965   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3966     return "fstp%z0\t%y0";
3967   else
3968     return "fst%z0\t%y0";
3969 }
3970   [(set_attr "type" "fmov")
3971    (set_attr "mode" "DF")])
3972
3973 (define_split
3974   [(set (match_operand:DF 0 "register_operand" "")
3975         (float_truncate:DF
3976          (match_operand:XF 1 "register_operand" "")))
3977    (clobber (match_operand:DF 2 "memory_operand" ""))]
3978   "TARGET_80387 && reload_completed"
3979   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3980    (set (match_dup 0) (match_dup 2))]
3981   "")
3982
3983 (define_split
3984   [(set (match_operand:DF 0 "memory_operand" "")
3985         (float_truncate:DF
3986          (match_operand:XF 1 "register_operand" "")))
3987    (clobber (match_operand:DF 2 "memory_operand" ""))]
3988   "TARGET_80387"
3989   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3990   "")
3991 \f
3992 ;; %%% Break up all these bad boys.
3993
3994 ;; Signed conversion to DImode.
3995
3996 (define_expand "fix_truncxfdi2"
3997   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3998                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3999               (clobber (reg:CC FLAGS_REG))])]
4000   "TARGET_80387"
4001   "")
4002
4003 (define_expand "fix_truncdfdi2"
4004   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4005                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4006               (clobber (reg:CC FLAGS_REG))])]
4007   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4008 {
4009   if (TARGET_64BIT && TARGET_SSE2)
4010    {
4011      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4012      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4013      if (out != operands[0])
4014         emit_move_insn (operands[0], out);
4015      DONE;
4016    }
4017 })
4018
4019 (define_expand "fix_truncsfdi2"
4020   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4021                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4022               (clobber (reg:CC FLAGS_REG))])] 
4023   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4024 {
4025   if (TARGET_64BIT && TARGET_SSE)
4026    {
4027      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4028      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4029      if (out != operands[0])
4030         emit_move_insn (operands[0], out);
4031      DONE;
4032    }
4033 })
4034
4035 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4036 ;; of the machinery.
4037 (define_insn_and_split "*fix_truncdi_i387"
4038   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4039         (fix:DI (match_operand 1 "register_operand" "f,f")))
4040    (clobber (reg:CC FLAGS_REG))]
4041   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4042    && !reload_completed && !reload_in_progress
4043    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4044   "#"
4045   "&& 1"
4046   [(const_int 0)]
4047 {
4048   ix86_optimize_mode_switching = 1;
4049   operands[2] = assign_386_stack_local (HImode, 1);
4050   operands[3] = assign_386_stack_local (HImode, 2);
4051   if (memory_operand (operands[0], VOIDmode))
4052     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4053                                        operands[2], operands[3]));
4054   else
4055     {
4056       operands[4] = assign_386_stack_local (DImode, 0);
4057       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4058                                            operands[2], operands[3],
4059                                            operands[4]));
4060     }
4061   DONE;
4062 }
4063   [(set_attr "type" "fistp")
4064    (set_attr "i387_cw" "trunc")
4065    (set_attr "mode" "DI")])
4066
4067 (define_insn "fix_truncdi_nomemory"
4068   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4069         (fix:DI (match_operand 1 "register_operand" "f,f")))
4070    (use (match_operand:HI 2 "memory_operand" "m,m"))
4071    (use (match_operand:HI 3 "memory_operand" "m,m"))
4072    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4073    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4074   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4075    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4076   "#"
4077   [(set_attr "type" "fistp")
4078    (set_attr "i387_cw" "trunc")
4079    (set_attr "mode" "DI")])
4080
4081 (define_insn "fix_truncdi_memory"
4082   [(set (match_operand:DI 0 "memory_operand" "=m")
4083         (fix:DI (match_operand 1 "register_operand" "f")))
4084    (use (match_operand:HI 2 "memory_operand" "m"))
4085    (use (match_operand:HI 3 "memory_operand" "m"))
4086    (clobber (match_scratch:DF 4 "=&1f"))]
4087   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4088    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4089   "* return output_fix_trunc (insn, operands);"
4090   [(set_attr "type" "fistp")
4091    (set_attr "i387_cw" "trunc")
4092    (set_attr "mode" "DI")])
4093
4094 (define_split 
4095   [(set (match_operand:DI 0 "register_operand" "")
4096         (fix:DI (match_operand 1 "register_operand" "")))
4097    (use (match_operand:HI 2 "memory_operand" ""))
4098    (use (match_operand:HI 3 "memory_operand" ""))
4099    (clobber (match_operand:DI 4 "memory_operand" ""))
4100    (clobber (match_scratch 5 ""))]
4101   "reload_completed"
4102   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4103               (use (match_dup 2))
4104               (use (match_dup 3))
4105               (clobber (match_dup 5))])
4106    (set (match_dup 0) (match_dup 4))]
4107   "")
4108
4109 (define_split 
4110   [(set (match_operand:DI 0 "memory_operand" "")
4111         (fix:DI (match_operand 1 "register_operand" "")))
4112    (use (match_operand:HI 2 "memory_operand" ""))
4113    (use (match_operand:HI 3 "memory_operand" ""))
4114    (clobber (match_operand:DI 4 "memory_operand" ""))
4115    (clobber (match_scratch 5 ""))]
4116   "reload_completed"
4117   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4118               (use (match_dup 2))
4119               (use (match_dup 3))
4120               (clobber (match_dup 5))])]
4121   "")
4122
4123 ;; When SSE available, it is always faster to use it!
4124 (define_insn "fix_truncsfdi_sse"
4125   [(set (match_operand:DI 0 "register_operand" "=r,r")
4126         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4127   "TARGET_64BIT && TARGET_SSE"
4128   "cvttss2si{q}\t{%1, %0|%0, %1}"
4129   [(set_attr "type" "sseicvt")
4130    (set_attr "mode" "SF")
4131    (set_attr "athlon_decode" "double,vector")])
4132
4133 ;; Avoid vector decoded form of the instruction.
4134 (define_peephole2
4135   [(match_scratch:SF 2 "x")
4136    (set (match_operand:DI 0 "register_operand" "")
4137         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4138   "TARGET_K8 && !optimize_size"
4139   [(set (match_dup 2) (match_dup 1))
4140    (set (match_dup 0) (fix:DI (match_dup 2)))]
4141   "")
4142
4143 (define_insn "fix_truncdfdi_sse"
4144   [(set (match_operand:DI 0 "register_operand" "=r,r")
4145         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4146   "TARGET_64BIT && TARGET_SSE2"
4147   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4148   [(set_attr "type" "sseicvt,sseicvt")
4149    (set_attr "mode" "DF")
4150    (set_attr "athlon_decode" "double,vector")])
4151
4152 ;; Avoid vector decoded form of the instruction.
4153 (define_peephole2
4154   [(match_scratch:DF 2 "Y")
4155    (set (match_operand:DI 0 "register_operand" "")
4156         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4157   "TARGET_K8 && !optimize_size"
4158   [(set (match_dup 2) (match_dup 1))
4159    (set (match_dup 0) (fix:DI (match_dup 2)))]
4160   "")
4161
4162 ;; Signed conversion to SImode.
4163
4164 (define_expand "fix_truncxfsi2"
4165   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4166                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4167               (clobber (reg:CC FLAGS_REG))])]
4168   "TARGET_80387"
4169   "")
4170
4171 (define_expand "fix_truncdfsi2"
4172   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4173                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4174               (clobber (reg:CC FLAGS_REG))])]
4175   "TARGET_80387 || TARGET_SSE2"
4176 {
4177   if (TARGET_SSE2)
4178    {
4179      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4180      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4181      if (out != operands[0])
4182         emit_move_insn (operands[0], out);
4183      DONE;
4184    }
4185 })
4186
4187 (define_expand "fix_truncsfsi2"
4188   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4189                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4190               (clobber (reg:CC FLAGS_REG))])] 
4191   "TARGET_80387 || TARGET_SSE"
4192 {
4193   if (TARGET_SSE)
4194    {
4195      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4196      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4197      if (out != operands[0])
4198         emit_move_insn (operands[0], out);
4199      DONE;
4200    }
4201 })
4202
4203 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4204 ;; of the machinery.
4205 (define_insn_and_split "*fix_truncsi_i387"
4206   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4207         (fix:SI (match_operand 1 "register_operand" "f,f")))
4208    (clobber (reg:CC FLAGS_REG))]
4209   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4210    && !reload_completed && !reload_in_progress
4211    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4212   "#"
4213   "&& 1"
4214   [(const_int 0)]
4215 {
4216   ix86_optimize_mode_switching = 1;
4217   operands[2] = assign_386_stack_local (HImode, 1);
4218   operands[3] = assign_386_stack_local (HImode, 2);
4219   if (memory_operand (operands[0], VOIDmode))
4220     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4221                                        operands[2], operands[3]));
4222   else
4223     {
4224       operands[4] = assign_386_stack_local (SImode, 0);
4225       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4226                                            operands[2], operands[3],
4227                                            operands[4]));
4228     }
4229   DONE;
4230 }
4231   [(set_attr "type" "fistp")
4232    (set_attr "i387_cw" "trunc")
4233    (set_attr "mode" "SI")])
4234
4235 (define_insn "fix_truncsi_nomemory"
4236   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4237         (fix:SI (match_operand 1 "register_operand" "f,f")))
4238    (use (match_operand:HI 2 "memory_operand" "m,m"))
4239    (use (match_operand:HI 3 "memory_operand" "m,m"))
4240    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4241   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4242    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4243   "#"
4244   [(set_attr "type" "fistp")
4245    (set_attr "i387_cw" "trunc")
4246    (set_attr "mode" "SI")])
4247
4248 (define_insn "fix_truncsi_memory"
4249   [(set (match_operand:SI 0 "memory_operand" "=m")
4250         (fix:SI (match_operand 1 "register_operand" "f")))
4251    (use (match_operand:HI 2 "memory_operand" "m"))
4252    (use (match_operand:HI 3 "memory_operand" "m"))]
4253   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4254    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4255   "* return output_fix_trunc (insn, operands);"
4256   [(set_attr "type" "fistp")
4257    (set_attr "i387_cw" "trunc")
4258    (set_attr "mode" "SI")])
4259
4260 ;; When SSE available, it is always faster to use it!
4261 (define_insn "fix_truncsfsi_sse"
4262   [(set (match_operand:SI 0 "register_operand" "=r,r")
4263         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4264   "TARGET_SSE"
4265   "cvttss2si\t{%1, %0|%0, %1}"
4266   [(set_attr "type" "sseicvt")
4267    (set_attr "mode" "DF")
4268    (set_attr "athlon_decode" "double,vector")])
4269
4270 ;; Avoid vector decoded form of the instruction.
4271 (define_peephole2
4272   [(match_scratch:SF 2 "x")
4273    (set (match_operand:SI 0 "register_operand" "")
4274         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4275   "TARGET_K8 && !optimize_size"
4276   [(set (match_dup 2) (match_dup 1))
4277    (set (match_dup 0) (fix:SI (match_dup 2)))]
4278   "")
4279
4280 (define_insn "fix_truncdfsi_sse"
4281   [(set (match_operand:SI 0 "register_operand" "=r,r")
4282         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4283   "TARGET_SSE2"
4284   "cvttsd2si\t{%1, %0|%0, %1}"
4285   [(set_attr "type" "sseicvt")
4286    (set_attr "mode" "DF")
4287    (set_attr "athlon_decode" "double,vector")])
4288
4289 ;; Avoid vector decoded form of the instruction.
4290 (define_peephole2
4291   [(match_scratch:DF 2 "Y")
4292    (set (match_operand:SI 0 "register_operand" "")
4293         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4294   "TARGET_K8 && !optimize_size"
4295   [(set (match_dup 2) (match_dup 1))
4296    (set (match_dup 0) (fix:SI (match_dup 2)))]
4297   "")
4298
4299 (define_split 
4300   [(set (match_operand:SI 0 "register_operand" "")
4301         (fix:SI (match_operand 1 "register_operand" "")))
4302    (use (match_operand:HI 2 "memory_operand" ""))
4303    (use (match_operand:HI 3 "memory_operand" ""))
4304    (clobber (match_operand:SI 4 "memory_operand" ""))]
4305   "reload_completed"
4306   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4307               (use (match_dup 2))
4308               (use (match_dup 3))])
4309    (set (match_dup 0) (match_dup 4))]
4310   "")
4311
4312 (define_split 
4313   [(set (match_operand:SI 0 "memory_operand" "")
4314         (fix:SI (match_operand 1 "register_operand" "")))
4315    (use (match_operand:HI 2 "memory_operand" ""))
4316    (use (match_operand:HI 3 "memory_operand" ""))
4317    (clobber (match_operand:SI 4 "memory_operand" ""))]
4318   "reload_completed"
4319   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4320               (use (match_dup 2))
4321               (use (match_dup 3))])]
4322   "")
4323
4324 ;; Signed conversion to HImode.
4325
4326 (define_expand "fix_truncxfhi2"
4327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4329               (clobber (reg:CC FLAGS_REG))])] 
4330   "TARGET_80387"
4331   "")
4332
4333 (define_expand "fix_truncdfhi2"
4334   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4336               (clobber (reg:CC FLAGS_REG))])]
4337   "TARGET_80387 && !TARGET_SSE2"
4338   "")
4339
4340 (define_expand "fix_truncsfhi2"
4341   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4342                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4343                (clobber (reg:CC FLAGS_REG))])]
4344   "TARGET_80387 && !TARGET_SSE"
4345   "")
4346
4347 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4348 ;; of the machinery.
4349 (define_insn_and_split "*fix_trunchi_i387"
4350   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4351         (fix:HI (match_operand 1 "register_operand" "f,f")))
4352    (clobber (reg:CC FLAGS_REG))]
4353   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4354    && !reload_completed && !reload_in_progress
4355    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4356   "#"
4357   "&& 1"
4358   [(const_int 0)]
4359 {
4360   ix86_optimize_mode_switching = 1;
4361   operands[2] = assign_386_stack_local (HImode, 1);
4362   operands[3] = assign_386_stack_local (HImode, 2);
4363   if (memory_operand (operands[0], VOIDmode))
4364     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4365                                        operands[2], operands[3]));
4366   else
4367     {
4368       operands[4] = assign_386_stack_local (HImode, 0);
4369       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4370                                            operands[2], operands[3],
4371                                            operands[4]));
4372     }
4373   DONE;
4374 }
4375   [(set_attr "type" "fistp")
4376    (set_attr "i387_cw" "trunc")
4377    (set_attr "mode" "HI")])
4378
4379 (define_insn "fix_trunchi_nomemory"
4380   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4381         (fix:HI (match_operand 1 "register_operand" "f,f")))
4382    (use (match_operand:HI 2 "memory_operand" "m,m"))
4383    (use (match_operand:HI 3 "memory_operand" "m,m"))
4384    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4385   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4386    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4387   "#"
4388   [(set_attr "type" "fistp")
4389    (set_attr "i387_cw" "trunc")
4390    (set_attr "mode" "HI")])
4391
4392 (define_insn "fix_trunchi_memory"
4393   [(set (match_operand:HI 0 "memory_operand" "=m")
4394         (fix:HI (match_operand 1 "register_operand" "f")))
4395    (use (match_operand:HI 2 "memory_operand" "m"))
4396    (use (match_operand:HI 3 "memory_operand" "m"))]
4397   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4398    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4399   "* return output_fix_trunc (insn, operands);"
4400   [(set_attr "type" "fistp")
4401    (set_attr "i387_cw" "trunc")
4402    (set_attr "mode" "HI")])
4403
4404 (define_split 
4405   [(set (match_operand:HI 0 "memory_operand" "")
4406         (fix:HI (match_operand 1 "register_operand" "")))
4407    (use (match_operand:HI 2 "memory_operand" ""))
4408    (use (match_operand:HI 3 "memory_operand" ""))
4409    (clobber (match_operand:HI 4 "memory_operand" ""))]
4410   "reload_completed"
4411   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4412               (use (match_dup 2))
4413               (use (match_dup 3))])]
4414   "")
4415
4416 (define_split 
4417   [(set (match_operand:HI 0 "register_operand" "")
4418         (fix:HI (match_operand 1 "register_operand" "")))
4419    (use (match_operand:HI 2 "memory_operand" ""))
4420    (use (match_operand:HI 3 "memory_operand" ""))
4421    (clobber (match_operand:HI 4 "memory_operand" ""))]
4422   "reload_completed"
4423   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4424               (use (match_dup 2))
4425               (use (match_dup 3))
4426               (clobber (match_dup 4))])
4427    (set (match_dup 0) (match_dup 4))]
4428   "")
4429
4430 (define_insn "x86_fnstcw_1"
4431   [(set (match_operand:HI 0 "memory_operand" "=m")
4432         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4433   "TARGET_80387"
4434   "fnstcw\t%0"
4435   [(set_attr "length" "2")
4436    (set_attr "mode" "HI")
4437    (set_attr "unit" "i387")])
4438
4439 (define_insn "x86_fldcw_1"
4440   [(set (reg:HI FPSR_REG)
4441         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4442   "TARGET_80387"
4443   "fldcw\t%0"
4444   [(set_attr "length" "2")
4445    (set_attr "mode" "HI")
4446    (set_attr "unit" "i387")
4447    (set_attr "athlon_decode" "vector")])
4448 \f
4449 ;; Conversion between fixed point and floating point.
4450
4451 ;; Even though we only accept memory inputs, the backend _really_
4452 ;; wants to be able to do this between registers.
4453
4454 (define_expand "floathisf2"
4455   [(set (match_operand:SF 0 "register_operand" "")
4456         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4457   "TARGET_80387 || TARGET_SSE_MATH"
4458 {
4459   if (TARGET_SSE_MATH)
4460     {
4461       emit_insn (gen_floatsisf2 (operands[0],
4462                                  convert_to_mode (SImode, operands[1], 0)));
4463       DONE;
4464     }
4465 })
4466
4467 (define_insn "*floathisf2_i387"
4468   [(set (match_operand:SF 0 "register_operand" "=f,f")
4469         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4470   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4471   "@
4472    fild%z1\t%1
4473    #"
4474   [(set_attr "type" "fmov,multi")
4475    (set_attr "mode" "SF")
4476    (set_attr "fp_int_src" "true")])
4477
4478 (define_expand "floatsisf2"
4479   [(set (match_operand:SF 0 "register_operand" "")
4480         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4481   "TARGET_80387 || TARGET_SSE_MATH"
4482   "")
4483
4484 (define_insn "*floatsisf2_mixed"
4485   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4486         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4487   "TARGET_MIX_SSE_I387"
4488   "@
4489    fild%z1\t%1
4490    #
4491    cvtsi2ss\t{%1, %0|%0, %1}
4492    cvtsi2ss\t{%1, %0|%0, %1}"
4493   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4494    (set_attr "mode" "SF")
4495    (set_attr "athlon_decode" "*,*,vector,double")
4496    (set_attr "fp_int_src" "true")])
4497
4498 (define_insn "*floatsisf2_sse"
4499   [(set (match_operand:SF 0 "register_operand" "=x,x")
4500         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4501   "TARGET_SSE_MATH"
4502   "cvtsi2ss\t{%1, %0|%0, %1}"
4503   [(set_attr "type" "sseicvt")
4504    (set_attr "mode" "SF")
4505    (set_attr "athlon_decode" "vector,double")
4506    (set_attr "fp_int_src" "true")])
4507
4508 (define_insn "*floatsisf2_i387"
4509   [(set (match_operand:SF 0 "register_operand" "=f,f")
4510         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4511   "TARGET_80387"
4512   "@
4513    fild%z1\t%1
4514    #"
4515   [(set_attr "type" "fmov,multi")
4516    (set_attr "mode" "SF")
4517    (set_attr "fp_int_src" "true")])
4518
4519 (define_expand "floatdisf2"
4520   [(set (match_operand:SF 0 "register_operand" "")
4521         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4522   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4523   "")
4524
4525 (define_insn "*floatdisf2_mixed"
4526   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4527         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4528   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4529   "@
4530    fild%z1\t%1
4531    #
4532    cvtsi2ss{q}\t{%1, %0|%0, %1}
4533    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4534   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4535    (set_attr "mode" "SF")
4536    (set_attr "athlon_decode" "*,*,vector,double")
4537    (set_attr "fp_int_src" "true")])
4538
4539 (define_insn "*floatdisf2_sse"
4540   [(set (match_operand:SF 0 "register_operand" "=x,x")
4541         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4542   "TARGET_64BIT && TARGET_SSE_MATH"
4543   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4544   [(set_attr "type" "sseicvt")
4545    (set_attr "mode" "SF")
4546    (set_attr "athlon_decode" "vector,double")
4547    (set_attr "fp_int_src" "true")])
4548
4549 (define_insn "*floatdisf2_i387"
4550   [(set (match_operand:SF 0 "register_operand" "=f,f")
4551         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4552   "TARGET_80387"
4553   "@
4554    fild%z1\t%1
4555    #"
4556   [(set_attr "type" "fmov,multi")
4557    (set_attr "mode" "SF")
4558    (set_attr "fp_int_src" "true")])
4559
4560 (define_expand "floathidf2"
4561   [(set (match_operand:DF 0 "register_operand" "")
4562         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4563   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4564 {
4565   if (TARGET_SSE2 && TARGET_SSE_MATH)
4566     {
4567       emit_insn (gen_floatsidf2 (operands[0],
4568                                  convert_to_mode (SImode, operands[1], 0)));
4569       DONE;
4570     }
4571 })
4572
4573 (define_insn "*floathidf2_i387"
4574   [(set (match_operand:DF 0 "register_operand" "=f,f")
4575         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4576   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4577   "@
4578    fild%z1\t%1
4579    #"
4580   [(set_attr "type" "fmov,multi")
4581    (set_attr "mode" "DF")
4582    (set_attr "fp_int_src" "true")])
4583
4584 (define_expand "floatsidf2"
4585   [(set (match_operand:DF 0 "register_operand" "")
4586         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4587   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4588   "")
4589
4590 (define_insn "*floatsidf2_mixed"
4591   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4592         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4593   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4594   "@
4595    fild%z1\t%1
4596    #
4597    cvtsi2sd\t{%1, %0|%0, %1}
4598    cvtsi2sd\t{%1, %0|%0, %1}"
4599   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4600    (set_attr "mode" "DF")
4601    (set_attr "athlon_decode" "*,*,double,direct")
4602    (set_attr "fp_int_src" "true")])
4603
4604 (define_insn "*floatsidf2_sse"
4605   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4606         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4607   "TARGET_SSE2 && TARGET_SSE_MATH"
4608   "cvtsi2sd\t{%1, %0|%0, %1}"
4609   [(set_attr "type" "sseicvt")
4610    (set_attr "mode" "DF")
4611    (set_attr "athlon_decode" "double,direct")
4612    (set_attr "fp_int_src" "true")])
4613
4614 (define_insn "*floatsidf2_i387"
4615   [(set (match_operand:DF 0 "register_operand" "=f,f")
4616         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4617   "TARGET_80387"
4618   "@
4619    fild%z1\t%1
4620    #"
4621   [(set_attr "type" "fmov,multi")
4622    (set_attr "mode" "DF")
4623    (set_attr "fp_int_src" "true")])
4624
4625 (define_expand "floatdidf2"
4626   [(set (match_operand:DF 0 "register_operand" "")
4627         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4628   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4629   "")
4630
4631 (define_insn "*floatdidf2_mixed"
4632   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4633         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4634   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4635   "@
4636    fild%z1\t%1
4637    #
4638    cvtsi2sd{q}\t{%1, %0|%0, %1}
4639    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4640   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4641    (set_attr "mode" "DF")
4642    (set_attr "athlon_decode" "*,*,double,direct")
4643    (set_attr "fp_int_src" "true")])
4644
4645 (define_insn "*floatdidf2_sse"
4646   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4647         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4648   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4649   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4650   [(set_attr "type" "sseicvt")
4651    (set_attr "mode" "DF")
4652    (set_attr "athlon_decode" "double,direct")
4653    (set_attr "fp_int_src" "true")])
4654
4655 (define_insn "*floatdidf2_i387"
4656   [(set (match_operand:DF 0 "register_operand" "=f,f")
4657         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4658   "TARGET_80387"
4659   "@
4660    fild%z1\t%1
4661    #"
4662   [(set_attr "type" "fmov,multi")
4663    (set_attr "mode" "DF")
4664    (set_attr "fp_int_src" "true")])
4665
4666 (define_insn "floathixf2"
4667   [(set (match_operand:XF 0 "register_operand" "=f,f")
4668         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4669   "TARGET_80387"
4670   "@
4671    fild%z1\t%1
4672    #"
4673   [(set_attr "type" "fmov,multi")
4674    (set_attr "mode" "XF")
4675    (set_attr "fp_int_src" "true")])
4676
4677 (define_insn "floatsixf2"
4678   [(set (match_operand:XF 0 "register_operand" "=f,f")
4679         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4680   "TARGET_80387"
4681   "@
4682    fild%z1\t%1
4683    #"
4684   [(set_attr "type" "fmov,multi")
4685    (set_attr "mode" "XF")
4686    (set_attr "fp_int_src" "true")])
4687
4688 (define_insn "floatdixf2"
4689   [(set (match_operand:XF 0 "register_operand" "=f,f")
4690         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4691   "TARGET_80387"
4692   "@
4693    fild%z1\t%1
4694    #"
4695   [(set_attr "type" "fmov,multi")
4696    (set_attr "mode" "XF")
4697    (set_attr "fp_int_src" "true")])
4698
4699 ;; %%% Kill these when reload knows how to do it.
4700 (define_split
4701   [(set (match_operand 0 "fp_register_operand" "")
4702         (float (match_operand 1 "register_operand" "")))]
4703   "reload_completed
4704    && TARGET_80387
4705    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4706   [(const_int 0)]
4707 {
4708   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4709   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4710   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4711   ix86_free_from_memory (GET_MODE (operands[1]));
4712   DONE;
4713 })
4714
4715 (define_expand "floatunssisf2"
4716   [(use (match_operand:SF 0 "register_operand" ""))
4717    (use (match_operand:SI 1 "register_operand" ""))]
4718   "!TARGET_64BIT && TARGET_SSE_MATH"
4719   "x86_emit_floatuns (operands); DONE;")
4720
4721 (define_expand "floatunsdisf2"
4722   [(use (match_operand:SF 0 "register_operand" ""))
4723    (use (match_operand:DI 1 "register_operand" ""))]
4724   "TARGET_64BIT && TARGET_SSE_MATH"
4725   "x86_emit_floatuns (operands); DONE;")
4726
4727 (define_expand "floatunsdidf2"
4728   [(use (match_operand:DF 0 "register_operand" ""))
4729    (use (match_operand:DI 1 "register_operand" ""))]
4730   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4731   "x86_emit_floatuns (operands); DONE;")
4732 \f
4733 ;; SSE extract/set expanders
4734
4735 (define_expand "vec_setv2df"
4736   [(match_operand:V2DF 0 "register_operand" "")
4737    (match_operand:DF 1 "register_operand" "")
4738    (match_operand 2 "const_int_operand" "")]
4739   "TARGET_SSE2"
4740 {
4741   switch (INTVAL (operands[2]))
4742     {
4743     case 0:
4744       emit_insn (gen_sse2_loadlpd (operands[0], operands[0], operands[1]));
4745       break;
4746     case 1:
4747       emit_insn (gen_sse2_loadhpd (operands[0], operands[0], operands[1]));
4748       break;
4749     default:
4750       abort ();
4751     }
4752   DONE;
4753 })
4754
4755 (define_expand "vec_extractv2df"
4756   [(match_operand:DF 0 "register_operand" "")
4757    (match_operand:V2DF 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_storelpd (operands[0], operands[1]));
4765       break;
4766     case 1:
4767       emit_insn (gen_sse2_storehpd (operands[0], operands[1]));
4768       break;
4769     default:
4770       abort ();
4771     }
4772   DONE;
4773 })
4774
4775 (define_expand "vec_initv2df"
4776   [(match_operand:V2DF 0 "register_operand" "")
4777    (match_operand 1 "" "")]
4778   "TARGET_SSE2"
4779 {
4780   ix86_expand_vector_init (operands[0], operands[1]);
4781   DONE;
4782 })
4783
4784 (define_expand "vec_setv4sf"
4785   [(match_operand:V4SF 0 "register_operand" "")
4786    (match_operand:SF 1 "register_operand" "")
4787    (match_operand 2 "const_int_operand" "")]
4788   "TARGET_SSE"
4789 {
4790   switch (INTVAL (operands[2]))
4791     {
4792     case 0:
4793       emit_insn (gen_sse_movss (operands[0], operands[0],
4794                                 simplify_gen_subreg (V4SFmode, operands[1],
4795                                                      SFmode, 0)));
4796       break;
4797     case 1:
4798       {
4799         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4800         rtx tmp = gen_reg_rtx (V4SFmode);
4801  
4802         emit_move_insn (tmp, operands[0]);
4803         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4804         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4805         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4806                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4807       }
4808       break;
4809     case 2:
4810       {
4811         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4812         rtx tmp = gen_reg_rtx (V4SFmode);
4813
4814         emit_move_insn (tmp, operands[0]);
4815         emit_insn (gen_sse_movss (tmp, tmp, op1));
4816         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4817                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4818       }
4819       break;
4820     case 3:
4821       {
4822         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4823         rtx tmp = gen_reg_rtx (V4SFmode);
4824
4825         emit_move_insn (tmp, operands[0]);
4826         emit_insn (gen_sse_movss (tmp, tmp, op1));
4827         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4828                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4829       }
4830       break;
4831     default:
4832       abort ();
4833     }
4834   DONE;
4835 })
4836
4837 (define_expand "vec_extractv4sf"
4838   [(match_operand:SF 0 "register_operand" "")
4839    (match_operand:V4SF 1 "register_operand" "")
4840    (match_operand 2 "const_int_operand" "")]
4841   "TARGET_SSE"
4842 {
4843   switch (INTVAL (operands[2]))
4844     {
4845     case 0:
4846       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4847       break;
4848     case 1:
4849       {
4850         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4851         rtx tmp = gen_reg_rtx (V4SFmode);
4852  
4853         emit_move_insn (tmp, operands[1]);
4854         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4855                                    const1_rtx));
4856       }
4857       break;
4858     case 2:
4859       {
4860         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4861         rtx tmp = gen_reg_rtx (V4SFmode);
4862  
4863         emit_move_insn (tmp, operands[1]);
4864         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4865       }
4866       break;
4867     case 3:
4868       {
4869         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4870         rtx tmp = gen_reg_rtx (V4SFmode);
4871  
4872         emit_move_insn (tmp, operands[1]);
4873         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4874                                    GEN_INT (3)));
4875       }
4876       break;
4877     default:
4878       abort ();
4879     }
4880   DONE;
4881 })
4882
4883 (define_expand "vec_initv4sf"
4884   [(match_operand:V4SF 0 "register_operand" "")
4885    (match_operand 1 "" "")]
4886   "TARGET_SSE"
4887 {
4888   ix86_expand_vector_init (operands[0], operands[1]);
4889   DONE;
4890 })
4891 \f
4892 ;; Add instructions
4893
4894 ;; %%% splits for addsidi3
4895 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4896 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4897 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4898
4899 (define_expand "adddi3"
4900   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4901         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4902                  (match_operand:DI 2 "x86_64_general_operand" "")))
4903    (clobber (reg:CC FLAGS_REG))]
4904   ""
4905   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4906
4907 (define_insn "*adddi3_1"
4908   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4909         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4910                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4911    (clobber (reg:CC FLAGS_REG))]
4912   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4913   "#")
4914
4915 (define_split
4916   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4917         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4918                  (match_operand:DI 2 "general_operand" "")))
4919    (clobber (reg:CC FLAGS_REG))]
4920   "!TARGET_64BIT && reload_completed"
4921   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4922                                           UNSPEC_ADD_CARRY))
4923               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4924    (parallel [(set (match_dup 3)
4925                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4926                                      (match_dup 4))
4927                             (match_dup 5)))
4928               (clobber (reg:CC FLAGS_REG))])]
4929   "split_di (operands+0, 1, operands+0, operands+3);
4930    split_di (operands+1, 1, operands+1, operands+4);
4931    split_di (operands+2, 1, operands+2, operands+5);")
4932
4933 (define_insn "adddi3_carry_rex64"
4934   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4935           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4936                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4937                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4938    (clobber (reg:CC FLAGS_REG))]
4939   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4940   "adc{q}\t{%2, %0|%0, %2}"
4941   [(set_attr "type" "alu")
4942    (set_attr "pent_pair" "pu")
4943    (set_attr "mode" "DI")])
4944
4945 (define_insn "*adddi3_cc_rex64"
4946   [(set (reg:CC FLAGS_REG)
4947         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4948                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4949                    UNSPEC_ADD_CARRY))
4950    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4951         (plus:DI (match_dup 1) (match_dup 2)))]
4952   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4953   "add{q}\t{%2, %0|%0, %2}"
4954   [(set_attr "type" "alu")
4955    (set_attr "mode" "DI")])
4956
4957 (define_insn "addqi3_carry"
4958   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4959           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4960                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4961                    (match_operand:QI 2 "general_operand" "qi,qm")))
4962    (clobber (reg:CC FLAGS_REG))]
4963   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4964   "adc{b}\t{%2, %0|%0, %2}"
4965   [(set_attr "type" "alu")
4966    (set_attr "pent_pair" "pu")
4967    (set_attr "mode" "QI")])
4968
4969 (define_insn "addhi3_carry"
4970   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4971           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4972                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4973                    (match_operand:HI 2 "general_operand" "ri,rm")))
4974    (clobber (reg:CC FLAGS_REG))]
4975   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4976   "adc{w}\t{%2, %0|%0, %2}"
4977   [(set_attr "type" "alu")
4978    (set_attr "pent_pair" "pu")
4979    (set_attr "mode" "HI")])
4980
4981 (define_insn "addsi3_carry"
4982   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4983           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4984                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4985                    (match_operand:SI 2 "general_operand" "ri,rm")))
4986    (clobber (reg:CC FLAGS_REG))]
4987   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4988   "adc{l}\t{%2, %0|%0, %2}"
4989   [(set_attr "type" "alu")
4990    (set_attr "pent_pair" "pu")
4991    (set_attr "mode" "SI")])
4992
4993 (define_insn "*addsi3_carry_zext"
4994   [(set (match_operand:DI 0 "register_operand" "=r")
4995           (zero_extend:DI 
4996             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4997                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4998                      (match_operand:SI 2 "general_operand" "rim"))))
4999    (clobber (reg:CC FLAGS_REG))]
5000   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5001   "adc{l}\t{%2, %k0|%k0, %2}"
5002   [(set_attr "type" "alu")
5003    (set_attr "pent_pair" "pu")
5004    (set_attr "mode" "SI")])
5005
5006 (define_insn "*addsi3_cc"
5007   [(set (reg:CC FLAGS_REG)
5008         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5009                     (match_operand:SI 2 "general_operand" "ri,rm")]
5010                    UNSPEC_ADD_CARRY))
5011    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5012         (plus:SI (match_dup 1) (match_dup 2)))]
5013   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5014   "add{l}\t{%2, %0|%0, %2}"
5015   [(set_attr "type" "alu")
5016    (set_attr "mode" "SI")])
5017
5018 (define_insn "addqi3_cc"
5019   [(set (reg:CC FLAGS_REG)
5020         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5021                     (match_operand:QI 2 "general_operand" "qi,qm")]
5022                    UNSPEC_ADD_CARRY))
5023    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5024         (plus:QI (match_dup 1) (match_dup 2)))]
5025   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5026   "add{b}\t{%2, %0|%0, %2}"
5027   [(set_attr "type" "alu")
5028    (set_attr "mode" "QI")])
5029
5030 (define_expand "addsi3"
5031   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5032                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5033                             (match_operand:SI 2 "general_operand" "")))
5034               (clobber (reg:CC FLAGS_REG))])]
5035   ""
5036   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5037
5038 (define_insn "*lea_1"
5039   [(set (match_operand:SI 0 "register_operand" "=r")
5040         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5041   "!TARGET_64BIT"
5042   "lea{l}\t{%a1, %0|%0, %a1}"
5043   [(set_attr "type" "lea")
5044    (set_attr "mode" "SI")])
5045
5046 (define_insn "*lea_1_rex64"
5047   [(set (match_operand:SI 0 "register_operand" "=r")
5048         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5049   "TARGET_64BIT"
5050   "lea{l}\t{%a1, %0|%0, %a1}"
5051   [(set_attr "type" "lea")
5052    (set_attr "mode" "SI")])
5053
5054 (define_insn "*lea_1_zext"
5055   [(set (match_operand:DI 0 "register_operand" "=r")
5056         (zero_extend:DI
5057          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5058   "TARGET_64BIT"
5059   "lea{l}\t{%a1, %k0|%k0, %a1}"
5060   [(set_attr "type" "lea")
5061    (set_attr "mode" "SI")])
5062
5063 (define_insn "*lea_2_rex64"
5064   [(set (match_operand:DI 0 "register_operand" "=r")
5065         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5066   "TARGET_64BIT"
5067   "lea{q}\t{%a1, %0|%0, %a1}"
5068   [(set_attr "type" "lea")
5069    (set_attr "mode" "DI")])
5070
5071 ;; The lea patterns for non-Pmodes needs to be matched by several
5072 ;; insns converted to real lea by splitters.
5073
5074 (define_insn_and_split "*lea_general_1"
5075   [(set (match_operand 0 "register_operand" "=r")
5076         (plus (plus (match_operand 1 "index_register_operand" "l")
5077                     (match_operand 2 "register_operand" "r"))
5078               (match_operand 3 "immediate_operand" "i")))]
5079   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5080     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5081    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5082    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5083    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5084    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5085        || GET_MODE (operands[3]) == VOIDmode)"
5086   "#"
5087   "&& reload_completed"
5088   [(const_int 0)]
5089 {
5090   rtx pat;
5091   operands[0] = gen_lowpart (SImode, operands[0]);
5092   operands[1] = gen_lowpart (Pmode, operands[1]);
5093   operands[2] = gen_lowpart (Pmode, operands[2]);
5094   operands[3] = gen_lowpart (Pmode, operands[3]);
5095   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5096                       operands[3]);
5097   if (Pmode != SImode)
5098     pat = gen_rtx_SUBREG (SImode, pat, 0);
5099   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5100   DONE;
5101 }
5102   [(set_attr "type" "lea")
5103    (set_attr "mode" "SI")])
5104
5105 (define_insn_and_split "*lea_general_1_zext"
5106   [(set (match_operand:DI 0 "register_operand" "=r")
5107         (zero_extend:DI
5108           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5109                             (match_operand:SI 2 "register_operand" "r"))
5110                    (match_operand:SI 3 "immediate_operand" "i"))))]
5111   "TARGET_64BIT"
5112   "#"
5113   "&& reload_completed"
5114   [(set (match_dup 0)
5115         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5116                                                      (match_dup 2))
5117                                             (match_dup 3)) 0)))]
5118 {
5119   operands[1] = gen_lowpart (Pmode, operands[1]);
5120   operands[2] = gen_lowpart (Pmode, operands[2]);
5121   operands[3] = gen_lowpart (Pmode, operands[3]);
5122 }
5123   [(set_attr "type" "lea")
5124    (set_attr "mode" "SI")])
5125
5126 (define_insn_and_split "*lea_general_2"
5127   [(set (match_operand 0 "register_operand" "=r")
5128         (plus (mult (match_operand 1 "index_register_operand" "l")
5129                     (match_operand 2 "const248_operand" "i"))
5130               (match_operand 3 "nonmemory_operand" "ri")))]
5131   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5132     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5133    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5134    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5135    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5136        || GET_MODE (operands[3]) == VOIDmode)"
5137   "#"
5138   "&& reload_completed"
5139   [(const_int 0)]
5140 {
5141   rtx pat;
5142   operands[0] = gen_lowpart (SImode, operands[0]);
5143   operands[1] = gen_lowpart (Pmode, operands[1]);
5144   operands[3] = gen_lowpart (Pmode, operands[3]);
5145   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5146                       operands[3]);
5147   if (Pmode != SImode)
5148     pat = gen_rtx_SUBREG (SImode, pat, 0);
5149   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5150   DONE;
5151 }
5152   [(set_attr "type" "lea")
5153    (set_attr "mode" "SI")])
5154
5155 (define_insn_and_split "*lea_general_2_zext"
5156   [(set (match_operand:DI 0 "register_operand" "=r")
5157         (zero_extend:DI
5158           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5159                             (match_operand:SI 2 "const248_operand" "n"))
5160                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5161   "TARGET_64BIT"
5162   "#"
5163   "&& reload_completed"
5164   [(set (match_dup 0)
5165         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5166                                                      (match_dup 2))
5167                                             (match_dup 3)) 0)))]
5168 {
5169   operands[1] = gen_lowpart (Pmode, operands[1]);
5170   operands[3] = gen_lowpart (Pmode, operands[3]);
5171 }
5172   [(set_attr "type" "lea")
5173    (set_attr "mode" "SI")])
5174
5175 (define_insn_and_split "*lea_general_3"
5176   [(set (match_operand 0 "register_operand" "=r")
5177         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5178                           (match_operand 2 "const248_operand" "i"))
5179                     (match_operand 3 "register_operand" "r"))
5180               (match_operand 4 "immediate_operand" "i")))]
5181   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5182     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5183    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5184    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5185    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5186   "#"
5187   "&& reload_completed"
5188   [(const_int 0)]
5189 {
5190   rtx pat;
5191   operands[0] = gen_lowpart (SImode, operands[0]);
5192   operands[1] = gen_lowpart (Pmode, operands[1]);
5193   operands[3] = gen_lowpart (Pmode, operands[3]);
5194   operands[4] = gen_lowpart (Pmode, operands[4]);
5195   pat = gen_rtx_PLUS (Pmode,
5196                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5197                                                          operands[2]),
5198                                     operands[3]),
5199                       operands[4]);
5200   if (Pmode != SImode)
5201     pat = gen_rtx_SUBREG (SImode, pat, 0);
5202   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5203   DONE;
5204 }
5205   [(set_attr "type" "lea")
5206    (set_attr "mode" "SI")])
5207
5208 (define_insn_and_split "*lea_general_3_zext"
5209   [(set (match_operand:DI 0 "register_operand" "=r")
5210         (zero_extend:DI
5211           (plus:SI (plus:SI (mult:SI
5212                               (match_operand:SI 1 "index_register_operand" "l")
5213                               (match_operand:SI 2 "const248_operand" "n"))
5214                             (match_operand:SI 3 "register_operand" "r"))
5215                    (match_operand:SI 4 "immediate_operand" "i"))))]
5216   "TARGET_64BIT"
5217   "#"
5218   "&& reload_completed"
5219   [(set (match_dup 0)
5220         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5221                                                               (match_dup 2))
5222                                                      (match_dup 3))
5223                                             (match_dup 4)) 0)))]
5224 {
5225   operands[1] = gen_lowpart (Pmode, operands[1]);
5226   operands[3] = gen_lowpart (Pmode, operands[3]);
5227   operands[4] = gen_lowpart (Pmode, operands[4]);
5228 }
5229   [(set_attr "type" "lea")
5230    (set_attr "mode" "SI")])
5231
5232 (define_insn "*adddi_1_rex64"
5233   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5234         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5235                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5236    (clobber (reg:CC FLAGS_REG))]
5237   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5238 {
5239   switch (get_attr_type (insn))
5240     {
5241     case TYPE_LEA:
5242       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5243       return "lea{q}\t{%a2, %0|%0, %a2}";
5244
5245     case TYPE_INCDEC:
5246       if (! rtx_equal_p (operands[0], operands[1]))
5247         abort ();
5248       if (operands[2] == const1_rtx)
5249         return "inc{q}\t%0";
5250       else if (operands[2] == constm1_rtx)
5251         return "dec{q}\t%0";
5252       else
5253         abort ();
5254
5255     default:
5256       if (! rtx_equal_p (operands[0], operands[1]))
5257         abort ();
5258
5259       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5261       if (GET_CODE (operands[2]) == CONST_INT
5262           /* Avoid overflows.  */
5263           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5264           && (INTVAL (operands[2]) == 128
5265               || (INTVAL (operands[2]) < 0
5266                   && INTVAL (operands[2]) != -128)))
5267         {
5268           operands[2] = GEN_INT (-INTVAL (operands[2]));
5269           return "sub{q}\t{%2, %0|%0, %2}";
5270         }
5271       return "add{q}\t{%2, %0|%0, %2}";
5272     }
5273 }
5274   [(set (attr "type")
5275      (cond [(eq_attr "alternative" "2")
5276               (const_string "lea")
5277             ; Current assemblers are broken and do not allow @GOTOFF in
5278             ; ought but a memory context.
5279             (match_operand:DI 2 "pic_symbolic_operand" "")
5280               (const_string "lea")
5281             (match_operand:DI 2 "incdec_operand" "")
5282               (const_string "incdec")
5283            ]
5284            (const_string "alu")))
5285    (set_attr "mode" "DI")])
5286
5287 ;; Convert lea to the lea pattern to avoid flags dependency.
5288 (define_split
5289   [(set (match_operand:DI 0 "register_operand" "")
5290         (plus:DI (match_operand:DI 1 "register_operand" "")
5291                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5292    (clobber (reg:CC FLAGS_REG))]
5293   "TARGET_64BIT && reload_completed
5294    && true_regnum (operands[0]) != true_regnum (operands[1])"
5295   [(set (match_dup 0)
5296         (plus:DI (match_dup 1)
5297                  (match_dup 2)))]
5298   "")
5299
5300 (define_insn "*adddi_2_rex64"
5301   [(set (reg FLAGS_REG)
5302         (compare
5303           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5304                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5305           (const_int 0)))                       
5306    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5307         (plus:DI (match_dup 1) (match_dup 2)))]
5308   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5309    && ix86_binary_operator_ok (PLUS, DImode, operands)
5310    /* Current assemblers are broken and do not allow @GOTOFF in
5311       ought but a memory context.  */
5312    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5313 {
5314   switch (get_attr_type (insn))
5315     {
5316     case TYPE_INCDEC:
5317       if (! rtx_equal_p (operands[0], operands[1]))
5318         abort ();
5319       if (operands[2] == const1_rtx)
5320         return "inc{q}\t%0";
5321       else if (operands[2] == constm1_rtx)
5322         return "dec{q}\t%0";
5323       else
5324         abort ();
5325
5326     default:
5327       if (! rtx_equal_p (operands[0], operands[1]))
5328         abort ();
5329       /* ???? We ought to handle there the 32bit case too
5330          - do we need new constraint?  */
5331       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5332          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5333       if (GET_CODE (operands[2]) == CONST_INT
5334           /* Avoid overflows.  */
5335           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5336           && (INTVAL (operands[2]) == 128
5337               || (INTVAL (operands[2]) < 0
5338                   && INTVAL (operands[2]) != -128)))
5339         {
5340           operands[2] = GEN_INT (-INTVAL (operands[2]));
5341           return "sub{q}\t{%2, %0|%0, %2}";
5342         }
5343       return "add{q}\t{%2, %0|%0, %2}";
5344     }
5345 }
5346   [(set (attr "type")
5347      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5348         (const_string "incdec")
5349         (const_string "alu")))
5350    (set_attr "mode" "DI")])
5351
5352 (define_insn "*adddi_3_rex64"
5353   [(set (reg FLAGS_REG)
5354         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5355                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5356    (clobber (match_scratch:DI 0 "=r"))]
5357   "TARGET_64BIT
5358    && ix86_match_ccmode (insn, CCZmode)
5359    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5360    /* Current assemblers are broken and do not allow @GOTOFF in
5361       ought but a memory context.  */
5362    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5363 {
5364   switch (get_attr_type (insn))
5365     {
5366     case TYPE_INCDEC:
5367       if (! rtx_equal_p (operands[0], operands[1]))
5368         abort ();
5369       if (operands[2] == const1_rtx)
5370         return "inc{q}\t%0";
5371       else if (operands[2] == constm1_rtx)
5372         return "dec{q}\t%0";
5373       else
5374         abort ();
5375
5376     default:
5377       if (! rtx_equal_p (operands[0], operands[1]))
5378         abort ();
5379       /* ???? We ought to handle there the 32bit case too
5380          - do we need new constraint?  */
5381       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5382          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5383       if (GET_CODE (operands[2]) == CONST_INT
5384           /* Avoid overflows.  */
5385           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5386           && (INTVAL (operands[2]) == 128
5387               || (INTVAL (operands[2]) < 0
5388                   && INTVAL (operands[2]) != -128)))
5389         {
5390           operands[2] = GEN_INT (-INTVAL (operands[2]));
5391           return "sub{q}\t{%2, %0|%0, %2}";
5392         }
5393       return "add{q}\t{%2, %0|%0, %2}";
5394     }
5395 }
5396   [(set (attr "type")
5397      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5398         (const_string "incdec")
5399         (const_string "alu")))
5400    (set_attr "mode" "DI")])
5401
5402 ; For comparisons against 1, -1 and 128, we may generate better code
5403 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5404 ; is matched then.  We can't accept general immediate, because for
5405 ; case of overflows,  the result is messed up.
5406 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5407 ; when negated.
5408 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5409 ; only for comparisons not depending on it.
5410 (define_insn "*adddi_4_rex64"
5411   [(set (reg FLAGS_REG)
5412         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5413                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5414    (clobber (match_scratch:DI 0 "=rm"))]
5415   "TARGET_64BIT
5416    &&  ix86_match_ccmode (insn, CCGCmode)"
5417 {
5418   switch (get_attr_type (insn))
5419     {
5420     case TYPE_INCDEC:
5421       if (operands[2] == constm1_rtx)
5422         return "inc{q}\t%0";
5423       else if (operands[2] == const1_rtx)
5424         return "dec{q}\t%0";
5425       else
5426         abort();
5427
5428     default:
5429       if (! rtx_equal_p (operands[0], operands[1]))
5430         abort ();
5431       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5432          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5433       if ((INTVAL (operands[2]) == -128
5434            || (INTVAL (operands[2]) > 0
5435                && INTVAL (operands[2]) != 128))
5436           /* Avoid overflows.  */
5437           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5438         return "sub{q}\t{%2, %0|%0, %2}";
5439       operands[2] = GEN_INT (-INTVAL (operands[2]));
5440       return "add{q}\t{%2, %0|%0, %2}";
5441     }
5442 }
5443   [(set (attr "type")
5444      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5445         (const_string "incdec")
5446         (const_string "alu")))
5447    (set_attr "mode" "DI")])
5448
5449 (define_insn "*adddi_5_rex64"
5450   [(set (reg FLAGS_REG)
5451         (compare
5452           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5453                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5454           (const_int 0)))                       
5455    (clobber (match_scratch:DI 0 "=r"))]
5456   "TARGET_64BIT
5457    && ix86_match_ccmode (insn, CCGOCmode)
5458    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5459    /* Current assemblers are broken and do not allow @GOTOFF in
5460       ought but a memory context.  */
5461    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5462 {
5463   switch (get_attr_type (insn))
5464     {
5465     case TYPE_INCDEC:
5466       if (! rtx_equal_p (operands[0], operands[1]))
5467         abort ();
5468       if (operands[2] == const1_rtx)
5469         return "inc{q}\t%0";
5470       else if (operands[2] == constm1_rtx)
5471         return "dec{q}\t%0";
5472       else
5473         abort();
5474
5475     default:
5476       if (! rtx_equal_p (operands[0], operands[1]))
5477         abort ();
5478       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5479          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5480       if (GET_CODE (operands[2]) == CONST_INT
5481           /* Avoid overflows.  */
5482           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5483           && (INTVAL (operands[2]) == 128
5484               || (INTVAL (operands[2]) < 0
5485                   && INTVAL (operands[2]) != -128)))
5486         {
5487           operands[2] = GEN_INT (-INTVAL (operands[2]));
5488           return "sub{q}\t{%2, %0|%0, %2}";
5489         }
5490       return "add{q}\t{%2, %0|%0, %2}";
5491     }
5492 }
5493   [(set (attr "type")
5494      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5495         (const_string "incdec")
5496         (const_string "alu")))
5497    (set_attr "mode" "DI")])
5498
5499
5500 (define_insn "*addsi_1"
5501   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5502         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5503                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5504    (clobber (reg:CC FLAGS_REG))]
5505   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5506 {
5507   switch (get_attr_type (insn))
5508     {
5509     case TYPE_LEA:
5510       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5511       return "lea{l}\t{%a2, %0|%0, %a2}";
5512
5513     case TYPE_INCDEC:
5514       if (! rtx_equal_p (operands[0], operands[1]))
5515         abort ();
5516       if (operands[2] == const1_rtx)
5517         return "inc{l}\t%0";
5518       else if (operands[2] == constm1_rtx)
5519         return "dec{l}\t%0";
5520       else
5521         abort();
5522
5523     default:
5524       if (! rtx_equal_p (operands[0], operands[1]))
5525         abort ();
5526
5527       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5528          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5529       if (GET_CODE (operands[2]) == CONST_INT
5530           && (INTVAL (operands[2]) == 128
5531               || (INTVAL (operands[2]) < 0
5532                   && INTVAL (operands[2]) != -128)))
5533         {
5534           operands[2] = GEN_INT (-INTVAL (operands[2]));
5535           return "sub{l}\t{%2, %0|%0, %2}";
5536         }
5537       return "add{l}\t{%2, %0|%0, %2}";
5538     }
5539 }
5540   [(set (attr "type")
5541      (cond [(eq_attr "alternative" "2")
5542               (const_string "lea")
5543             ; Current assemblers are broken and do not allow @GOTOFF in
5544             ; ought but a memory context.
5545             (match_operand:SI 2 "pic_symbolic_operand" "")
5546               (const_string "lea")
5547             (match_operand:SI 2 "incdec_operand" "")
5548               (const_string "incdec")
5549            ]
5550            (const_string "alu")))
5551    (set_attr "mode" "SI")])
5552
5553 ;; Convert lea to the lea pattern to avoid flags dependency.
5554 (define_split
5555   [(set (match_operand 0 "register_operand" "")
5556         (plus (match_operand 1 "register_operand" "")
5557               (match_operand 2 "nonmemory_operand" "")))
5558    (clobber (reg:CC FLAGS_REG))]
5559   "reload_completed
5560    && true_regnum (operands[0]) != true_regnum (operands[1])"
5561   [(const_int 0)]
5562 {
5563   rtx pat;
5564   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5565      may confuse gen_lowpart.  */
5566   if (GET_MODE (operands[0]) != Pmode)
5567     {
5568       operands[1] = gen_lowpart (Pmode, operands[1]);
5569       operands[2] = gen_lowpart (Pmode, operands[2]);
5570     }
5571   operands[0] = gen_lowpart (SImode, operands[0]);
5572   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5573   if (Pmode != SImode)
5574     pat = gen_rtx_SUBREG (SImode, pat, 0);
5575   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5576   DONE;
5577 })
5578
5579 ;; It may seem that nonimmediate operand is proper one for operand 1.
5580 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5581 ;; we take care in ix86_binary_operator_ok to not allow two memory
5582 ;; operands so proper swapping will be done in reload.  This allow
5583 ;; patterns constructed from addsi_1 to match.
5584 (define_insn "addsi_1_zext"
5585   [(set (match_operand:DI 0 "register_operand" "=r,r")
5586         (zero_extend:DI
5587           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5588                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5589    (clobber (reg:CC FLAGS_REG))]
5590   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5591 {
5592   switch (get_attr_type (insn))
5593     {
5594     case TYPE_LEA:
5595       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5596       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5597
5598     case TYPE_INCDEC:
5599       if (operands[2] == const1_rtx)
5600         return "inc{l}\t%k0";
5601       else if (operands[2] == constm1_rtx)
5602         return "dec{l}\t%k0";
5603       else
5604         abort();
5605
5606     default:
5607       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5608          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5609       if (GET_CODE (operands[2]) == CONST_INT
5610           && (INTVAL (operands[2]) == 128
5611               || (INTVAL (operands[2]) < 0
5612                   && INTVAL (operands[2]) != -128)))
5613         {
5614           operands[2] = GEN_INT (-INTVAL (operands[2]));
5615           return "sub{l}\t{%2, %k0|%k0, %2}";
5616         }
5617       return "add{l}\t{%2, %k0|%k0, %2}";
5618     }
5619 }
5620   [(set (attr "type")
5621      (cond [(eq_attr "alternative" "1")
5622               (const_string "lea")
5623             ; Current assemblers are broken and do not allow @GOTOFF in
5624             ; ought but a memory context.
5625             (match_operand:SI 2 "pic_symbolic_operand" "")
5626               (const_string "lea")
5627             (match_operand:SI 2 "incdec_operand" "")
5628               (const_string "incdec")
5629            ]
5630            (const_string "alu")))
5631    (set_attr "mode" "SI")])
5632
5633 ;; Convert lea to the lea pattern to avoid flags dependency.
5634 (define_split
5635   [(set (match_operand:DI 0 "register_operand" "")
5636         (zero_extend:DI
5637           (plus:SI (match_operand:SI 1 "register_operand" "")
5638                    (match_operand:SI 2 "nonmemory_operand" ""))))
5639    (clobber (reg:CC FLAGS_REG))]
5640   "TARGET_64BIT && reload_completed
5641    && true_regnum (operands[0]) != true_regnum (operands[1])"
5642   [(set (match_dup 0)
5643         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5644 {
5645   operands[1] = gen_lowpart (Pmode, operands[1]);
5646   operands[2] = gen_lowpart (Pmode, operands[2]);
5647 })
5648
5649 (define_insn "*addsi_2"
5650   [(set (reg FLAGS_REG)
5651         (compare
5652           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5653                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5654           (const_int 0)))                       
5655    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5656         (plus:SI (match_dup 1) (match_dup 2)))]
5657   "ix86_match_ccmode (insn, CCGOCmode)
5658    && ix86_binary_operator_ok (PLUS, SImode, operands)
5659    /* Current assemblers are broken and do not allow @GOTOFF in
5660       ought but a memory context.  */
5661    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5662 {
5663   switch (get_attr_type (insn))
5664     {
5665     case TYPE_INCDEC:
5666       if (! rtx_equal_p (operands[0], operands[1]))
5667         abort ();
5668       if (operands[2] == const1_rtx)
5669         return "inc{l}\t%0";
5670       else if (operands[2] == constm1_rtx)
5671         return "dec{l}\t%0";
5672       else
5673         abort();
5674
5675     default:
5676       if (! rtx_equal_p (operands[0], operands[1]))
5677         abort ();
5678       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5679          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5680       if (GET_CODE (operands[2]) == CONST_INT
5681           && (INTVAL (operands[2]) == 128
5682               || (INTVAL (operands[2]) < 0
5683                   && INTVAL (operands[2]) != -128)))
5684         {
5685           operands[2] = GEN_INT (-INTVAL (operands[2]));
5686           return "sub{l}\t{%2, %0|%0, %2}";
5687         }
5688       return "add{l}\t{%2, %0|%0, %2}";
5689     }
5690 }
5691   [(set (attr "type")
5692      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5693         (const_string "incdec")
5694         (const_string "alu")))
5695    (set_attr "mode" "SI")])
5696
5697 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5698 (define_insn "*addsi_2_zext"
5699   [(set (reg FLAGS_REG)
5700         (compare
5701           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5702                    (match_operand:SI 2 "general_operand" "rmni"))
5703           (const_int 0)))                       
5704    (set (match_operand:DI 0 "register_operand" "=r")
5705         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5706   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5707    && ix86_binary_operator_ok (PLUS, SImode, operands)
5708    /* Current assemblers are broken and do not allow @GOTOFF in
5709       ought but a memory context.  */
5710    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5711 {
5712   switch (get_attr_type (insn))
5713     {
5714     case TYPE_INCDEC:
5715       if (operands[2] == const1_rtx)
5716         return "inc{l}\t%k0";
5717       else if (operands[2] == constm1_rtx)
5718         return "dec{l}\t%k0";
5719       else
5720         abort();
5721
5722     default:
5723       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5724          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5725       if (GET_CODE (operands[2]) == CONST_INT
5726           && (INTVAL (operands[2]) == 128
5727               || (INTVAL (operands[2]) < 0
5728                   && INTVAL (operands[2]) != -128)))
5729         {
5730           operands[2] = GEN_INT (-INTVAL (operands[2]));
5731           return "sub{l}\t{%2, %k0|%k0, %2}";
5732         }
5733       return "add{l}\t{%2, %k0|%k0, %2}";
5734     }
5735 }
5736   [(set (attr "type")
5737      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5738         (const_string "incdec")
5739         (const_string "alu")))
5740    (set_attr "mode" "SI")])
5741
5742 (define_insn "*addsi_3"
5743   [(set (reg FLAGS_REG)
5744         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5745                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5746    (clobber (match_scratch:SI 0 "=r"))]
5747   "ix86_match_ccmode (insn, CCZmode)
5748    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5749    /* Current assemblers are broken and do not allow @GOTOFF in
5750       ought but a memory context.  */
5751    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5752 {
5753   switch (get_attr_type (insn))
5754     {
5755     case TYPE_INCDEC:
5756       if (! rtx_equal_p (operands[0], operands[1]))
5757         abort ();
5758       if (operands[2] == const1_rtx)
5759         return "inc{l}\t%0";
5760       else if (operands[2] == constm1_rtx)
5761         return "dec{l}\t%0";
5762       else
5763         abort();
5764
5765     default:
5766       if (! rtx_equal_p (operands[0], operands[1]))
5767         abort ();
5768       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5769          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5770       if (GET_CODE (operands[2]) == CONST_INT
5771           && (INTVAL (operands[2]) == 128
5772               || (INTVAL (operands[2]) < 0
5773                   && INTVAL (operands[2]) != -128)))
5774         {
5775           operands[2] = GEN_INT (-INTVAL (operands[2]));
5776           return "sub{l}\t{%2, %0|%0, %2}";
5777         }
5778       return "add{l}\t{%2, %0|%0, %2}";
5779     }
5780 }
5781   [(set (attr "type")
5782      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5783         (const_string "incdec")
5784         (const_string "alu")))
5785    (set_attr "mode" "SI")])
5786
5787 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5788 (define_insn "*addsi_3_zext"
5789   [(set (reg FLAGS_REG)
5790         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5791                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5792    (set (match_operand:DI 0 "register_operand" "=r")
5793         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5794   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5795    && ix86_binary_operator_ok (PLUS, SImode, operands)
5796    /* Current assemblers are broken and do not allow @GOTOFF in
5797       ought but a memory context.  */
5798    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5799 {
5800   switch (get_attr_type (insn))
5801     {
5802     case TYPE_INCDEC:
5803       if (operands[2] == const1_rtx)
5804         return "inc{l}\t%k0";
5805       else if (operands[2] == constm1_rtx)
5806         return "dec{l}\t%k0";
5807       else
5808         abort();
5809
5810     default:
5811       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5812          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5813       if (GET_CODE (operands[2]) == CONST_INT
5814           && (INTVAL (operands[2]) == 128
5815               || (INTVAL (operands[2]) < 0
5816                   && INTVAL (operands[2]) != -128)))
5817         {
5818           operands[2] = GEN_INT (-INTVAL (operands[2]));
5819           return "sub{l}\t{%2, %k0|%k0, %2}";
5820         }
5821       return "add{l}\t{%2, %k0|%k0, %2}";
5822     }
5823 }
5824   [(set (attr "type")
5825      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5826         (const_string "incdec")
5827         (const_string "alu")))
5828    (set_attr "mode" "SI")])
5829
5830 ; For comparisons against 1, -1 and 128, we may generate better code
5831 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5832 ; is matched then.  We can't accept general immediate, because for
5833 ; case of overflows,  the result is messed up.
5834 ; This pattern also don't hold of 0x80000000, since the value overflows
5835 ; when negated.
5836 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5837 ; only for comparisons not depending on it.
5838 (define_insn "*addsi_4"
5839   [(set (reg FLAGS_REG)
5840         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5841                  (match_operand:SI 2 "const_int_operand" "n")))
5842    (clobber (match_scratch:SI 0 "=rm"))]
5843   "ix86_match_ccmode (insn, CCGCmode)
5844    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5845 {
5846   switch (get_attr_type (insn))
5847     {
5848     case TYPE_INCDEC:
5849       if (operands[2] == constm1_rtx)
5850         return "inc{l}\t%0";
5851       else if (operands[2] == const1_rtx)
5852         return "dec{l}\t%0";
5853       else
5854         abort();
5855
5856     default:
5857       if (! rtx_equal_p (operands[0], operands[1]))
5858         abort ();
5859       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5860          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5861       if ((INTVAL (operands[2]) == -128
5862            || (INTVAL (operands[2]) > 0
5863                && INTVAL (operands[2]) != 128)))
5864         return "sub{l}\t{%2, %0|%0, %2}";
5865       operands[2] = GEN_INT (-INTVAL (operands[2]));
5866       return "add{l}\t{%2, %0|%0, %2}";
5867     }
5868 }
5869   [(set (attr "type")
5870      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5871         (const_string "incdec")
5872         (const_string "alu")))
5873    (set_attr "mode" "SI")])
5874
5875 (define_insn "*addsi_5"
5876   [(set (reg FLAGS_REG)
5877         (compare
5878           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5879                    (match_operand:SI 2 "general_operand" "rmni"))
5880           (const_int 0)))                       
5881    (clobber (match_scratch:SI 0 "=r"))]
5882   "ix86_match_ccmode (insn, CCGOCmode)
5883    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5884    /* Current assemblers are broken and do not allow @GOTOFF in
5885       ought but a memory context.  */
5886    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5887 {
5888   switch (get_attr_type (insn))
5889     {
5890     case TYPE_INCDEC:
5891       if (! rtx_equal_p (operands[0], operands[1]))
5892         abort ();
5893       if (operands[2] == const1_rtx)
5894         return "inc{l}\t%0";
5895       else if (operands[2] == constm1_rtx)
5896         return "dec{l}\t%0";
5897       else
5898         abort();
5899
5900     default:
5901       if (! rtx_equal_p (operands[0], operands[1]))
5902         abort ();
5903       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5904          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5905       if (GET_CODE (operands[2]) == CONST_INT
5906           && (INTVAL (operands[2]) == 128
5907               || (INTVAL (operands[2]) < 0
5908                   && INTVAL (operands[2]) != -128)))
5909         {
5910           operands[2] = GEN_INT (-INTVAL (operands[2]));
5911           return "sub{l}\t{%2, %0|%0, %2}";
5912         }
5913       return "add{l}\t{%2, %0|%0, %2}";
5914     }
5915 }
5916   [(set (attr "type")
5917      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5918         (const_string "incdec")
5919         (const_string "alu")))
5920    (set_attr "mode" "SI")])
5921
5922 (define_expand "addhi3"
5923   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5924                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5925                             (match_operand:HI 2 "general_operand" "")))
5926               (clobber (reg:CC FLAGS_REG))])]
5927   "TARGET_HIMODE_MATH"
5928   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5929
5930 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5931 ;; type optimizations enabled by define-splits.  This is not important
5932 ;; for PII, and in fact harmful because of partial register stalls.
5933
5934 (define_insn "*addhi_1_lea"
5935   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5936         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5937                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5938    (clobber (reg:CC FLAGS_REG))]
5939   "!TARGET_PARTIAL_REG_STALL
5940    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5941 {
5942   switch (get_attr_type (insn))
5943     {
5944     case TYPE_LEA:
5945       return "#";
5946     case TYPE_INCDEC:
5947       if (operands[2] == const1_rtx)
5948         return "inc{w}\t%0";
5949       else if (operands[2] == constm1_rtx)
5950         return "dec{w}\t%0";
5951       abort();
5952
5953     default:
5954       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5956       if (GET_CODE (operands[2]) == CONST_INT
5957           && (INTVAL (operands[2]) == 128
5958               || (INTVAL (operands[2]) < 0
5959                   && INTVAL (operands[2]) != -128)))
5960         {
5961           operands[2] = GEN_INT (-INTVAL (operands[2]));
5962           return "sub{w}\t{%2, %0|%0, %2}";
5963         }
5964       return "add{w}\t{%2, %0|%0, %2}";
5965     }
5966 }
5967   [(set (attr "type")
5968      (if_then_else (eq_attr "alternative" "2")
5969         (const_string "lea")
5970         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5971            (const_string "incdec")
5972            (const_string "alu"))))
5973    (set_attr "mode" "HI,HI,SI")])
5974
5975 (define_insn "*addhi_1"
5976   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5977         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5978                  (match_operand:HI 2 "general_operand" "ri,rm")))
5979    (clobber (reg:CC FLAGS_REG))]
5980   "TARGET_PARTIAL_REG_STALL
5981    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5982 {
5983   switch (get_attr_type (insn))
5984     {
5985     case TYPE_INCDEC:
5986       if (operands[2] == const1_rtx)
5987         return "inc{w}\t%0";
5988       else if (operands[2] == constm1_rtx)
5989         return "dec{w}\t%0";
5990       abort();
5991
5992     default:
5993       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5994          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5995       if (GET_CODE (operands[2]) == CONST_INT
5996           && (INTVAL (operands[2]) == 128
5997               || (INTVAL (operands[2]) < 0
5998                   && INTVAL (operands[2]) != -128)))
5999         {
6000           operands[2] = GEN_INT (-INTVAL (operands[2]));
6001           return "sub{w}\t{%2, %0|%0, %2}";
6002         }
6003       return "add{w}\t{%2, %0|%0, %2}";
6004     }
6005 }
6006   [(set (attr "type")
6007      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6008         (const_string "incdec")
6009         (const_string "alu")))
6010    (set_attr "mode" "HI")])
6011
6012 (define_insn "*addhi_2"
6013   [(set (reg FLAGS_REG)
6014         (compare
6015           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6016                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6017           (const_int 0)))                       
6018    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6019         (plus:HI (match_dup 1) (match_dup 2)))]
6020   "ix86_match_ccmode (insn, CCGOCmode)
6021    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6022 {
6023   switch (get_attr_type (insn))
6024     {
6025     case TYPE_INCDEC:
6026       if (operands[2] == const1_rtx)
6027         return "inc{w}\t%0";
6028       else if (operands[2] == constm1_rtx)
6029         return "dec{w}\t%0";
6030       abort();
6031
6032     default:
6033       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6034          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6035       if (GET_CODE (operands[2]) == CONST_INT
6036           && (INTVAL (operands[2]) == 128
6037               || (INTVAL (operands[2]) < 0
6038                   && INTVAL (operands[2]) != -128)))
6039         {
6040           operands[2] = GEN_INT (-INTVAL (operands[2]));
6041           return "sub{w}\t{%2, %0|%0, %2}";
6042         }
6043       return "add{w}\t{%2, %0|%0, %2}";
6044     }
6045 }
6046   [(set (attr "type")
6047      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6048         (const_string "incdec")
6049         (const_string "alu")))
6050    (set_attr "mode" "HI")])
6051
6052 (define_insn "*addhi_3"
6053   [(set (reg FLAGS_REG)
6054         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6055                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6056    (clobber (match_scratch:HI 0 "=r"))]
6057   "ix86_match_ccmode (insn, CCZmode)
6058    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6059 {
6060   switch (get_attr_type (insn))
6061     {
6062     case TYPE_INCDEC:
6063       if (operands[2] == const1_rtx)
6064         return "inc{w}\t%0";
6065       else if (operands[2] == constm1_rtx)
6066         return "dec{w}\t%0";
6067       abort();
6068
6069     default:
6070       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6071          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6072       if (GET_CODE (operands[2]) == CONST_INT
6073           && (INTVAL (operands[2]) == 128
6074               || (INTVAL (operands[2]) < 0
6075                   && INTVAL (operands[2]) != -128)))
6076         {
6077           operands[2] = GEN_INT (-INTVAL (operands[2]));
6078           return "sub{w}\t{%2, %0|%0, %2}";
6079         }
6080       return "add{w}\t{%2, %0|%0, %2}";
6081     }
6082 }
6083   [(set (attr "type")
6084      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6085         (const_string "incdec")
6086         (const_string "alu")))
6087    (set_attr "mode" "HI")])
6088
6089 ; See comments above addsi_3_imm for details.
6090 (define_insn "*addhi_4"
6091   [(set (reg FLAGS_REG)
6092         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6093                  (match_operand:HI 2 "const_int_operand" "n")))
6094    (clobber (match_scratch:HI 0 "=rm"))]
6095   "ix86_match_ccmode (insn, CCGCmode)
6096    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6097 {
6098   switch (get_attr_type (insn))
6099     {
6100     case TYPE_INCDEC:
6101       if (operands[2] == constm1_rtx)
6102         return "inc{w}\t%0";
6103       else if (operands[2] == const1_rtx)
6104         return "dec{w}\t%0";
6105       else
6106         abort();
6107
6108     default:
6109       if (! rtx_equal_p (operands[0], operands[1]))
6110         abort ();
6111       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6112          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6113       if ((INTVAL (operands[2]) == -128
6114            || (INTVAL (operands[2]) > 0
6115                && INTVAL (operands[2]) != 128)))
6116         return "sub{w}\t{%2, %0|%0, %2}";
6117       operands[2] = GEN_INT (-INTVAL (operands[2]));
6118       return "add{w}\t{%2, %0|%0, %2}";
6119     }
6120 }
6121   [(set (attr "type")
6122      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6123         (const_string "incdec")
6124         (const_string "alu")))
6125    (set_attr "mode" "SI")])
6126
6127
6128 (define_insn "*addhi_5"
6129   [(set (reg FLAGS_REG)
6130         (compare
6131           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6132                    (match_operand:HI 2 "general_operand" "rmni"))
6133           (const_int 0)))                       
6134    (clobber (match_scratch:HI 0 "=r"))]
6135   "ix86_match_ccmode (insn, CCGOCmode)
6136    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6137 {
6138   switch (get_attr_type (insn))
6139     {
6140     case TYPE_INCDEC:
6141       if (operands[2] == const1_rtx)
6142         return "inc{w}\t%0";
6143       else if (operands[2] == constm1_rtx)
6144         return "dec{w}\t%0";
6145       abort();
6146
6147     default:
6148       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6149          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6150       if (GET_CODE (operands[2]) == CONST_INT
6151           && (INTVAL (operands[2]) == 128
6152               || (INTVAL (operands[2]) < 0
6153                   && INTVAL (operands[2]) != -128)))
6154         {
6155           operands[2] = GEN_INT (-INTVAL (operands[2]));
6156           return "sub{w}\t{%2, %0|%0, %2}";
6157         }
6158       return "add{w}\t{%2, %0|%0, %2}";
6159     }
6160 }
6161   [(set (attr "type")
6162      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6163         (const_string "incdec")
6164         (const_string "alu")))
6165    (set_attr "mode" "HI")])
6166
6167 (define_expand "addqi3"
6168   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6169                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6170                             (match_operand:QI 2 "general_operand" "")))
6171               (clobber (reg:CC FLAGS_REG))])]
6172   "TARGET_QIMODE_MATH"
6173   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6174
6175 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6176 (define_insn "*addqi_1_lea"
6177   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6178         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6179                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6180    (clobber (reg:CC FLAGS_REG))]
6181   "!TARGET_PARTIAL_REG_STALL
6182    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6183 {
6184   int widen = (which_alternative == 2);
6185   switch (get_attr_type (insn))
6186     {
6187     case TYPE_LEA:
6188       return "#";
6189     case TYPE_INCDEC:
6190       if (operands[2] == const1_rtx)
6191         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6192       else if (operands[2] == constm1_rtx)
6193         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6194       abort();
6195
6196     default:
6197       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6198          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6199       if (GET_CODE (operands[2]) == CONST_INT
6200           && (INTVAL (operands[2]) == 128
6201               || (INTVAL (operands[2]) < 0
6202                   && INTVAL (operands[2]) != -128)))
6203         {
6204           operands[2] = GEN_INT (-INTVAL (operands[2]));
6205           if (widen)
6206             return "sub{l}\t{%2, %k0|%k0, %2}";
6207           else
6208             return "sub{b}\t{%2, %0|%0, %2}";
6209         }
6210       if (widen)
6211         return "add{l}\t{%k2, %k0|%k0, %k2}";
6212       else
6213         return "add{b}\t{%2, %0|%0, %2}";
6214     }
6215 }
6216   [(set (attr "type")
6217      (if_then_else (eq_attr "alternative" "3")
6218         (const_string "lea")
6219         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6220            (const_string "incdec")
6221            (const_string "alu"))))
6222    (set_attr "mode" "QI,QI,SI,SI")])
6223
6224 (define_insn "*addqi_1"
6225   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6226         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6227                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6228    (clobber (reg:CC FLAGS_REG))]
6229   "TARGET_PARTIAL_REG_STALL
6230    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6231 {
6232   int widen = (which_alternative == 2);
6233   switch (get_attr_type (insn))
6234     {
6235     case TYPE_INCDEC:
6236       if (operands[2] == const1_rtx)
6237         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6238       else if (operands[2] == constm1_rtx)
6239         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6240       abort();
6241
6242     default:
6243       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6244          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6245       if (GET_CODE (operands[2]) == CONST_INT
6246           && (INTVAL (operands[2]) == 128
6247               || (INTVAL (operands[2]) < 0
6248                   && INTVAL (operands[2]) != -128)))
6249         {
6250           operands[2] = GEN_INT (-INTVAL (operands[2]));
6251           if (widen)
6252             return "sub{l}\t{%2, %k0|%k0, %2}";
6253           else
6254             return "sub{b}\t{%2, %0|%0, %2}";
6255         }
6256       if (widen)
6257         return "add{l}\t{%k2, %k0|%k0, %k2}";
6258       else
6259         return "add{b}\t{%2, %0|%0, %2}";
6260     }
6261 }
6262   [(set (attr "type")
6263      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6264         (const_string "incdec")
6265         (const_string "alu")))
6266    (set_attr "mode" "QI,QI,SI")])
6267
6268 (define_insn "*addqi_1_slp"
6269   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6270         (plus:QI (match_dup 0)
6271                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6272    (clobber (reg:CC FLAGS_REG))]
6273   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6274    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6275 {
6276   switch (get_attr_type (insn))
6277     {
6278     case TYPE_INCDEC:
6279       if (operands[1] == const1_rtx)
6280         return "inc{b}\t%0";
6281       else if (operands[1] == constm1_rtx)
6282         return "dec{b}\t%0";
6283       abort();
6284
6285     default:
6286       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6287       if (GET_CODE (operands[1]) == CONST_INT
6288           && INTVAL (operands[1]) < 0)
6289         {
6290           operands[1] = GEN_INT (-INTVAL (operands[1]));
6291           return "sub{b}\t{%1, %0|%0, %1}";
6292         }
6293       return "add{b}\t{%1, %0|%0, %1}";
6294     }
6295 }
6296   [(set (attr "type")
6297      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6298         (const_string "incdec")
6299         (const_string "alu1")))
6300    (set (attr "memory")
6301      (if_then_else (match_operand 1 "memory_operand" "")
6302         (const_string "load")
6303         (const_string "none")))
6304    (set_attr "mode" "QI")])
6305
6306 (define_insn "*addqi_2"
6307   [(set (reg FLAGS_REG)
6308         (compare
6309           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6310                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6311           (const_int 0)))
6312    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6313         (plus:QI (match_dup 1) (match_dup 2)))]
6314   "ix86_match_ccmode (insn, CCGOCmode)
6315    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6316 {
6317   switch (get_attr_type (insn))
6318     {
6319     case TYPE_INCDEC:
6320       if (operands[2] == const1_rtx)
6321         return "inc{b}\t%0";
6322       else if (operands[2] == constm1_rtx
6323                || (GET_CODE (operands[2]) == CONST_INT
6324                    && INTVAL (operands[2]) == 255))
6325         return "dec{b}\t%0";
6326       abort();
6327
6328     default:
6329       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6330       if (GET_CODE (operands[2]) == CONST_INT
6331           && INTVAL (operands[2]) < 0)
6332         {
6333           operands[2] = GEN_INT (-INTVAL (operands[2]));
6334           return "sub{b}\t{%2, %0|%0, %2}";
6335         }
6336       return "add{b}\t{%2, %0|%0, %2}";
6337     }
6338 }
6339   [(set (attr "type")
6340      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6341         (const_string "incdec")
6342         (const_string "alu")))
6343    (set_attr "mode" "QI")])
6344
6345 (define_insn "*addqi_3"
6346   [(set (reg FLAGS_REG)
6347         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6348                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6349    (clobber (match_scratch:QI 0 "=q"))]
6350   "ix86_match_ccmode (insn, CCZmode)
6351    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6352 {
6353   switch (get_attr_type (insn))
6354     {
6355     case TYPE_INCDEC:
6356       if (operands[2] == const1_rtx)
6357         return "inc{b}\t%0";
6358       else if (operands[2] == constm1_rtx
6359                || (GET_CODE (operands[2]) == CONST_INT
6360                    && INTVAL (operands[2]) == 255))
6361         return "dec{b}\t%0";
6362       abort();
6363
6364     default:
6365       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6366       if (GET_CODE (operands[2]) == CONST_INT
6367           && INTVAL (operands[2]) < 0)
6368         {
6369           operands[2] = GEN_INT (-INTVAL (operands[2]));
6370           return "sub{b}\t{%2, %0|%0, %2}";
6371         }
6372       return "add{b}\t{%2, %0|%0, %2}";
6373     }
6374 }
6375   [(set (attr "type")
6376      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6377         (const_string "incdec")
6378         (const_string "alu")))
6379    (set_attr "mode" "QI")])
6380
6381 ; See comments above addsi_3_imm for details.
6382 (define_insn "*addqi_4"
6383   [(set (reg FLAGS_REG)
6384         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6385                  (match_operand:QI 2 "const_int_operand" "n")))
6386    (clobber (match_scratch:QI 0 "=qm"))]
6387   "ix86_match_ccmode (insn, CCGCmode)
6388    && (INTVAL (operands[2]) & 0xff) != 0x80"
6389 {
6390   switch (get_attr_type (insn))
6391     {
6392     case TYPE_INCDEC:
6393       if (operands[2] == constm1_rtx
6394           || (GET_CODE (operands[2]) == CONST_INT
6395               && INTVAL (operands[2]) == 255))
6396         return "inc{b}\t%0";
6397       else if (operands[2] == const1_rtx)
6398         return "dec{b}\t%0";
6399       else
6400         abort();
6401
6402     default:
6403       if (! rtx_equal_p (operands[0], operands[1]))
6404         abort ();
6405       if (INTVAL (operands[2]) < 0)
6406         {
6407           operands[2] = GEN_INT (-INTVAL (operands[2]));
6408           return "add{b}\t{%2, %0|%0, %2}";
6409         }
6410       return "sub{b}\t{%2, %0|%0, %2}";
6411     }
6412 }
6413   [(set (attr "type")
6414      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6415         (const_string "incdec")
6416         (const_string "alu")))
6417    (set_attr "mode" "QI")])
6418
6419
6420 (define_insn "*addqi_5"
6421   [(set (reg FLAGS_REG)
6422         (compare
6423           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6424                    (match_operand:QI 2 "general_operand" "qmni"))
6425           (const_int 0)))
6426    (clobber (match_scratch:QI 0 "=q"))]
6427   "ix86_match_ccmode (insn, CCGOCmode)
6428    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6429 {
6430   switch (get_attr_type (insn))
6431     {
6432     case TYPE_INCDEC:
6433       if (operands[2] == const1_rtx)
6434         return "inc{b}\t%0";
6435       else if (operands[2] == constm1_rtx
6436                || (GET_CODE (operands[2]) == CONST_INT
6437                    && INTVAL (operands[2]) == 255))
6438         return "dec{b}\t%0";
6439       abort();
6440
6441     default:
6442       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6443       if (GET_CODE (operands[2]) == CONST_INT
6444           && INTVAL (operands[2]) < 0)
6445         {
6446           operands[2] = GEN_INT (-INTVAL (operands[2]));
6447           return "sub{b}\t{%2, %0|%0, %2}";
6448         }
6449       return "add{b}\t{%2, %0|%0, %2}";
6450     }
6451 }
6452   [(set (attr "type")
6453      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6454         (const_string "incdec")
6455         (const_string "alu")))
6456    (set_attr "mode" "QI")])
6457
6458
6459 (define_insn "addqi_ext_1"
6460   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6461                          (const_int 8)
6462                          (const_int 8))
6463         (plus:SI
6464           (zero_extract:SI
6465             (match_operand 1 "ext_register_operand" "0")
6466             (const_int 8)
6467             (const_int 8))
6468           (match_operand:QI 2 "general_operand" "Qmn")))
6469    (clobber (reg:CC FLAGS_REG))]
6470   "!TARGET_64BIT"
6471 {
6472   switch (get_attr_type (insn))
6473     {
6474     case TYPE_INCDEC:
6475       if (operands[2] == const1_rtx)
6476         return "inc{b}\t%h0";
6477       else if (operands[2] == constm1_rtx
6478                || (GET_CODE (operands[2]) == CONST_INT
6479                    && INTVAL (operands[2]) == 255))
6480         return "dec{b}\t%h0";
6481       abort();
6482
6483     default:
6484       return "add{b}\t{%2, %h0|%h0, %2}";
6485     }
6486 }
6487   [(set (attr "type")
6488      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6489         (const_string "incdec")
6490         (const_string "alu")))
6491    (set_attr "mode" "QI")])
6492
6493 (define_insn "*addqi_ext_1_rex64"
6494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6495                          (const_int 8)
6496                          (const_int 8))
6497         (plus:SI
6498           (zero_extract:SI
6499             (match_operand 1 "ext_register_operand" "0")
6500             (const_int 8)
6501             (const_int 8))
6502           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6503    (clobber (reg:CC FLAGS_REG))]
6504   "TARGET_64BIT"
6505 {
6506   switch (get_attr_type (insn))
6507     {
6508     case TYPE_INCDEC:
6509       if (operands[2] == const1_rtx)
6510         return "inc{b}\t%h0";
6511       else if (operands[2] == constm1_rtx
6512                || (GET_CODE (operands[2]) == CONST_INT
6513                    && INTVAL (operands[2]) == 255))
6514         return "dec{b}\t%h0";
6515       abort();
6516
6517     default:
6518       return "add{b}\t{%2, %h0|%h0, %2}";
6519     }
6520 }
6521   [(set (attr "type")
6522      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6523         (const_string "incdec")
6524         (const_string "alu")))
6525    (set_attr "mode" "QI")])
6526
6527 (define_insn "*addqi_ext_2"
6528   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6529                          (const_int 8)
6530                          (const_int 8))
6531         (plus:SI
6532           (zero_extract:SI
6533             (match_operand 1 "ext_register_operand" "%0")
6534             (const_int 8)
6535             (const_int 8))
6536           (zero_extract:SI
6537             (match_operand 2 "ext_register_operand" "Q")
6538             (const_int 8)
6539             (const_int 8))))
6540    (clobber (reg:CC FLAGS_REG))]
6541   ""
6542   "add{b}\t{%h2, %h0|%h0, %h2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "mode" "QI")])
6545
6546 ;; The patterns that match these are at the end of this file.
6547
6548 (define_expand "addxf3"
6549   [(set (match_operand:XF 0 "register_operand" "")
6550         (plus:XF (match_operand:XF 1 "register_operand" "")
6551                  (match_operand:XF 2 "register_operand" "")))]
6552   "TARGET_80387"
6553   "")
6554
6555 (define_expand "adddf3"
6556   [(set (match_operand:DF 0 "register_operand" "")
6557         (plus:DF (match_operand:DF 1 "register_operand" "")
6558                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6559   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6560   "")
6561
6562 (define_expand "addsf3"
6563   [(set (match_operand:SF 0 "register_operand" "")
6564         (plus:SF (match_operand:SF 1 "register_operand" "")
6565                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6566   "TARGET_80387 || TARGET_SSE_MATH"
6567   "")
6568 \f
6569 ;; Subtract instructions
6570
6571 ;; %%% splits for subsidi3
6572
6573 (define_expand "subdi3"
6574   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6575                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6576                              (match_operand:DI 2 "x86_64_general_operand" "")))
6577               (clobber (reg:CC FLAGS_REG))])]
6578   ""
6579   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6580
6581 (define_insn "*subdi3_1"
6582   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6583         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6584                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6587   "#")
6588
6589 (define_split
6590   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6591         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6592                   (match_operand:DI 2 "general_operand" "")))
6593    (clobber (reg:CC FLAGS_REG))]
6594   "!TARGET_64BIT && reload_completed"
6595   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6596               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6597    (parallel [(set (match_dup 3)
6598                    (minus:SI (match_dup 4)
6599                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6600                                       (match_dup 5))))
6601               (clobber (reg:CC FLAGS_REG))])]
6602   "split_di (operands+0, 1, operands+0, operands+3);
6603    split_di (operands+1, 1, operands+1, operands+4);
6604    split_di (operands+2, 1, operands+2, operands+5);")
6605
6606 (define_insn "subdi3_carry_rex64"
6607   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6608           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6610                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6613   "sbb{q}\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "pent_pair" "pu")
6616    (set_attr "mode" "DI")])
6617
6618 (define_insn "*subdi_1_rex64"
6619   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6620         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6621                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6622    (clobber (reg:CC FLAGS_REG))]
6623   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6624   "sub{q}\t{%2, %0|%0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "mode" "DI")])
6627
6628 (define_insn "*subdi_2_rex64"
6629   [(set (reg FLAGS_REG)
6630         (compare
6631           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6632                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6633           (const_int 0)))
6634    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6635         (minus:DI (match_dup 1) (match_dup 2)))]
6636   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6637    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6638   "sub{q}\t{%2, %0|%0, %2}"
6639   [(set_attr "type" "alu")
6640    (set_attr "mode" "DI")])
6641
6642 (define_insn "*subdi_3_rex63"
6643   [(set (reg FLAGS_REG)
6644         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6645                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6646    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6647         (minus:DI (match_dup 1) (match_dup 2)))]
6648   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6649    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650   "sub{q}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "DI")])
6653
6654 (define_insn "subqi3_carry"
6655   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6656           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6657             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6658                (match_operand:QI 2 "general_operand" "qi,qm"))))
6659    (clobber (reg:CC FLAGS_REG))]
6660   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6661   "sbb{b}\t{%2, %0|%0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "pent_pair" "pu")
6664    (set_attr "mode" "QI")])
6665
6666 (define_insn "subhi3_carry"
6667   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6668           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6669             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6670                (match_operand:HI 2 "general_operand" "ri,rm"))))
6671    (clobber (reg:CC FLAGS_REG))]
6672   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6673   "sbb{w}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "pent_pair" "pu")
6676    (set_attr "mode" "HI")])
6677
6678 (define_insn "subsi3_carry"
6679   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6680           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6681             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6682                (match_operand:SI 2 "general_operand" "ri,rm"))))
6683    (clobber (reg:CC FLAGS_REG))]
6684   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6685   "sbb{l}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "pent_pair" "pu")
6688    (set_attr "mode" "SI")])
6689
6690 (define_insn "subsi3_carry_zext"
6691   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6692           (zero_extend:DI
6693             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6694               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6695                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6696    (clobber (reg:CC FLAGS_REG))]
6697   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6698   "sbb{l}\t{%2, %k0|%k0, %2}"
6699   [(set_attr "type" "alu")
6700    (set_attr "pent_pair" "pu")
6701    (set_attr "mode" "SI")])
6702
6703 (define_expand "subsi3"
6704   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6705                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6706                              (match_operand:SI 2 "general_operand" "")))
6707               (clobber (reg:CC FLAGS_REG))])]
6708   ""
6709   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6710
6711 (define_insn "*subsi_1"
6712   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6714                   (match_operand:SI 2 "general_operand" "ri,rm")))
6715    (clobber (reg:CC FLAGS_REG))]
6716   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6717   "sub{l}\t{%2, %0|%0, %2}"
6718   [(set_attr "type" "alu")
6719    (set_attr "mode" "SI")])
6720
6721 (define_insn "*subsi_1_zext"
6722   [(set (match_operand:DI 0 "register_operand" "=r")
6723         (zero_extend:DI
6724           (minus:SI (match_operand:SI 1 "register_operand" "0")
6725                     (match_operand:SI 2 "general_operand" "rim"))))
6726    (clobber (reg:CC FLAGS_REG))]
6727   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6728   "sub{l}\t{%2, %k0|%k0, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "SI")])
6731
6732 (define_insn "*subsi_2"
6733   [(set (reg FLAGS_REG)
6734         (compare
6735           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6736                     (match_operand:SI 2 "general_operand" "ri,rm"))
6737           (const_int 0)))
6738    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6739         (minus:SI (match_dup 1) (match_dup 2)))]
6740   "ix86_match_ccmode (insn, CCGOCmode)
6741    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6742   "sub{l}\t{%2, %0|%0, %2}"
6743   [(set_attr "type" "alu")
6744    (set_attr "mode" "SI")])
6745
6746 (define_insn "*subsi_2_zext"
6747   [(set (reg FLAGS_REG)
6748         (compare
6749           (minus:SI (match_operand:SI 1 "register_operand" "0")
6750                     (match_operand:SI 2 "general_operand" "rim"))
6751           (const_int 0)))
6752    (set (match_operand:DI 0 "register_operand" "=r")
6753         (zero_extend:DI
6754           (minus:SI (match_dup 1)
6755                     (match_dup 2))))]
6756   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6757    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6758   "sub{l}\t{%2, %k0|%k0, %2}"
6759   [(set_attr "type" "alu")
6760    (set_attr "mode" "SI")])
6761
6762 (define_insn "*subsi_3"
6763   [(set (reg FLAGS_REG)
6764         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6765                  (match_operand:SI 2 "general_operand" "ri,rm")))
6766    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6767         (minus:SI (match_dup 1) (match_dup 2)))]
6768   "ix86_match_ccmode (insn, CCmode)
6769    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6770   "sub{l}\t{%2, %0|%0, %2}"
6771   [(set_attr "type" "alu")
6772    (set_attr "mode" "SI")])
6773
6774 (define_insn "*subsi_3_zext"
6775   [(set (reg FLAGS_REG)
6776         (compare (match_operand:SI 1 "register_operand" "0")
6777                  (match_operand:SI 2 "general_operand" "rim")))
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, CCmode)
6783    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784   "sub{q}\t{%2, %0|%0, %2}"
6785   [(set_attr "type" "alu")
6786    (set_attr "mode" "DI")])
6787
6788 (define_expand "subhi3"
6789   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6790                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6791                              (match_operand:HI 2 "general_operand" "")))
6792               (clobber (reg:CC FLAGS_REG))])]
6793   "TARGET_HIMODE_MATH"
6794   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6795
6796 (define_insn "*subhi_1"
6797   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6798         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6799                   (match_operand:HI 2 "general_operand" "ri,rm")))
6800    (clobber (reg:CC FLAGS_REG))]
6801   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6802   "sub{w}\t{%2, %0|%0, %2}"
6803   [(set_attr "type" "alu")
6804    (set_attr "mode" "HI")])
6805
6806 (define_insn "*subhi_2"
6807   [(set (reg FLAGS_REG)
6808         (compare
6809           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6810                     (match_operand:HI 2 "general_operand" "ri,rm"))
6811           (const_int 0)))
6812    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6813         (minus:HI (match_dup 1) (match_dup 2)))]
6814   "ix86_match_ccmode (insn, CCGOCmode)
6815    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6816   "sub{w}\t{%2, %0|%0, %2}"
6817   [(set_attr "type" "alu")
6818    (set_attr "mode" "HI")])
6819
6820 (define_insn "*subhi_3"
6821   [(set (reg FLAGS_REG)
6822         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6823                  (match_operand:HI 2 "general_operand" "ri,rm")))
6824    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6825         (minus:HI (match_dup 1) (match_dup 2)))]
6826   "ix86_match_ccmode (insn, CCmode)
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_expand "subqi3"
6833   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6834                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6835                              (match_operand:QI 2 "general_operand" "")))
6836               (clobber (reg:CC FLAGS_REG))])]
6837   "TARGET_QIMODE_MATH"
6838   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6839
6840 (define_insn "*subqi_1"
6841   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6842         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6843                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6844    (clobber (reg:CC FLAGS_REG))]
6845   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6846   "sub{b}\t{%2, %0|%0, %2}"
6847   [(set_attr "type" "alu")
6848    (set_attr "mode" "QI")])
6849
6850 (define_insn "*subqi_1_slp"
6851   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6852         (minus:QI (match_dup 0)
6853                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6854    (clobber (reg:CC FLAGS_REG))]
6855   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6856    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6857   "sub{b}\t{%1, %0|%0, %1}"
6858   [(set_attr "type" "alu1")
6859    (set_attr "mode" "QI")])
6860
6861 (define_insn "*subqi_2"
6862   [(set (reg FLAGS_REG)
6863         (compare
6864           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6865                     (match_operand:QI 2 "general_operand" "qi,qm"))
6866           (const_int 0)))
6867    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6868         (minus:HI (match_dup 1) (match_dup 2)))]
6869   "ix86_match_ccmode (insn, CCGOCmode)
6870    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6871   "sub{b}\t{%2, %0|%0, %2}"
6872   [(set_attr "type" "alu")
6873    (set_attr "mode" "QI")])
6874
6875 (define_insn "*subqi_3"
6876   [(set (reg FLAGS_REG)
6877         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878                  (match_operand:QI 2 "general_operand" "qi,qm")))
6879    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6880         (minus:HI (match_dup 1) (match_dup 2)))]
6881   "ix86_match_ccmode (insn, CCmode)
6882    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6883   "sub{b}\t{%2, %0|%0, %2}"
6884   [(set_attr "type" "alu")
6885    (set_attr "mode" "QI")])
6886
6887 ;; The patterns that match these are at the end of this file.
6888
6889 (define_expand "subxf3"
6890   [(set (match_operand:XF 0 "register_operand" "")
6891         (minus:XF (match_operand:XF 1 "register_operand" "")
6892                   (match_operand:XF 2 "register_operand" "")))]
6893   "TARGET_80387"
6894   "")
6895
6896 (define_expand "subdf3"
6897   [(set (match_operand:DF 0 "register_operand" "")
6898         (minus:DF (match_operand:DF 1 "register_operand" "")
6899                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6900   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6901   "")
6902
6903 (define_expand "subsf3"
6904   [(set (match_operand:SF 0 "register_operand" "")
6905         (minus:SF (match_operand:SF 1 "register_operand" "")
6906                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6907   "TARGET_80387 || TARGET_SSE_MATH"
6908   "")
6909 \f
6910 ;; Multiply instructions
6911
6912 (define_expand "muldi3"
6913   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6914                    (mult:DI (match_operand:DI 1 "register_operand" "")
6915                             (match_operand:DI 2 "x86_64_general_operand" "")))
6916               (clobber (reg:CC FLAGS_REG))])]
6917   "TARGET_64BIT"
6918   "")
6919
6920 (define_insn "*muldi3_1_rex64"
6921   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6922         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6923                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "TARGET_64BIT
6926    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6927   "@
6928    imul{q}\t{%2, %1, %0|%0, %1, %2}
6929    imul{q}\t{%2, %1, %0|%0, %1, %2}
6930    imul{q}\t{%2, %0|%0, %2}"
6931   [(set_attr "type" "imul")
6932    (set_attr "prefix_0f" "0,0,1")
6933    (set (attr "athlon_decode")
6934         (cond [(eq_attr "cpu" "athlon")
6935                   (const_string "vector")
6936                (eq_attr "alternative" "1")
6937                   (const_string "vector")
6938                (and (eq_attr "alternative" "2")
6939                     (match_operand 1 "memory_operand" ""))
6940                   (const_string "vector")]
6941               (const_string "direct")))
6942    (set_attr "mode" "DI")])
6943
6944 (define_expand "mulsi3"
6945   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6946                    (mult:SI (match_operand:SI 1 "register_operand" "")
6947                             (match_operand:SI 2 "general_operand" "")))
6948               (clobber (reg:CC FLAGS_REG))])]
6949   ""
6950   "")
6951
6952 (define_insn "*mulsi3_1"
6953   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6954         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6955                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6956    (clobber (reg:CC FLAGS_REG))]
6957   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6958   "@
6959    imul{l}\t{%2, %1, %0|%0, %1, %2}
6960    imul{l}\t{%2, %1, %0|%0, %1, %2}
6961    imul{l}\t{%2, %0|%0, %2}"
6962   [(set_attr "type" "imul")
6963    (set_attr "prefix_0f" "0,0,1")
6964    (set (attr "athlon_decode")
6965         (cond [(eq_attr "cpu" "athlon")
6966                   (const_string "vector")
6967                (eq_attr "alternative" "1")
6968                   (const_string "vector")
6969                (and (eq_attr "alternative" "2")
6970                     (match_operand 1 "memory_operand" ""))
6971                   (const_string "vector")]
6972               (const_string "direct")))
6973    (set_attr "mode" "SI")])
6974
6975 (define_insn "*mulsi3_1_zext"
6976   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6977         (zero_extend:DI
6978           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6979                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6980    (clobber (reg:CC FLAGS_REG))]
6981   "TARGET_64BIT
6982    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6983   "@
6984    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6985    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6986    imul{l}\t{%2, %k0|%k0, %2}"
6987   [(set_attr "type" "imul")
6988    (set_attr "prefix_0f" "0,0,1")
6989    (set (attr "athlon_decode")
6990         (cond [(eq_attr "cpu" "athlon")
6991                   (const_string "vector")
6992                (eq_attr "alternative" "1")
6993                   (const_string "vector")
6994                (and (eq_attr "alternative" "2")
6995                     (match_operand 1 "memory_operand" ""))
6996                   (const_string "vector")]
6997               (const_string "direct")))
6998    (set_attr "mode" "SI")])
6999
7000 (define_expand "mulhi3"
7001   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7002                    (mult:HI (match_operand:HI 1 "register_operand" "")
7003                             (match_operand:HI 2 "general_operand" "")))
7004               (clobber (reg:CC FLAGS_REG))])]
7005   "TARGET_HIMODE_MATH"
7006   "")
7007
7008 (define_insn "*mulhi3_1"
7009   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7010         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7011                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7012    (clobber (reg:CC FLAGS_REG))]
7013   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7014   "@
7015    imul{w}\t{%2, %1, %0|%0, %1, %2}
7016    imul{w}\t{%2, %1, %0|%0, %1, %2}
7017    imul{w}\t{%2, %0|%0, %2}"
7018   [(set_attr "type" "imul")
7019    (set_attr "prefix_0f" "0,0,1")
7020    (set (attr "athlon_decode")
7021         (cond [(eq_attr "cpu" "athlon")
7022                   (const_string "vector")
7023                (eq_attr "alternative" "1,2")
7024                   (const_string "vector")]
7025               (const_string "direct")))
7026    (set_attr "mode" "HI")])
7027
7028 (define_expand "mulqi3"
7029   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7030                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7031                             (match_operand:QI 2 "register_operand" "")))
7032               (clobber (reg:CC FLAGS_REG))])]
7033   "TARGET_QIMODE_MATH"
7034   "")
7035
7036 (define_insn "*mulqi3_1"
7037   [(set (match_operand:QI 0 "register_operand" "=a")
7038         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7039                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7040    (clobber (reg:CC FLAGS_REG))]
7041   "TARGET_QIMODE_MATH
7042    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7043   "mul{b}\t%2"
7044   [(set_attr "type" "imul")
7045    (set_attr "length_immediate" "0")
7046    (set (attr "athlon_decode")
7047      (if_then_else (eq_attr "cpu" "athlon")
7048         (const_string "vector")
7049         (const_string "direct")))
7050    (set_attr "mode" "QI")])
7051
7052 (define_expand "umulqihi3"
7053   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7054                    (mult:HI (zero_extend:HI
7055                               (match_operand:QI 1 "nonimmediate_operand" ""))
7056                             (zero_extend:HI
7057                               (match_operand:QI 2 "register_operand" ""))))
7058               (clobber (reg:CC FLAGS_REG))])]
7059   "TARGET_QIMODE_MATH"
7060   "")
7061
7062 (define_insn "*umulqihi3_1"
7063   [(set (match_operand:HI 0 "register_operand" "=a")
7064         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7065                  (zero_extend:HI (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 "mulqihi3"
7079   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7080                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7081                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   "TARGET_QIMODE_MATH"
7084   "")
7085
7086 (define_insn "*mulqihi3_insn"
7087   [(set (match_operand:HI 0 "register_operand" "=a")
7088         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "TARGET_QIMODE_MATH
7092    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093   "imul{b}\t%2"
7094   [(set_attr "type" "imul")
7095    (set_attr "length_immediate" "0")
7096    (set (attr "athlon_decode")
7097      (if_then_else (eq_attr "cpu" "athlon")
7098         (const_string "vector")
7099         (const_string "direct")))
7100    (set_attr "mode" "QI")])
7101
7102 (define_expand "umulditi3"
7103   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7104                    (mult:TI (zero_extend:TI
7105                               (match_operand:DI 1 "nonimmediate_operand" ""))
7106                             (zero_extend:TI
7107                               (match_operand:DI 2 "register_operand" ""))))
7108               (clobber (reg:CC FLAGS_REG))])]
7109   "TARGET_64BIT"
7110   "")
7111
7112 (define_insn "*umulditi3_insn"
7113   [(set (match_operand:TI 0 "register_operand" "=A")
7114         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7115                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7116    (clobber (reg:CC FLAGS_REG))]
7117   "TARGET_64BIT
7118    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7119   "mul{q}\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 "double")))
7126    (set_attr "mode" "DI")])
7127
7128 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7129 (define_expand "umulsidi3"
7130   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7131                    (mult:DI (zero_extend:DI
7132                               (match_operand:SI 1 "nonimmediate_operand" ""))
7133                             (zero_extend:DI
7134                               (match_operand:SI 2 "register_operand" ""))))
7135               (clobber (reg:CC FLAGS_REG))])]
7136   "!TARGET_64BIT"
7137   "")
7138
7139 (define_insn "*umulsidi3_insn"
7140   [(set (match_operand:DI 0 "register_operand" "=A")
7141         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7142                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7143    (clobber (reg:CC FLAGS_REG))]
7144   "!TARGET_64BIT
7145    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7146   "mul{l}\t%2"
7147   [(set_attr "type" "imul")
7148    (set_attr "length_immediate" "0")
7149    (set (attr "athlon_decode")
7150      (if_then_else (eq_attr "cpu" "athlon")
7151         (const_string "vector")
7152         (const_string "double")))
7153    (set_attr "mode" "SI")])
7154
7155 (define_expand "mulditi3"
7156   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7157                    (mult:TI (sign_extend:TI
7158                               (match_operand:DI 1 "nonimmediate_operand" ""))
7159                             (sign_extend:TI
7160                               (match_operand:DI 2 "register_operand" ""))))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   "TARGET_64BIT"
7163   "")
7164
7165 (define_insn "*mulditi3_insn"
7166   [(set (match_operand:TI 0 "register_operand" "=A")
7167         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7168                  (sign_extend:TI (match_operand:DI 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   "imul{q}\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" "DI")])
7180
7181 (define_expand "mulsidi3"
7182   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7183                    (mult:DI (sign_extend:DI
7184                               (match_operand:SI 1 "nonimmediate_operand" ""))
7185                             (sign_extend:DI
7186                               (match_operand:SI 2 "register_operand" ""))))
7187               (clobber (reg:CC FLAGS_REG))])]
7188   "!TARGET_64BIT"
7189   "")
7190
7191 (define_insn "*mulsidi3_insn"
7192   [(set (match_operand:DI 0 "register_operand" "=A")
7193         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7194                  (sign_extend:DI (match_operand:SI 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{l}\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" "SI")])
7206
7207 (define_expand "umuldi3_highpart"
7208   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7209                    (truncate:DI
7210                      (lshiftrt:TI
7211                        (mult:TI (zero_extend:TI
7212                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7213                                 (zero_extend:TI
7214                                   (match_operand:DI 2 "register_operand" "")))
7215                        (const_int 64))))
7216               (clobber (match_scratch:DI 3 ""))
7217               (clobber (reg:CC FLAGS_REG))])]
7218   "TARGET_64BIT"
7219   "")
7220
7221 (define_insn "*umuldi3_highpart_rex64"
7222   [(set (match_operand:DI 0 "register_operand" "=d")
7223         (truncate:DI
7224           (lshiftrt:TI
7225             (mult:TI (zero_extend:TI
7226                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7227                      (zero_extend:TI
7228                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7229             (const_int 64))))
7230    (clobber (match_scratch:DI 3 "=1"))
7231    (clobber (reg:CC FLAGS_REG))]
7232   "TARGET_64BIT
7233    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234   "mul{q}\t%2"
7235   [(set_attr "type" "imul")
7236    (set_attr "length_immediate" "0")
7237    (set (attr "athlon_decode")
7238      (if_then_else (eq_attr "cpu" "athlon")
7239         (const_string "vector")
7240         (const_string "double")))
7241    (set_attr "mode" "DI")])
7242
7243 (define_expand "umulsi3_highpart"
7244   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7245                    (truncate:SI
7246                      (lshiftrt:DI
7247                        (mult:DI (zero_extend:DI
7248                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7249                                 (zero_extend:DI
7250                                   (match_operand:SI 2 "register_operand" "")))
7251                        (const_int 32))))
7252               (clobber (match_scratch:SI 3 ""))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   ""
7255   "")
7256
7257 (define_insn "*umulsi3_highpart_insn"
7258   [(set (match_operand:SI 0 "register_operand" "=d")
7259         (truncate:SI
7260           (lshiftrt:DI
7261             (mult:DI (zero_extend:DI
7262                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7263                      (zero_extend:DI
7264                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7265             (const_int 32))))
7266    (clobber (match_scratch:SI 3 "=1"))
7267    (clobber (reg:CC FLAGS_REG))]
7268   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7269   "mul{l}\t%2"
7270   [(set_attr "type" "imul")
7271    (set_attr "length_immediate" "0")
7272    (set (attr "athlon_decode")
7273      (if_then_else (eq_attr "cpu" "athlon")
7274         (const_string "vector")
7275         (const_string "double")))
7276    (set_attr "mode" "SI")])
7277
7278 (define_insn "*umulsi3_highpart_zext"
7279   [(set (match_operand:DI 0 "register_operand" "=d")
7280         (zero_extend:DI (truncate:SI
7281           (lshiftrt:DI
7282             (mult:DI (zero_extend:DI
7283                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7284                      (zero_extend:DI
7285                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7286             (const_int 32)))))
7287    (clobber (match_scratch:SI 3 "=1"))
7288    (clobber (reg:CC FLAGS_REG))]
7289   "TARGET_64BIT
7290    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7291   "mul{l}\t%2"
7292   [(set_attr "type" "imul")
7293    (set_attr "length_immediate" "0")
7294    (set (attr "athlon_decode")
7295      (if_then_else (eq_attr "cpu" "athlon")
7296         (const_string "vector")
7297         (const_string "double")))
7298    (set_attr "mode" "SI")])
7299
7300 (define_expand "smuldi3_highpart"
7301   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7302                    (truncate:DI
7303                      (lshiftrt:TI
7304                        (mult:TI (sign_extend:TI
7305                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7306                                 (sign_extend:TI
7307                                   (match_operand:DI 2 "register_operand" "")))
7308                        (const_int 64))))
7309               (clobber (match_scratch:DI 3 ""))
7310               (clobber (reg:CC FLAGS_REG))])]
7311   "TARGET_64BIT"
7312   "")
7313
7314 (define_insn "*smuldi3_highpart_rex64"
7315   [(set (match_operand:DI 0 "register_operand" "=d")
7316         (truncate:DI
7317           (lshiftrt:TI
7318             (mult:TI (sign_extend:TI
7319                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7320                      (sign_extend:TI
7321                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7322             (const_int 64))))
7323    (clobber (match_scratch:DI 3 "=1"))
7324    (clobber (reg:CC FLAGS_REG))]
7325   "TARGET_64BIT
7326    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7327   "imul{q}\t%2"
7328   [(set_attr "type" "imul")
7329    (set (attr "athlon_decode")
7330      (if_then_else (eq_attr "cpu" "athlon")
7331         (const_string "vector")
7332         (const_string "double")))
7333    (set_attr "mode" "DI")])
7334
7335 (define_expand "smulsi3_highpart"
7336   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7337                    (truncate:SI
7338                      (lshiftrt:DI
7339                        (mult:DI (sign_extend:DI
7340                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7341                                 (sign_extend:DI
7342                                   (match_operand:SI 2 "register_operand" "")))
7343                        (const_int 32))))
7344               (clobber (match_scratch:SI 3 ""))
7345               (clobber (reg:CC FLAGS_REG))])]
7346   ""
7347   "")
7348
7349 (define_insn "*smulsi3_highpart_insn"
7350   [(set (match_operand:SI 0 "register_operand" "=d")
7351         (truncate:SI
7352           (lshiftrt:DI
7353             (mult:DI (sign_extend:DI
7354                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7355                      (sign_extend:DI
7356                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7357             (const_int 32))))
7358    (clobber (match_scratch:SI 3 "=1"))
7359    (clobber (reg:CC FLAGS_REG))]
7360   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7361   "imul{l}\t%2"
7362   [(set_attr "type" "imul")
7363    (set (attr "athlon_decode")
7364      (if_then_else (eq_attr "cpu" "athlon")
7365         (const_string "vector")
7366         (const_string "double")))
7367    (set_attr "mode" "SI")])
7368
7369 (define_insn "*smulsi3_highpart_zext"
7370   [(set (match_operand:DI 0 "register_operand" "=d")
7371         (zero_extend:DI (truncate:SI
7372           (lshiftrt:DI
7373             (mult:DI (sign_extend:DI
7374                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7375                      (sign_extend:DI
7376                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7377             (const_int 32)))))
7378    (clobber (match_scratch:SI 3 "=1"))
7379    (clobber (reg:CC FLAGS_REG))]
7380   "TARGET_64BIT
7381    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7382   "imul{l}\t%2"
7383   [(set_attr "type" "imul")
7384    (set (attr "athlon_decode")
7385      (if_then_else (eq_attr "cpu" "athlon")
7386         (const_string "vector")
7387         (const_string "double")))
7388    (set_attr "mode" "SI")])
7389
7390 ;; The patterns that match these are at the end of this file.
7391
7392 (define_expand "mulxf3"
7393   [(set (match_operand:XF 0 "register_operand" "")
7394         (mult:XF (match_operand:XF 1 "register_operand" "")
7395                  (match_operand:XF 2 "register_operand" "")))]
7396   "TARGET_80387"
7397   "")
7398
7399 (define_expand "muldf3"
7400   [(set (match_operand:DF 0 "register_operand" "")
7401         (mult:DF (match_operand:DF 1 "register_operand" "")
7402                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7403   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7404   "")
7405
7406 (define_expand "mulsf3"
7407   [(set (match_operand:SF 0 "register_operand" "")
7408         (mult:SF (match_operand:SF 1 "register_operand" "")
7409                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7410   "TARGET_80387 || TARGET_SSE_MATH"
7411   "")
7412 \f
7413 ;; Divide instructions
7414
7415 (define_insn "divqi3"
7416   [(set (match_operand:QI 0 "register_operand" "=a")
7417         (div:QI (match_operand:HI 1 "register_operand" "0")
7418                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "TARGET_QIMODE_MATH"
7421   "idiv{b}\t%2"
7422   [(set_attr "type" "idiv")
7423    (set_attr "mode" "QI")])
7424
7425 (define_insn "udivqi3"
7426   [(set (match_operand:QI 0 "register_operand" "=a")
7427         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7428                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7429    (clobber (reg:CC FLAGS_REG))]
7430   "TARGET_QIMODE_MATH"
7431   "div{b}\t%2"
7432   [(set_attr "type" "idiv")
7433    (set_attr "mode" "QI")])
7434
7435 ;; The patterns that match these are at the end of this file.
7436
7437 (define_expand "divxf3"
7438   [(set (match_operand:XF 0 "register_operand" "")
7439         (div:XF (match_operand:XF 1 "register_operand" "")
7440                 (match_operand:XF 2 "register_operand" "")))]
7441   "TARGET_80387"
7442   "")
7443
7444 (define_expand "divdf3"
7445   [(set (match_operand:DF 0 "register_operand" "")
7446         (div:DF (match_operand:DF 1 "register_operand" "")
7447                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7448    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7449    "")
7450  
7451 (define_expand "divsf3"
7452   [(set (match_operand:SF 0 "register_operand" "")
7453         (div:SF (match_operand:SF 1 "register_operand" "")
7454                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7455   "TARGET_80387 || TARGET_SSE_MATH"
7456   "")
7457 \f
7458 ;; Remainder instructions.
7459
7460 (define_expand "divmoddi4"
7461   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7462                    (div:DI (match_operand:DI 1 "register_operand" "")
7463                            (match_operand:DI 2 "nonimmediate_operand" "")))
7464               (set (match_operand:DI 3 "register_operand" "")
7465                    (mod:DI (match_dup 1) (match_dup 2)))
7466               (clobber (reg:CC FLAGS_REG))])]
7467   "TARGET_64BIT"
7468   "")
7469
7470 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7471 ;; Penalize eax case slightly because it results in worse scheduling
7472 ;; of code.
7473 (define_insn "*divmoddi4_nocltd_rex64"
7474   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7475         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7476                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7477    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7478         (mod:DI (match_dup 2) (match_dup 3)))
7479    (clobber (reg:CC FLAGS_REG))]
7480   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7481   "#"
7482   [(set_attr "type" "multi")])
7483
7484 (define_insn "*divmoddi4_cltd_rex64"
7485   [(set (match_operand:DI 0 "register_operand" "=a")
7486         (div:DI (match_operand:DI 2 "register_operand" "a")
7487                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7488    (set (match_operand:DI 1 "register_operand" "=&d")
7489         (mod:DI (match_dup 2) (match_dup 3)))
7490    (clobber (reg:CC FLAGS_REG))]
7491   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7492   "#"
7493   [(set_attr "type" "multi")])
7494
7495 (define_insn "*divmoddi_noext_rex64"
7496   [(set (match_operand:DI 0 "register_operand" "=a")
7497         (div:DI (match_operand:DI 1 "register_operand" "0")
7498                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7499    (set (match_operand:DI 3 "register_operand" "=d")
7500         (mod:DI (match_dup 1) (match_dup 2)))
7501    (use (match_operand:DI 4 "register_operand" "3"))
7502    (clobber (reg:CC FLAGS_REG))]
7503   "TARGET_64BIT"
7504   "idiv{q}\t%2"
7505   [(set_attr "type" "idiv")
7506    (set_attr "mode" "DI")])
7507
7508 (define_split
7509   [(set (match_operand:DI 0 "register_operand" "")
7510         (div:DI (match_operand:DI 1 "register_operand" "")
7511                 (match_operand:DI 2 "nonimmediate_operand" "")))
7512    (set (match_operand:DI 3 "register_operand" "")
7513         (mod:DI (match_dup 1) (match_dup 2)))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "TARGET_64BIT && reload_completed"
7516   [(parallel [(set (match_dup 3)
7517                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7518               (clobber (reg:CC FLAGS_REG))])
7519    (parallel [(set (match_dup 0)
7520                    (div:DI (reg:DI 0) (match_dup 2)))
7521               (set (match_dup 3)
7522                    (mod:DI (reg:DI 0) (match_dup 2)))
7523               (use (match_dup 3))
7524               (clobber (reg:CC FLAGS_REG))])]
7525 {
7526   /* Avoid use of cltd in favor of a mov+shift.  */
7527   if (!TARGET_USE_CLTD && !optimize_size)
7528     {
7529       if (true_regnum (operands[1]))
7530         emit_move_insn (operands[0], operands[1]);
7531       else
7532         emit_move_insn (operands[3], operands[1]);
7533       operands[4] = operands[3];
7534     }
7535   else
7536     {
7537       if (true_regnum (operands[1]))
7538         abort();
7539       operands[4] = operands[1];
7540     }
7541 })
7542
7543
7544 (define_expand "divmodsi4"
7545   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7546                    (div:SI (match_operand:SI 1 "register_operand" "")
7547                            (match_operand:SI 2 "nonimmediate_operand" "")))
7548               (set (match_operand:SI 3 "register_operand" "")
7549                    (mod:SI (match_dup 1) (match_dup 2)))
7550               (clobber (reg:CC FLAGS_REG))])]
7551   ""
7552   "")
7553
7554 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7555 ;; Penalize eax case slightly because it results in worse scheduling
7556 ;; of code.
7557 (define_insn "*divmodsi4_nocltd"
7558   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7559         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7560                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7561    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7562         (mod:SI (match_dup 2) (match_dup 3)))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "!optimize_size && !TARGET_USE_CLTD"
7565   "#"
7566   [(set_attr "type" "multi")])
7567
7568 (define_insn "*divmodsi4_cltd"
7569   [(set (match_operand:SI 0 "register_operand" "=a")
7570         (div:SI (match_operand:SI 2 "register_operand" "a")
7571                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7572    (set (match_operand:SI 1 "register_operand" "=&d")
7573         (mod:SI (match_dup 2) (match_dup 3)))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "optimize_size || TARGET_USE_CLTD"
7576   "#"
7577   [(set_attr "type" "multi")])
7578
7579 (define_insn "*divmodsi_noext"
7580   [(set (match_operand:SI 0 "register_operand" "=a")
7581         (div:SI (match_operand:SI 1 "register_operand" "0")
7582                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7583    (set (match_operand:SI 3 "register_operand" "=d")
7584         (mod:SI (match_dup 1) (match_dup 2)))
7585    (use (match_operand:SI 4 "register_operand" "3"))
7586    (clobber (reg:CC FLAGS_REG))]
7587   ""
7588   "idiv{l}\t%2"
7589   [(set_attr "type" "idiv")
7590    (set_attr "mode" "SI")])
7591
7592 (define_split
7593   [(set (match_operand:SI 0 "register_operand" "")
7594         (div:SI (match_operand:SI 1 "register_operand" "")
7595                 (match_operand:SI 2 "nonimmediate_operand" "")))
7596    (set (match_operand:SI 3 "register_operand" "")
7597         (mod:SI (match_dup 1) (match_dup 2)))
7598    (clobber (reg:CC FLAGS_REG))]
7599   "reload_completed"
7600   [(parallel [(set (match_dup 3)
7601                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7602               (clobber (reg:CC FLAGS_REG))])
7603    (parallel [(set (match_dup 0)
7604                    (div:SI (reg:SI 0) (match_dup 2)))
7605               (set (match_dup 3)
7606                    (mod:SI (reg:SI 0) (match_dup 2)))
7607               (use (match_dup 3))
7608               (clobber (reg:CC FLAGS_REG))])]
7609 {
7610   /* Avoid use of cltd in favor of a mov+shift.  */
7611   if (!TARGET_USE_CLTD && !optimize_size)
7612     {
7613       if (true_regnum (operands[1]))
7614         emit_move_insn (operands[0], operands[1]);
7615       else
7616         emit_move_insn (operands[3], operands[1]);
7617       operands[4] = operands[3];
7618     }
7619   else
7620     {
7621       if (true_regnum (operands[1]))
7622         abort();
7623       operands[4] = operands[1];
7624     }
7625 })
7626 ;; %%% Split me.
7627 (define_insn "divmodhi4"
7628   [(set (match_operand:HI 0 "register_operand" "=a")
7629         (div:HI (match_operand:HI 1 "register_operand" "0")
7630                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7631    (set (match_operand:HI 3 "register_operand" "=&d")
7632         (mod:HI (match_dup 1) (match_dup 2)))
7633    (clobber (reg:CC FLAGS_REG))]
7634   "TARGET_HIMODE_MATH"
7635   "cwtd\;idiv{w}\t%2"
7636   [(set_attr "type" "multi")
7637    (set_attr "length_immediate" "0")
7638    (set_attr "mode" "SI")])
7639
7640 (define_insn "udivmoddi4"
7641   [(set (match_operand:DI 0 "register_operand" "=a")
7642         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7643                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7644    (set (match_operand:DI 3 "register_operand" "=&d")
7645         (umod:DI (match_dup 1) (match_dup 2)))
7646    (clobber (reg:CC FLAGS_REG))]
7647   "TARGET_64BIT"
7648   "xor{q}\t%3, %3\;div{q}\t%2"
7649   [(set_attr "type" "multi")
7650    (set_attr "length_immediate" "0")
7651    (set_attr "mode" "DI")])
7652
7653 (define_insn "*udivmoddi4_noext"
7654   [(set (match_operand:DI 0 "register_operand" "=a")
7655         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7656                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7657    (set (match_operand:DI 3 "register_operand" "=d")
7658         (umod:DI (match_dup 1) (match_dup 2)))
7659    (use (match_dup 3))
7660    (clobber (reg:CC FLAGS_REG))]
7661   "TARGET_64BIT"
7662   "div{q}\t%2"
7663   [(set_attr "type" "idiv")
7664    (set_attr "mode" "DI")])
7665
7666 (define_split
7667   [(set (match_operand:DI 0 "register_operand" "")
7668         (udiv:DI (match_operand:DI 1 "register_operand" "")
7669                  (match_operand:DI 2 "nonimmediate_operand" "")))
7670    (set (match_operand:DI 3 "register_operand" "")
7671         (umod:DI (match_dup 1) (match_dup 2)))
7672    (clobber (reg:CC FLAGS_REG))]
7673   "TARGET_64BIT && reload_completed"
7674   [(set (match_dup 3) (const_int 0))
7675    (parallel [(set (match_dup 0)
7676                    (udiv:DI (match_dup 1) (match_dup 2)))
7677               (set (match_dup 3)
7678                    (umod:DI (match_dup 1) (match_dup 2)))
7679               (use (match_dup 3))
7680               (clobber (reg:CC FLAGS_REG))])]
7681   "")
7682
7683 (define_insn "udivmodsi4"
7684   [(set (match_operand:SI 0 "register_operand" "=a")
7685         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7686                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7687    (set (match_operand:SI 3 "register_operand" "=&d")
7688         (umod:SI (match_dup 1) (match_dup 2)))
7689    (clobber (reg:CC FLAGS_REG))]
7690   ""
7691   "xor{l}\t%3, %3\;div{l}\t%2"
7692   [(set_attr "type" "multi")
7693    (set_attr "length_immediate" "0")
7694    (set_attr "mode" "SI")])
7695
7696 (define_insn "*udivmodsi4_noext"
7697   [(set (match_operand:SI 0 "register_operand" "=a")
7698         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7699                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7700    (set (match_operand:SI 3 "register_operand" "=d")
7701         (umod:SI (match_dup 1) (match_dup 2)))
7702    (use (match_dup 3))
7703    (clobber (reg:CC FLAGS_REG))]
7704   ""
7705   "div{l}\t%2"
7706   [(set_attr "type" "idiv")
7707    (set_attr "mode" "SI")])
7708
7709 (define_split
7710   [(set (match_operand:SI 0 "register_operand" "")
7711         (udiv:SI (match_operand:SI 1 "register_operand" "")
7712                  (match_operand:SI 2 "nonimmediate_operand" "")))
7713    (set (match_operand:SI 3 "register_operand" "")
7714         (umod:SI (match_dup 1) (match_dup 2)))
7715    (clobber (reg:CC FLAGS_REG))]
7716   "reload_completed"
7717   [(set (match_dup 3) (const_int 0))
7718    (parallel [(set (match_dup 0)
7719                    (udiv:SI (match_dup 1) (match_dup 2)))
7720               (set (match_dup 3)
7721                    (umod:SI (match_dup 1) (match_dup 2)))
7722               (use (match_dup 3))
7723               (clobber (reg:CC FLAGS_REG))])]
7724   "")
7725
7726 (define_expand "udivmodhi4"
7727   [(set (match_dup 4) (const_int 0))
7728    (parallel [(set (match_operand:HI 0 "register_operand" "")
7729                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7730                             (match_operand:HI 2 "nonimmediate_operand" "")))
7731               (set (match_operand:HI 3 "register_operand" "")
7732                    (umod:HI (match_dup 1) (match_dup 2)))
7733               (use (match_dup 4))
7734               (clobber (reg:CC FLAGS_REG))])]
7735   "TARGET_HIMODE_MATH"
7736   "operands[4] = gen_reg_rtx (HImode);")
7737
7738 (define_insn "*udivmodhi_noext"
7739   [(set (match_operand:HI 0 "register_operand" "=a")
7740         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7741                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7742    (set (match_operand:HI 3 "register_operand" "=d")
7743         (umod:HI (match_dup 1) (match_dup 2)))
7744    (use (match_operand:HI 4 "register_operand" "3"))
7745    (clobber (reg:CC FLAGS_REG))]
7746   ""
7747   "div{w}\t%2"
7748   [(set_attr "type" "idiv")
7749    (set_attr "mode" "HI")])
7750
7751 ;; We cannot use div/idiv for double division, because it causes
7752 ;; "division by zero" on the overflow and that's not what we expect
7753 ;; from truncate.  Because true (non truncating) double division is
7754 ;; never generated, we can't create this insn anyway.
7755 ;
7756 ;(define_insn ""
7757 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7758 ;       (truncate:SI
7759 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7760 ;                  (zero_extend:DI
7761 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7762 ;   (set (match_operand:SI 3 "register_operand" "=d")
7763 ;       (truncate:SI
7764 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7765 ;   (clobber (reg:CC FLAGS_REG))]
7766 ;  ""
7767 ;  "div{l}\t{%2, %0|%0, %2}"
7768 ;  [(set_attr "type" "idiv")])
7769 \f
7770 ;;- Logical AND instructions
7771
7772 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7773 ;; Note that this excludes ah.
7774
7775 (define_insn "*testdi_1_rex64"
7776   [(set (reg FLAGS_REG)
7777         (compare
7778           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7779                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7780           (const_int 0)))]
7781   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7782    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7783   "@
7784    test{l}\t{%k1, %k0|%k0, %k1}
7785    test{l}\t{%k1, %k0|%k0, %k1}
7786    test{q}\t{%1, %0|%0, %1}
7787    test{q}\t{%1, %0|%0, %1}
7788    test{q}\t{%1, %0|%0, %1}"
7789   [(set_attr "type" "test")
7790    (set_attr "modrm" "0,1,0,1,1")
7791    (set_attr "mode" "SI,SI,DI,DI,DI")
7792    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7793
7794 (define_insn "testsi_1"
7795   [(set (reg FLAGS_REG)
7796         (compare
7797           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7798                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7799           (const_int 0)))]
7800   "ix86_match_ccmode (insn, CCNOmode)
7801    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7802   "test{l}\t{%1, %0|%0, %1}"
7803   [(set_attr "type" "test")
7804    (set_attr "modrm" "0,1,1")
7805    (set_attr "mode" "SI")
7806    (set_attr "pent_pair" "uv,np,uv")])
7807
7808 (define_expand "testsi_ccno_1"
7809   [(set (reg:CCNO FLAGS_REG)
7810         (compare:CCNO
7811           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7812                   (match_operand:SI 1 "nonmemory_operand" ""))
7813           (const_int 0)))]
7814   ""
7815   "")
7816
7817 (define_insn "*testhi_1"
7818   [(set (reg FLAGS_REG)
7819         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7820                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7821                  (const_int 0)))]
7822   "ix86_match_ccmode (insn, CCNOmode)
7823    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7824   "test{w}\t{%1, %0|%0, %1}"
7825   [(set_attr "type" "test")
7826    (set_attr "modrm" "0,1,1")
7827    (set_attr "mode" "HI")
7828    (set_attr "pent_pair" "uv,np,uv")])
7829
7830 (define_expand "testqi_ccz_1"
7831   [(set (reg:CCZ FLAGS_REG)
7832         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7833                              (match_operand:QI 1 "nonmemory_operand" ""))
7834                  (const_int 0)))]
7835   ""
7836   "")
7837
7838 (define_insn "*testqi_1_maybe_si"
7839   [(set (reg FLAGS_REG)
7840         (compare
7841           (and:QI
7842             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7843             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7844           (const_int 0)))]
7845    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7846     && ix86_match_ccmode (insn,
7847                          GET_CODE (operands[1]) == CONST_INT
7848                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7849 {
7850   if (which_alternative == 3)
7851     {
7852       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7853         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7854       return "test{l}\t{%1, %k0|%k0, %1}";
7855     }
7856   return "test{b}\t{%1, %0|%0, %1}";
7857 }
7858   [(set_attr "type" "test")
7859    (set_attr "modrm" "0,1,1,1")
7860    (set_attr "mode" "QI,QI,QI,SI")
7861    (set_attr "pent_pair" "uv,np,uv,np")])
7862
7863 (define_insn "*testqi_1"
7864   [(set (reg FLAGS_REG)
7865         (compare
7866           (and:QI
7867             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7868             (match_operand:QI 1 "general_operand" "n,n,qn"))
7869           (const_int 0)))]
7870   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7871    && ix86_match_ccmode (insn, CCNOmode)"
7872   "test{b}\t{%1, %0|%0, %1}"
7873   [(set_attr "type" "test")
7874    (set_attr "modrm" "0,1,1")
7875    (set_attr "mode" "QI")
7876    (set_attr "pent_pair" "uv,np,uv")])
7877
7878 (define_expand "testqi_ext_ccno_0"
7879   [(set (reg:CCNO FLAGS_REG)
7880         (compare:CCNO
7881           (and:SI
7882             (zero_extract:SI
7883               (match_operand 0 "ext_register_operand" "")
7884               (const_int 8)
7885               (const_int 8))
7886             (match_operand 1 "const_int_operand" ""))
7887           (const_int 0)))]
7888   ""
7889   "")
7890
7891 (define_insn "*testqi_ext_0"
7892   [(set (reg FLAGS_REG)
7893         (compare
7894           (and:SI
7895             (zero_extract:SI
7896               (match_operand 0 "ext_register_operand" "Q")
7897               (const_int 8)
7898               (const_int 8))
7899             (match_operand 1 "const_int_operand" "n"))
7900           (const_int 0)))]
7901   "ix86_match_ccmode (insn, CCNOmode)"
7902   "test{b}\t{%1, %h0|%h0, %1}"
7903   [(set_attr "type" "test")
7904    (set_attr "mode" "QI")
7905    (set_attr "length_immediate" "1")
7906    (set_attr "pent_pair" "np")])
7907
7908 (define_insn "*testqi_ext_1"
7909   [(set (reg FLAGS_REG)
7910         (compare
7911           (and:SI
7912             (zero_extract:SI
7913               (match_operand 0 "ext_register_operand" "Q")
7914               (const_int 8)
7915               (const_int 8))
7916             (zero_extend:SI
7917               (match_operand:QI 1 "general_operand" "Qm")))
7918           (const_int 0)))]
7919   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7921   "test{b}\t{%1, %h0|%h0, %1}"
7922   [(set_attr "type" "test")
7923    (set_attr "mode" "QI")])
7924
7925 (define_insn "*testqi_ext_1_rex64"
7926   [(set (reg FLAGS_REG)
7927         (compare
7928           (and:SI
7929             (zero_extract:SI
7930               (match_operand 0 "ext_register_operand" "Q")
7931               (const_int 8)
7932               (const_int 8))
7933             (zero_extend:SI
7934               (match_operand:QI 1 "register_operand" "Q")))
7935           (const_int 0)))]
7936   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7937   "test{b}\t{%1, %h0|%h0, %1}"
7938   [(set_attr "type" "test")
7939    (set_attr "mode" "QI")])
7940
7941 (define_insn "*testqi_ext_2"
7942   [(set (reg FLAGS_REG)
7943         (compare
7944           (and:SI
7945             (zero_extract:SI
7946               (match_operand 0 "ext_register_operand" "Q")
7947               (const_int 8)
7948               (const_int 8))
7949             (zero_extract:SI
7950               (match_operand 1 "ext_register_operand" "Q")
7951               (const_int 8)
7952               (const_int 8)))
7953           (const_int 0)))]
7954   "ix86_match_ccmode (insn, CCNOmode)"
7955   "test{b}\t{%h1, %h0|%h0, %h1}"
7956   [(set_attr "type" "test")
7957    (set_attr "mode" "QI")])
7958
7959 ;; Combine likes to form bit extractions for some tests.  Humor it.
7960 (define_insn "*testqi_ext_3"
7961   [(set (reg FLAGS_REG)
7962         (compare (zero_extract:SI
7963                    (match_operand 0 "nonimmediate_operand" "rm")
7964                    (match_operand:SI 1 "const_int_operand" "")
7965                    (match_operand:SI 2 "const_int_operand" ""))
7966                  (const_int 0)))]
7967   "ix86_match_ccmode (insn, CCNOmode)
7968    && (GET_MODE (operands[0]) == SImode
7969        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7970        || GET_MODE (operands[0]) == HImode
7971        || GET_MODE (operands[0]) == QImode)"
7972   "#")
7973
7974 (define_insn "*testqi_ext_3_rex64"
7975   [(set (reg FLAGS_REG)
7976         (compare (zero_extract:DI
7977                    (match_operand 0 "nonimmediate_operand" "rm")
7978                    (match_operand:DI 1 "const_int_operand" "")
7979                    (match_operand:DI 2 "const_int_operand" ""))
7980                  (const_int 0)))]
7981   "TARGET_64BIT
7982    && ix86_match_ccmode (insn, CCNOmode)
7983    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7984    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7985    /* Ensure that resulting mask is zero or sign extended operand.  */
7986    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7987        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7988            && INTVAL (operands[1]) > 32))
7989    && (GET_MODE (operands[0]) == SImode
7990        || GET_MODE (operands[0]) == DImode
7991        || GET_MODE (operands[0]) == HImode
7992        || GET_MODE (operands[0]) == QImode)"
7993   "#")
7994
7995 (define_split
7996   [(set (match_operand 0 "flags_reg_operand" "")
7997         (match_operator 1 "compare_operator"
7998           [(zero_extract
7999              (match_operand 2 "nonimmediate_operand" "")
8000              (match_operand 3 "const_int_operand" "")
8001              (match_operand 4 "const_int_operand" ""))
8002            (const_int 0)]))]
8003   "ix86_match_ccmode (insn, CCNOmode)"
8004   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8005 {
8006   rtx val = operands[2];
8007   HOST_WIDE_INT len = INTVAL (operands[3]);
8008   HOST_WIDE_INT pos = INTVAL (operands[4]);
8009   HOST_WIDE_INT mask;
8010   enum machine_mode mode, submode;
8011
8012   mode = GET_MODE (val);
8013   if (GET_CODE (val) == MEM)
8014     {
8015       /* ??? Combine likes to put non-volatile mem extractions in QImode
8016          no matter the size of the test.  So find a mode that works.  */
8017       if (! MEM_VOLATILE_P (val))
8018         {
8019           mode = smallest_mode_for_size (pos + len, MODE_INT);
8020           val = adjust_address (val, mode, 0);
8021         }
8022     }
8023   else if (GET_CODE (val) == SUBREG
8024            && (submode = GET_MODE (SUBREG_REG (val)),
8025                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8026            && pos + len <= GET_MODE_BITSIZE (submode))
8027     {
8028       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8029       mode = submode;
8030       val = SUBREG_REG (val);
8031     }
8032   else if (mode == HImode && pos + len <= 8)
8033     {
8034       /* Small HImode tests can be converted to QImode.  */
8035       mode = QImode;
8036       val = gen_lowpart (QImode, val);
8037     }
8038
8039   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8040   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8041
8042   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8043 })
8044
8045 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8046 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8047 ;; this is relatively important trick.
8048 ;; Do the conversion only post-reload to avoid limiting of the register class
8049 ;; to QI regs.
8050 (define_split
8051   [(set (match_operand 0 "flags_reg_operand" "")
8052         (match_operator 1 "compare_operator"
8053           [(and (match_operand 2 "register_operand" "")
8054                 (match_operand 3 "const_int_operand" ""))
8055            (const_int 0)]))]
8056    "reload_completed
8057     && QI_REG_P (operands[2])
8058     && GET_MODE (operands[2]) != QImode
8059     && ((ix86_match_ccmode (insn, CCZmode)
8060          && !(INTVAL (operands[3]) & ~(255 << 8)))
8061         || (ix86_match_ccmode (insn, CCNOmode)
8062             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8063   [(set (match_dup 0)
8064         (match_op_dup 1
8065           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8066                    (match_dup 3))
8067            (const_int 0)]))]
8068   "operands[2] = gen_lowpart (SImode, operands[2]);
8069    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8070
8071 (define_split
8072   [(set (match_operand 0 "flags_reg_operand" "")
8073         (match_operator 1 "compare_operator"
8074           [(and (match_operand 2 "nonimmediate_operand" "")
8075                 (match_operand 3 "const_int_operand" ""))
8076            (const_int 0)]))]
8077    "reload_completed
8078     && GET_MODE (operands[2]) != QImode
8079     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8080     && ((ix86_match_ccmode (insn, CCZmode)
8081          && !(INTVAL (operands[3]) & ~255))
8082         || (ix86_match_ccmode (insn, CCNOmode)
8083             && !(INTVAL (operands[3]) & ~127)))"
8084   [(set (match_dup 0)
8085         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8086                          (const_int 0)]))]
8087   "operands[2] = gen_lowpart (QImode, operands[2]);
8088    operands[3] = gen_lowpart (QImode, operands[3]);")
8089
8090
8091 ;; %%% This used to optimize known byte-wide and operations to memory,
8092 ;; and sometimes to QImode registers.  If this is considered useful,
8093 ;; it should be done with splitters.
8094
8095 (define_expand "anddi3"
8096   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8097         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8098                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "TARGET_64BIT"
8101   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8102
8103 (define_insn "*anddi_1_rex64"
8104   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8105         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8106                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8107    (clobber (reg:CC FLAGS_REG))]
8108   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8109 {
8110   switch (get_attr_type (insn))
8111     {
8112     case TYPE_IMOVX:
8113       {
8114         enum machine_mode mode;
8115
8116         if (GET_CODE (operands[2]) != CONST_INT)
8117           abort ();
8118         if (INTVAL (operands[2]) == 0xff)
8119           mode = QImode;
8120         else if (INTVAL (operands[2]) == 0xffff)
8121           mode = HImode;
8122         else
8123           abort ();
8124         
8125         operands[1] = gen_lowpart (mode, operands[1]);
8126         if (mode == QImode)
8127           return "movz{bq|x}\t{%1,%0|%0, %1}";
8128         else
8129           return "movz{wq|x}\t{%1,%0|%0, %1}";
8130       }
8131
8132     default:
8133       if (! rtx_equal_p (operands[0], operands[1]))
8134         abort ();
8135       if (get_attr_mode (insn) == MODE_SI)
8136         return "and{l}\t{%k2, %k0|%k0, %k2}";
8137       else
8138         return "and{q}\t{%2, %0|%0, %2}";
8139     }
8140 }
8141   [(set_attr "type" "alu,alu,alu,imovx")
8142    (set_attr "length_immediate" "*,*,*,0")
8143    (set_attr "mode" "SI,DI,DI,DI")])
8144
8145 (define_insn "*anddi_2"
8146   [(set (reg FLAGS_REG)
8147         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8148                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8149                  (const_int 0)))
8150    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8151         (and:DI (match_dup 1) (match_dup 2)))]
8152   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8153    && ix86_binary_operator_ok (AND, DImode, operands)"
8154   "@
8155    and{l}\t{%k2, %k0|%k0, %k2}
8156    and{q}\t{%2, %0|%0, %2}
8157    and{q}\t{%2, %0|%0, %2}"
8158   [(set_attr "type" "alu")
8159    (set_attr "mode" "SI,DI,DI")])
8160
8161 (define_expand "andsi3"
8162   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8163         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8164                 (match_operand:SI 2 "general_operand" "")))
8165    (clobber (reg:CC FLAGS_REG))]
8166   ""
8167   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8168
8169 (define_insn "*andsi_1"
8170   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8171         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8172                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8173    (clobber (reg:CC FLAGS_REG))]
8174   "ix86_binary_operator_ok (AND, SImode, operands)"
8175 {
8176   switch (get_attr_type (insn))
8177     {
8178     case TYPE_IMOVX:
8179       {
8180         enum machine_mode mode;
8181
8182         if (GET_CODE (operands[2]) != CONST_INT)
8183           abort ();
8184         if (INTVAL (operands[2]) == 0xff)
8185           mode = QImode;
8186         else if (INTVAL (operands[2]) == 0xffff)
8187           mode = HImode;
8188         else
8189           abort ();
8190         
8191         operands[1] = gen_lowpart (mode, operands[1]);
8192         if (mode == QImode)
8193           return "movz{bl|x}\t{%1,%0|%0, %1}";
8194         else
8195           return "movz{wl|x}\t{%1,%0|%0, %1}";
8196       }
8197
8198     default:
8199       if (! rtx_equal_p (operands[0], operands[1]))
8200         abort ();
8201       return "and{l}\t{%2, %0|%0, %2}";
8202     }
8203 }
8204   [(set_attr "type" "alu,alu,imovx")
8205    (set_attr "length_immediate" "*,*,0")
8206    (set_attr "mode" "SI")])
8207
8208 (define_split
8209   [(set (match_operand 0 "register_operand" "")
8210         (and (match_dup 0)
8211              (const_int -65536)))
8212    (clobber (reg:CC FLAGS_REG))]
8213   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8214   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8215   "operands[1] = gen_lowpart (HImode, operands[0]);")
8216
8217 (define_split
8218   [(set (match_operand 0 "ext_register_operand" "")
8219         (and (match_dup 0)
8220              (const_int -256)))
8221    (clobber (reg:CC FLAGS_REG))]
8222   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8223   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8224   "operands[1] = gen_lowpart (QImode, operands[0]);")
8225
8226 (define_split
8227   [(set (match_operand 0 "ext_register_operand" "")
8228         (and (match_dup 0)
8229              (const_int -65281)))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8232   [(parallel [(set (zero_extract:SI (match_dup 0)
8233                                     (const_int 8)
8234                                     (const_int 8))
8235                    (xor:SI 
8236                      (zero_extract:SI (match_dup 0)
8237                                       (const_int 8)
8238                                       (const_int 8))
8239                      (zero_extract:SI (match_dup 0)
8240                                       (const_int 8)
8241                                       (const_int 8))))
8242               (clobber (reg:CC FLAGS_REG))])]
8243   "operands[0] = gen_lowpart (SImode, operands[0]);")
8244
8245 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8246 (define_insn "*andsi_1_zext"
8247   [(set (match_operand:DI 0 "register_operand" "=r")
8248         (zero_extend:DI
8249           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250                   (match_operand:SI 2 "general_operand" "rim"))))
8251    (clobber (reg:CC FLAGS_REG))]
8252   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8253   "and{l}\t{%2, %k0|%k0, %2}"
8254   [(set_attr "type" "alu")
8255    (set_attr "mode" "SI")])
8256
8257 (define_insn "*andsi_2"
8258   [(set (reg FLAGS_REG)
8259         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8260                          (match_operand:SI 2 "general_operand" "rim,ri"))
8261                  (const_int 0)))
8262    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8263         (and:SI (match_dup 1) (match_dup 2)))]
8264   "ix86_match_ccmode (insn, CCNOmode)
8265    && ix86_binary_operator_ok (AND, SImode, operands)"
8266   "and{l}\t{%2, %0|%0, %2}"
8267   [(set_attr "type" "alu")
8268    (set_attr "mode" "SI")])
8269
8270 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8271 (define_insn "*andsi_2_zext"
8272   [(set (reg FLAGS_REG)
8273         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8274                          (match_operand:SI 2 "general_operand" "rim"))
8275                  (const_int 0)))
8276    (set (match_operand:DI 0 "register_operand" "=r")
8277         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8278   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8279    && ix86_binary_operator_ok (AND, SImode, operands)"
8280   "and{l}\t{%2, %k0|%k0, %2}"
8281   [(set_attr "type" "alu")
8282    (set_attr "mode" "SI")])
8283
8284 (define_expand "andhi3"
8285   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8286         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8287                 (match_operand:HI 2 "general_operand" "")))
8288    (clobber (reg:CC FLAGS_REG))]
8289   "TARGET_HIMODE_MATH"
8290   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8291
8292 (define_insn "*andhi_1"
8293   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8294         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8295                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "ix86_binary_operator_ok (AND, HImode, operands)"
8298 {
8299   switch (get_attr_type (insn))
8300     {
8301     case TYPE_IMOVX:
8302       if (GET_CODE (operands[2]) != CONST_INT)
8303         abort ();
8304       if (INTVAL (operands[2]) == 0xff)
8305         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8306       abort ();
8307
8308     default:
8309       if (! rtx_equal_p (operands[0], operands[1]))
8310         abort ();
8311
8312       return "and{w}\t{%2, %0|%0, %2}";
8313     }
8314 }
8315   [(set_attr "type" "alu,alu,imovx")
8316    (set_attr "length_immediate" "*,*,0")
8317    (set_attr "mode" "HI,HI,SI")])
8318
8319 (define_insn "*andhi_2"
8320   [(set (reg FLAGS_REG)
8321         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8322                          (match_operand:HI 2 "general_operand" "rim,ri"))
8323                  (const_int 0)))
8324    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8325         (and:HI (match_dup 1) (match_dup 2)))]
8326   "ix86_match_ccmode (insn, CCNOmode)
8327    && ix86_binary_operator_ok (AND, HImode, operands)"
8328   "and{w}\t{%2, %0|%0, %2}"
8329   [(set_attr "type" "alu")
8330    (set_attr "mode" "HI")])
8331
8332 (define_expand "andqi3"
8333   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8334         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8335                 (match_operand:QI 2 "general_operand" "")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "TARGET_QIMODE_MATH"
8338   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8339
8340 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8341 (define_insn "*andqi_1"
8342   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8343         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8344                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "ix86_binary_operator_ok (AND, QImode, operands)"
8347   "@
8348    and{b}\t{%2, %0|%0, %2}
8349    and{b}\t{%2, %0|%0, %2}
8350    and{l}\t{%k2, %k0|%k0, %k2}"
8351   [(set_attr "type" "alu")
8352    (set_attr "mode" "QI,QI,SI")])
8353
8354 (define_insn "*andqi_1_slp"
8355   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8356         (and:QI (match_dup 0)
8357                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8358    (clobber (reg:CC FLAGS_REG))]
8359   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8360    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8361   "and{b}\t{%1, %0|%0, %1}"
8362   [(set_attr "type" "alu1")
8363    (set_attr "mode" "QI")])
8364
8365 (define_insn "*andqi_2_maybe_si"
8366   [(set (reg FLAGS_REG)
8367         (compare (and:QI
8368                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8369                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8370                  (const_int 0)))
8371    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8372         (and:QI (match_dup 1) (match_dup 2)))]
8373   "ix86_binary_operator_ok (AND, QImode, operands)
8374    && ix86_match_ccmode (insn,
8375                          GET_CODE (operands[2]) == CONST_INT
8376                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8377 {
8378   if (which_alternative == 2)
8379     {
8380       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8381         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8382       return "and{l}\t{%2, %k0|%k0, %2}";
8383     }
8384   return "and{b}\t{%2, %0|%0, %2}";
8385 }
8386   [(set_attr "type" "alu")
8387    (set_attr "mode" "QI,QI,SI")])
8388
8389 (define_insn "*andqi_2"
8390   [(set (reg FLAGS_REG)
8391         (compare (and:QI
8392                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8393                    (match_operand:QI 2 "general_operand" "qim,qi"))
8394                  (const_int 0)))
8395    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8396         (and:QI (match_dup 1) (match_dup 2)))]
8397   "ix86_match_ccmode (insn, CCNOmode)
8398    && ix86_binary_operator_ok (AND, QImode, operands)"
8399   "and{b}\t{%2, %0|%0, %2}"
8400   [(set_attr "type" "alu")
8401    (set_attr "mode" "QI")])
8402
8403 (define_insn "*andqi_2_slp"
8404   [(set (reg FLAGS_REG)
8405         (compare (and:QI
8406                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8407                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8408                  (const_int 0)))
8409    (set (strict_low_part (match_dup 0))
8410         (and:QI (match_dup 0) (match_dup 1)))]
8411   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8412    && ix86_match_ccmode (insn, CCNOmode)
8413    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8414   "and{b}\t{%1, %0|%0, %1}"
8415   [(set_attr "type" "alu1")
8416    (set_attr "mode" "QI")])
8417
8418 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8419 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8420 ;; for a QImode operand, which of course failed.
8421
8422 (define_insn "andqi_ext_0"
8423   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8424                          (const_int 8)
8425                          (const_int 8))
8426         (and:SI 
8427           (zero_extract:SI
8428             (match_operand 1 "ext_register_operand" "0")
8429             (const_int 8)
8430             (const_int 8))
8431           (match_operand 2 "const_int_operand" "n")))
8432    (clobber (reg:CC FLAGS_REG))]
8433   ""
8434   "and{b}\t{%2, %h0|%h0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "length_immediate" "1")
8437    (set_attr "mode" "QI")])
8438
8439 ;; Generated by peephole translating test to and.  This shows up
8440 ;; often in fp comparisons.
8441
8442 (define_insn "*andqi_ext_0_cc"
8443   [(set (reg FLAGS_REG)
8444         (compare
8445           (and:SI
8446             (zero_extract:SI
8447               (match_operand 1 "ext_register_operand" "0")
8448               (const_int 8)
8449               (const_int 8))
8450             (match_operand 2 "const_int_operand" "n"))
8451           (const_int 0)))
8452    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8453                          (const_int 8)
8454                          (const_int 8))
8455         (and:SI 
8456           (zero_extract:SI
8457             (match_dup 1)
8458             (const_int 8)
8459             (const_int 8))
8460           (match_dup 2)))]
8461   "ix86_match_ccmode (insn, CCNOmode)"
8462   "and{b}\t{%2, %h0|%h0, %2}"
8463   [(set_attr "type" "alu")
8464    (set_attr "length_immediate" "1")
8465    (set_attr "mode" "QI")])
8466
8467 (define_insn "*andqi_ext_1"
8468   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8469                          (const_int 8)
8470                          (const_int 8))
8471         (and:SI 
8472           (zero_extract:SI
8473             (match_operand 1 "ext_register_operand" "0")
8474             (const_int 8)
8475             (const_int 8))
8476           (zero_extend:SI
8477             (match_operand:QI 2 "general_operand" "Qm"))))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "!TARGET_64BIT"
8480   "and{b}\t{%2, %h0|%h0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "length_immediate" "0")
8483    (set_attr "mode" "QI")])
8484
8485 (define_insn "*andqi_ext_1_rex64"
8486   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8487                          (const_int 8)
8488                          (const_int 8))
8489         (and:SI 
8490           (zero_extract:SI
8491             (match_operand 1 "ext_register_operand" "0")
8492             (const_int 8)
8493             (const_int 8))
8494           (zero_extend:SI
8495             (match_operand 2 "ext_register_operand" "Q"))))
8496    (clobber (reg:CC FLAGS_REG))]
8497   "TARGET_64BIT"
8498   "and{b}\t{%2, %h0|%h0, %2}"
8499   [(set_attr "type" "alu")
8500    (set_attr "length_immediate" "0")
8501    (set_attr "mode" "QI")])
8502
8503 (define_insn "*andqi_ext_2"
8504   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8505                          (const_int 8)
8506                          (const_int 8))
8507         (and:SI
8508           (zero_extract:SI
8509             (match_operand 1 "ext_register_operand" "%0")
8510             (const_int 8)
8511             (const_int 8))
8512           (zero_extract:SI
8513             (match_operand 2 "ext_register_operand" "Q")
8514             (const_int 8)
8515             (const_int 8))))
8516    (clobber (reg:CC FLAGS_REG))]
8517   ""
8518   "and{b}\t{%h2, %h0|%h0, %h2}"
8519   [(set_attr "type" "alu")
8520    (set_attr "length_immediate" "0")
8521    (set_attr "mode" "QI")])
8522
8523 ;; Convert wide AND instructions with immediate operand to shorter QImode
8524 ;; equivalents when possible.
8525 ;; Don't do the splitting with memory operands, since it introduces risk
8526 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8527 ;; for size, but that can (should?) be handled by generic code instead.
8528 (define_split
8529   [(set (match_operand 0 "register_operand" "")
8530         (and (match_operand 1 "register_operand" "")
8531              (match_operand 2 "const_int_operand" "")))
8532    (clobber (reg:CC FLAGS_REG))]
8533    "reload_completed
8534     && QI_REG_P (operands[0])
8535     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8536     && !(~INTVAL (operands[2]) & ~(255 << 8))
8537     && GET_MODE (operands[0]) != QImode"
8538   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8539                    (and:SI (zero_extract:SI (match_dup 1)
8540                                             (const_int 8) (const_int 8))
8541                            (match_dup 2)))
8542               (clobber (reg:CC FLAGS_REG))])]
8543   "operands[0] = gen_lowpart (SImode, operands[0]);
8544    operands[1] = gen_lowpart (SImode, operands[1]);
8545    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8546
8547 ;; Since AND can be encoded with sign extended immediate, this is only
8548 ;; profitable when 7th bit is not set.
8549 (define_split
8550   [(set (match_operand 0 "register_operand" "")
8551         (and (match_operand 1 "general_operand" "")
8552              (match_operand 2 "const_int_operand" "")))
8553    (clobber (reg:CC FLAGS_REG))]
8554    "reload_completed
8555     && ANY_QI_REG_P (operands[0])
8556     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8557     && !(~INTVAL (operands[2]) & ~255)
8558     && !(INTVAL (operands[2]) & 128)
8559     && GET_MODE (operands[0]) != QImode"
8560   [(parallel [(set (strict_low_part (match_dup 0))
8561                    (and:QI (match_dup 1)
8562                            (match_dup 2)))
8563               (clobber (reg:CC FLAGS_REG))])]
8564   "operands[0] = gen_lowpart (QImode, operands[0]);
8565    operands[1] = gen_lowpart (QImode, operands[1]);
8566    operands[2] = gen_lowpart (QImode, operands[2]);")
8567 \f
8568 ;; Logical inclusive OR instructions
8569
8570 ;; %%% This used to optimize known byte-wide and operations to memory.
8571 ;; If this is considered useful, it should be done with splitters.
8572
8573 (define_expand "iordi3"
8574   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8575         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8576                 (match_operand:DI 2 "x86_64_general_operand" "")))
8577    (clobber (reg:CC FLAGS_REG))]
8578   "TARGET_64BIT"
8579   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8580
8581 (define_insn "*iordi_1_rex64"
8582   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8583         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8584                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "TARGET_64BIT
8587    && ix86_binary_operator_ok (IOR, DImode, operands)"
8588   "or{q}\t{%2, %0|%0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "DI")])
8591
8592 (define_insn "*iordi_2_rex64"
8593   [(set (reg FLAGS_REG)
8594         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8595                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8596                  (const_int 0)))
8597    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8598         (ior:DI (match_dup 1) (match_dup 2)))]
8599   "TARGET_64BIT
8600    && ix86_match_ccmode (insn, CCNOmode)
8601    && ix86_binary_operator_ok (IOR, DImode, operands)"
8602   "or{q}\t{%2, %0|%0, %2}"
8603   [(set_attr "type" "alu")
8604    (set_attr "mode" "DI")])
8605
8606 (define_insn "*iordi_3_rex64"
8607   [(set (reg FLAGS_REG)
8608         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8609                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8610                  (const_int 0)))
8611    (clobber (match_scratch:DI 0 "=r"))]
8612   "TARGET_64BIT
8613    && ix86_match_ccmode (insn, CCNOmode)
8614    && ix86_binary_operator_ok (IOR, DImode, operands)"
8615   "or{q}\t{%2, %0|%0, %2}"
8616   [(set_attr "type" "alu")
8617    (set_attr "mode" "DI")])
8618
8619
8620 (define_expand "iorsi3"
8621   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8622         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8623                 (match_operand:SI 2 "general_operand" "")))
8624    (clobber (reg:CC FLAGS_REG))]
8625   ""
8626   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8627
8628 (define_insn "*iorsi_1"
8629   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8630         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8631                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   "ix86_binary_operator_ok (IOR, SImode, operands)"
8634   "or{l}\t{%2, %0|%0, %2}"
8635   [(set_attr "type" "alu")
8636    (set_attr "mode" "SI")])
8637
8638 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8639 (define_insn "*iorsi_1_zext"
8640   [(set (match_operand:DI 0 "register_operand" "=rm")
8641         (zero_extend:DI
8642           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8643                   (match_operand:SI 2 "general_operand" "rim"))))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8646   "or{l}\t{%2, %k0|%k0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "SI")])
8649
8650 (define_insn "*iorsi_1_zext_imm"
8651   [(set (match_operand:DI 0 "register_operand" "=rm")
8652         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8653                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8654    (clobber (reg:CC FLAGS_REG))]
8655   "TARGET_64BIT"
8656   "or{l}\t{%2, %k0|%k0, %2}"
8657   [(set_attr "type" "alu")
8658    (set_attr "mode" "SI")])
8659
8660 (define_insn "*iorsi_2"
8661   [(set (reg FLAGS_REG)
8662         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8663                          (match_operand:SI 2 "general_operand" "rim,ri"))
8664                  (const_int 0)))
8665    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8666         (ior:SI (match_dup 1) (match_dup 2)))]
8667   "ix86_match_ccmode (insn, CCNOmode)
8668    && ix86_binary_operator_ok (IOR, SImode, operands)"
8669   "or{l}\t{%2, %0|%0, %2}"
8670   [(set_attr "type" "alu")
8671    (set_attr "mode" "SI")])
8672
8673 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8674 ;; ??? Special case for immediate operand is missing - it is tricky.
8675 (define_insn "*iorsi_2_zext"
8676   [(set (reg FLAGS_REG)
8677         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678                          (match_operand:SI 2 "general_operand" "rim"))
8679                  (const_int 0)))
8680    (set (match_operand:DI 0 "register_operand" "=r")
8681         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8682   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8683    && ix86_binary_operator_ok (IOR, SImode, operands)"
8684   "or{l}\t{%2, %k0|%k0, %2}"
8685   [(set_attr "type" "alu")
8686    (set_attr "mode" "SI")])
8687
8688 (define_insn "*iorsi_2_zext_imm"
8689   [(set (reg FLAGS_REG)
8690         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8691                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8692                  (const_int 0)))
8693    (set (match_operand:DI 0 "register_operand" "=r")
8694         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8695   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8696    && ix86_binary_operator_ok (IOR, SImode, operands)"
8697   "or{l}\t{%2, %k0|%k0, %2}"
8698   [(set_attr "type" "alu")
8699    (set_attr "mode" "SI")])
8700
8701 (define_insn "*iorsi_3"
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    (clobber (match_scratch:SI 0 "=r"))]
8707   "ix86_match_ccmode (insn, CCNOmode)
8708    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8709   "or{l}\t{%2, %0|%0, %2}"
8710   [(set_attr "type" "alu")
8711    (set_attr "mode" "SI")])
8712
8713 (define_expand "iorhi3"
8714   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8715         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8716                 (match_operand:HI 2 "general_operand" "")))
8717    (clobber (reg:CC FLAGS_REG))]
8718   "TARGET_HIMODE_MATH"
8719   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8720
8721 (define_insn "*iorhi_1"
8722   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8723         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8724                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8725    (clobber (reg:CC FLAGS_REG))]
8726   "ix86_binary_operator_ok (IOR, HImode, operands)"
8727   "or{w}\t{%2, %0|%0, %2}"
8728   [(set_attr "type" "alu")
8729    (set_attr "mode" "HI")])
8730
8731 (define_insn "*iorhi_2"
8732   [(set (reg FLAGS_REG)
8733         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8734                          (match_operand:HI 2 "general_operand" "rim,ri"))
8735                  (const_int 0)))
8736    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8737         (ior:HI (match_dup 1) (match_dup 2)))]
8738   "ix86_match_ccmode (insn, CCNOmode)
8739    && ix86_binary_operator_ok (IOR, HImode, operands)"
8740   "or{w}\t{%2, %0|%0, %2}"
8741   [(set_attr "type" "alu")
8742    (set_attr "mode" "HI")])
8743
8744 (define_insn "*iorhi_3"
8745   [(set (reg FLAGS_REG)
8746         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8747                          (match_operand:HI 2 "general_operand" "rim"))
8748                  (const_int 0)))
8749    (clobber (match_scratch:HI 0 "=r"))]
8750   "ix86_match_ccmode (insn, CCNOmode)
8751    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8752   "or{w}\t{%2, %0|%0, %2}"
8753   [(set_attr "type" "alu")
8754    (set_attr "mode" "HI")])
8755
8756 (define_expand "iorqi3"
8757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8758         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8759                 (match_operand:QI 2 "general_operand" "")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "TARGET_QIMODE_MATH"
8762   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8763
8764 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8765 (define_insn "*iorqi_1"
8766   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8767         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8768                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "ix86_binary_operator_ok (IOR, QImode, operands)"
8771   "@
8772    or{b}\t{%2, %0|%0, %2}
8773    or{b}\t{%2, %0|%0, %2}
8774    or{l}\t{%k2, %k0|%k0, %k2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "mode" "QI,QI,SI")])
8777
8778 (define_insn "*iorqi_1_slp"
8779   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8780         (ior:QI (match_dup 0)
8781                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8782    (clobber (reg:CC FLAGS_REG))]
8783   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8784    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8785   "or{b}\t{%1, %0|%0, %1}"
8786   [(set_attr "type" "alu1")
8787    (set_attr "mode" "QI")])
8788
8789 (define_insn "*iorqi_2"
8790   [(set (reg FLAGS_REG)
8791         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8792                          (match_operand:QI 2 "general_operand" "qim,qi"))
8793                  (const_int 0)))
8794    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8795         (ior:QI (match_dup 1) (match_dup 2)))]
8796   "ix86_match_ccmode (insn, CCNOmode)
8797    && ix86_binary_operator_ok (IOR, QImode, operands)"
8798   "or{b}\t{%2, %0|%0, %2}"
8799   [(set_attr "type" "alu")
8800    (set_attr "mode" "QI")])
8801
8802 (define_insn "*iorqi_2_slp"
8803   [(set (reg FLAGS_REG)
8804         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8805                          (match_operand:QI 1 "general_operand" "qim,qi"))
8806                  (const_int 0)))
8807    (set (strict_low_part (match_dup 0))
8808         (ior:QI (match_dup 0) (match_dup 1)))]
8809   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8810    && ix86_match_ccmode (insn, CCNOmode)
8811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8812   "or{b}\t{%1, %0|%0, %1}"
8813   [(set_attr "type" "alu1")
8814    (set_attr "mode" "QI")])
8815
8816 (define_insn "*iorqi_3"
8817   [(set (reg FLAGS_REG)
8818         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8819                          (match_operand:QI 2 "general_operand" "qim"))
8820                  (const_int 0)))
8821    (clobber (match_scratch:QI 0 "=q"))]
8822   "ix86_match_ccmode (insn, CCNOmode)
8823    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8824   "or{b}\t{%2, %0|%0, %2}"
8825   [(set_attr "type" "alu")
8826    (set_attr "mode" "QI")])
8827
8828 (define_insn "iorqi_ext_0"
8829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8830                          (const_int 8)
8831                          (const_int 8))
8832         (ior:SI 
8833           (zero_extract:SI
8834             (match_operand 1 "ext_register_operand" "0")
8835             (const_int 8)
8836             (const_int 8))
8837           (match_operand 2 "const_int_operand" "n")))
8838    (clobber (reg:CC FLAGS_REG))]
8839   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8840   "or{b}\t{%2, %h0|%h0, %2}"
8841   [(set_attr "type" "alu")
8842    (set_attr "length_immediate" "1")
8843    (set_attr "mode" "QI")])
8844
8845 (define_insn "*iorqi_ext_1"
8846   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8847                          (const_int 8)
8848                          (const_int 8))
8849         (ior:SI 
8850           (zero_extract:SI
8851             (match_operand 1 "ext_register_operand" "0")
8852             (const_int 8)
8853             (const_int 8))
8854           (zero_extend:SI
8855             (match_operand:QI 2 "general_operand" "Qm"))))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "!TARGET_64BIT
8858    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8859   "or{b}\t{%2, %h0|%h0, %2}"
8860   [(set_attr "type" "alu")
8861    (set_attr "length_immediate" "0")
8862    (set_attr "mode" "QI")])
8863
8864 (define_insn "*iorqi_ext_1_rex64"
8865   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8866                          (const_int 8)
8867                          (const_int 8))
8868         (ior:SI 
8869           (zero_extract:SI
8870             (match_operand 1 "ext_register_operand" "0")
8871             (const_int 8)
8872             (const_int 8))
8873           (zero_extend:SI
8874             (match_operand 2 "ext_register_operand" "Q"))))
8875    (clobber (reg:CC FLAGS_REG))]
8876   "TARGET_64BIT
8877    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8878   "or{b}\t{%2, %h0|%h0, %2}"
8879   [(set_attr "type" "alu")
8880    (set_attr "length_immediate" "0")
8881    (set_attr "mode" "QI")])
8882
8883 (define_insn "*iorqi_ext_2"
8884   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8885                          (const_int 8)
8886                          (const_int 8))
8887         (ior:SI 
8888           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8889                            (const_int 8)
8890                            (const_int 8))
8891           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8892                            (const_int 8)
8893                            (const_int 8))))
8894    (clobber (reg:CC FLAGS_REG))]
8895   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8896   "ior{b}\t{%h2, %h0|%h0, %h2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "length_immediate" "0")
8899    (set_attr "mode" "QI")])
8900
8901 (define_split
8902   [(set (match_operand 0 "register_operand" "")
8903         (ior (match_operand 1 "register_operand" "")
8904              (match_operand 2 "const_int_operand" "")))
8905    (clobber (reg:CC FLAGS_REG))]
8906    "reload_completed
8907     && QI_REG_P (operands[0])
8908     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8909     && !(INTVAL (operands[2]) & ~(255 << 8))
8910     && GET_MODE (operands[0]) != QImode"
8911   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8912                    (ior:SI (zero_extract:SI (match_dup 1)
8913                                             (const_int 8) (const_int 8))
8914                            (match_dup 2)))
8915               (clobber (reg:CC FLAGS_REG))])]
8916   "operands[0] = gen_lowpart (SImode, operands[0]);
8917    operands[1] = gen_lowpart (SImode, operands[1]);
8918    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8919
8920 ;; Since OR can be encoded with sign extended immediate, this is only
8921 ;; profitable when 7th bit is set.
8922 (define_split
8923   [(set (match_operand 0 "register_operand" "")
8924         (ior (match_operand 1 "general_operand" "")
8925              (match_operand 2 "const_int_operand" "")))
8926    (clobber (reg:CC FLAGS_REG))]
8927    "reload_completed
8928     && ANY_QI_REG_P (operands[0])
8929     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8930     && !(INTVAL (operands[2]) & ~255)
8931     && (INTVAL (operands[2]) & 128)
8932     && GET_MODE (operands[0]) != QImode"
8933   [(parallel [(set (strict_low_part (match_dup 0))
8934                    (ior:QI (match_dup 1)
8935                            (match_dup 2)))
8936               (clobber (reg:CC FLAGS_REG))])]
8937   "operands[0] = gen_lowpart (QImode, operands[0]);
8938    operands[1] = gen_lowpart (QImode, operands[1]);
8939    operands[2] = gen_lowpart (QImode, operands[2]);")
8940 \f
8941 ;; Logical XOR instructions
8942
8943 ;; %%% This used to optimize known byte-wide and operations to memory.
8944 ;; If this is considered useful, it should be done with splitters.
8945
8946 (define_expand "xordi3"
8947   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8948         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8949                 (match_operand:DI 2 "x86_64_general_operand" "")))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "TARGET_64BIT"
8952   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8953
8954 (define_insn "*xordi_1_rex64"
8955   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8956         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8957                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8958    (clobber (reg:CC FLAGS_REG))]
8959   "TARGET_64BIT
8960    && ix86_binary_operator_ok (XOR, DImode, operands)"
8961   "@
8962    xor{q}\t{%2, %0|%0, %2}
8963    xor{q}\t{%2, %0|%0, %2}"
8964   [(set_attr "type" "alu")
8965    (set_attr "mode" "DI,DI")])
8966
8967 (define_insn "*xordi_2_rex64"
8968   [(set (reg FLAGS_REG)
8969         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8970                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8971                  (const_int 0)))
8972    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8973         (xor:DI (match_dup 1) (match_dup 2)))]
8974   "TARGET_64BIT
8975    && ix86_match_ccmode (insn, CCNOmode)
8976    && ix86_binary_operator_ok (XOR, DImode, operands)"
8977   "@
8978    xor{q}\t{%2, %0|%0, %2}
8979    xor{q}\t{%2, %0|%0, %2}"
8980   [(set_attr "type" "alu")
8981    (set_attr "mode" "DI,DI")])
8982
8983 (define_insn "*xordi_3_rex64"
8984   [(set (reg FLAGS_REG)
8985         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8986                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8987                  (const_int 0)))
8988    (clobber (match_scratch:DI 0 "=r"))]
8989   "TARGET_64BIT
8990    && ix86_match_ccmode (insn, CCNOmode)
8991    && ix86_binary_operator_ok (XOR, DImode, operands)"
8992   "xor{q}\t{%2, %0|%0, %2}"
8993   [(set_attr "type" "alu")
8994    (set_attr "mode" "DI")])
8995
8996 (define_expand "xorsi3"
8997   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8998         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8999                 (match_operand:SI 2 "general_operand" "")))
9000    (clobber (reg:CC FLAGS_REG))]
9001   ""
9002   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9003
9004 (define_insn "*xorsi_1"
9005   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9006         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9007                 (match_operand:SI 2 "general_operand" "ri,rm")))
9008    (clobber (reg:CC FLAGS_REG))]
9009   "ix86_binary_operator_ok (XOR, SImode, operands)"
9010   "xor{l}\t{%2, %0|%0, %2}"
9011   [(set_attr "type" "alu")
9012    (set_attr "mode" "SI")])
9013
9014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9015 ;; Add speccase for immediates
9016 (define_insn "*xorsi_1_zext"
9017   [(set (match_operand:DI 0 "register_operand" "=r")
9018         (zero_extend:DI
9019           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9020                   (match_operand:SI 2 "general_operand" "rim"))))
9021    (clobber (reg:CC FLAGS_REG))]
9022   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9023   "xor{l}\t{%2, %k0|%k0, %2}"
9024   [(set_attr "type" "alu")
9025    (set_attr "mode" "SI")])
9026
9027 (define_insn "*xorsi_1_zext_imm"
9028   [(set (match_operand:DI 0 "register_operand" "=r")
9029         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9030                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9031    (clobber (reg:CC FLAGS_REG))]
9032   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9033   "xor{l}\t{%2, %k0|%k0, %2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "mode" "SI")])
9036
9037 (define_insn "*xorsi_2"
9038   [(set (reg FLAGS_REG)
9039         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9040                          (match_operand:SI 2 "general_operand" "rim,ri"))
9041                  (const_int 0)))
9042    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9043         (xor:SI (match_dup 1) (match_dup 2)))]
9044   "ix86_match_ccmode (insn, CCNOmode)
9045    && ix86_binary_operator_ok (XOR, SImode, operands)"
9046   "xor{l}\t{%2, %0|%0, %2}"
9047   [(set_attr "type" "alu")
9048    (set_attr "mode" "SI")])
9049
9050 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9051 ;; ??? Special case for immediate operand is missing - it is tricky.
9052 (define_insn "*xorsi_2_zext"
9053   [(set (reg FLAGS_REG)
9054         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055                          (match_operand:SI 2 "general_operand" "rim"))
9056                  (const_int 0)))
9057    (set (match_operand:DI 0 "register_operand" "=r")
9058         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9059   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9060    && ix86_binary_operator_ok (XOR, SImode, operands)"
9061   "xor{l}\t{%2, %k0|%k0, %2}"
9062   [(set_attr "type" "alu")
9063    (set_attr "mode" "SI")])
9064
9065 (define_insn "*xorsi_2_zext_imm"
9066   [(set (reg FLAGS_REG)
9067         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9068                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9069                  (const_int 0)))
9070    (set (match_operand:DI 0 "register_operand" "=r")
9071         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9072   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9073    && ix86_binary_operator_ok (XOR, SImode, operands)"
9074   "xor{l}\t{%2, %k0|%k0, %2}"
9075   [(set_attr "type" "alu")
9076    (set_attr "mode" "SI")])
9077
9078 (define_insn "*xorsi_3"
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    (clobber (match_scratch:SI 0 "=r"))]
9084   "ix86_match_ccmode (insn, CCNOmode)
9085    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9086   "xor{l}\t{%2, %0|%0, %2}"
9087   [(set_attr "type" "alu")
9088    (set_attr "mode" "SI")])
9089
9090 (define_expand "xorhi3"
9091   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9092         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9093                 (match_operand:HI 2 "general_operand" "")))
9094    (clobber (reg:CC FLAGS_REG))]
9095   "TARGET_HIMODE_MATH"
9096   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9097
9098 (define_insn "*xorhi_1"
9099   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9100         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9101                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9102    (clobber (reg:CC FLAGS_REG))]
9103   "ix86_binary_operator_ok (XOR, HImode, operands)"
9104   "xor{w}\t{%2, %0|%0, %2}"
9105   [(set_attr "type" "alu")
9106    (set_attr "mode" "HI")])
9107
9108 (define_insn "*xorhi_2"
9109   [(set (reg FLAGS_REG)
9110         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9111                          (match_operand:HI 2 "general_operand" "rim,ri"))
9112                  (const_int 0)))
9113    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9114         (xor:HI (match_dup 1) (match_dup 2)))]
9115   "ix86_match_ccmode (insn, CCNOmode)
9116    && ix86_binary_operator_ok (XOR, HImode, operands)"
9117   "xor{w}\t{%2, %0|%0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "mode" "HI")])
9120
9121 (define_insn "*xorhi_3"
9122   [(set (reg FLAGS_REG)
9123         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9124                          (match_operand:HI 2 "general_operand" "rim"))
9125                  (const_int 0)))
9126    (clobber (match_scratch:HI 0 "=r"))]
9127   "ix86_match_ccmode (insn, CCNOmode)
9128    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9129   "xor{w}\t{%2, %0|%0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "HI")])
9132
9133 (define_expand "xorqi3"
9134   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9135         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9136                 (match_operand:QI 2 "general_operand" "")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "TARGET_QIMODE_MATH"
9139   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9140
9141 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9142 (define_insn "*xorqi_1"
9143   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9144         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9145                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "ix86_binary_operator_ok (XOR, QImode, operands)"
9148   "@
9149    xor{b}\t{%2, %0|%0, %2}
9150    xor{b}\t{%2, %0|%0, %2}
9151    xor{l}\t{%k2, %k0|%k0, %k2}"
9152   [(set_attr "type" "alu")
9153    (set_attr "mode" "QI,QI,SI")])
9154
9155 (define_insn "*xorqi_1_slp"
9156   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9157         (xor:QI (match_dup 0)
9158                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9159    (clobber (reg:CC FLAGS_REG))]
9160   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9161    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9162   "xor{b}\t{%1, %0|%0, %1}"
9163   [(set_attr "type" "alu1")
9164    (set_attr "mode" "QI")])
9165
9166 (define_insn "xorqi_ext_0"
9167   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9168                          (const_int 8)
9169                          (const_int 8))
9170         (xor:SI 
9171           (zero_extract:SI
9172             (match_operand 1 "ext_register_operand" "0")
9173             (const_int 8)
9174             (const_int 8))
9175           (match_operand 2 "const_int_operand" "n")))
9176    (clobber (reg:CC FLAGS_REG))]
9177   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9178   "xor{b}\t{%2, %h0|%h0, %2}"
9179   [(set_attr "type" "alu")
9180    (set_attr "length_immediate" "1")
9181    (set_attr "mode" "QI")])
9182
9183 (define_insn "*xorqi_ext_1"
9184   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9185                          (const_int 8)
9186                          (const_int 8))
9187         (xor:SI 
9188           (zero_extract:SI
9189             (match_operand 1 "ext_register_operand" "0")
9190             (const_int 8)
9191             (const_int 8))
9192           (zero_extend:SI
9193             (match_operand:QI 2 "general_operand" "Qm"))))
9194    (clobber (reg:CC FLAGS_REG))]
9195   "!TARGET_64BIT
9196    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9197   "xor{b}\t{%2, %h0|%h0, %2}"
9198   [(set_attr "type" "alu")
9199    (set_attr "length_immediate" "0")
9200    (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_ext_1_rex64"
9203   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9204                          (const_int 8)
9205                          (const_int 8))
9206         (xor:SI 
9207           (zero_extract:SI
9208             (match_operand 1 "ext_register_operand" "0")
9209             (const_int 8)
9210             (const_int 8))
9211           (zero_extend:SI
9212             (match_operand 2 "ext_register_operand" "Q"))))
9213    (clobber (reg:CC FLAGS_REG))]
9214   "TARGET_64BIT
9215    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9216   "xor{b}\t{%2, %h0|%h0, %2}"
9217   [(set_attr "type" "alu")
9218    (set_attr "length_immediate" "0")
9219    (set_attr "mode" "QI")])
9220
9221 (define_insn "*xorqi_ext_2"
9222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9223                          (const_int 8)
9224                          (const_int 8))
9225         (xor:SI 
9226           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9227                            (const_int 8)
9228                            (const_int 8))
9229           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9230                            (const_int 8)
9231                            (const_int 8))))
9232    (clobber (reg:CC FLAGS_REG))]
9233   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9234   "xor{b}\t{%h2, %h0|%h0, %h2}"
9235   [(set_attr "type" "alu")
9236    (set_attr "length_immediate" "0")
9237    (set_attr "mode" "QI")])
9238
9239 (define_insn "*xorqi_cc_1"
9240   [(set (reg FLAGS_REG)
9241         (compare
9242           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9243                   (match_operand:QI 2 "general_operand" "qim,qi"))
9244           (const_int 0)))
9245    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9246         (xor:QI (match_dup 1) (match_dup 2)))]
9247   "ix86_match_ccmode (insn, CCNOmode)
9248    && ix86_binary_operator_ok (XOR, QImode, operands)"
9249   "xor{b}\t{%2, %0|%0, %2}"
9250   [(set_attr "type" "alu")
9251    (set_attr "mode" "QI")])
9252
9253 (define_insn "*xorqi_2_slp"
9254   [(set (reg FLAGS_REG)
9255         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9256                          (match_operand:QI 1 "general_operand" "qim,qi"))
9257                  (const_int 0)))
9258    (set (strict_low_part (match_dup 0))
9259         (xor:QI (match_dup 0) (match_dup 1)))]
9260   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9261    && ix86_match_ccmode (insn, CCNOmode)
9262    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9263   "xor{b}\t{%1, %0|%0, %1}"
9264   [(set_attr "type" "alu1")
9265    (set_attr "mode" "QI")])
9266
9267 (define_insn "*xorqi_cc_2"
9268   [(set (reg FLAGS_REG)
9269         (compare
9270           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9271                   (match_operand:QI 2 "general_operand" "qim"))
9272           (const_int 0)))
9273    (clobber (match_scratch:QI 0 "=q"))]
9274   "ix86_match_ccmode (insn, CCNOmode)
9275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9276   "xor{b}\t{%2, %0|%0, %2}"
9277   [(set_attr "type" "alu")
9278    (set_attr "mode" "QI")])
9279
9280 (define_insn "*xorqi_cc_ext_1"
9281   [(set (reg FLAGS_REG)
9282         (compare
9283           (xor:SI
9284             (zero_extract:SI
9285               (match_operand 1 "ext_register_operand" "0")
9286               (const_int 8)
9287               (const_int 8))
9288             (match_operand:QI 2 "general_operand" "qmn"))
9289           (const_int 0)))
9290    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9291                          (const_int 8)
9292                          (const_int 8))
9293         (xor:SI 
9294           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9295           (match_dup 2)))]
9296   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9297   "xor{b}\t{%2, %h0|%h0, %2}"
9298   [(set_attr "type" "alu")
9299    (set_attr "mode" "QI")])
9300
9301 (define_insn "*xorqi_cc_ext_1_rex64"
9302   [(set (reg FLAGS_REG)
9303         (compare
9304           (xor:SI
9305             (zero_extract:SI
9306               (match_operand 1 "ext_register_operand" "0")
9307               (const_int 8)
9308               (const_int 8))
9309             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9310           (const_int 0)))
9311    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9312                          (const_int 8)
9313                          (const_int 8))
9314         (xor:SI 
9315           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9316           (match_dup 2)))]
9317   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9318   "xor{b}\t{%2, %h0|%h0, %2}"
9319   [(set_attr "type" "alu")
9320    (set_attr "mode" "QI")])
9321
9322 (define_expand "xorqi_cc_ext_1"
9323   [(parallel [
9324      (set (reg:CCNO FLAGS_REG)
9325           (compare:CCNO
9326             (xor:SI
9327               (zero_extract:SI
9328                 (match_operand 1 "ext_register_operand" "")
9329                 (const_int 8)
9330                 (const_int 8))
9331               (match_operand:QI 2 "general_operand" ""))
9332             (const_int 0)))
9333      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9334                            (const_int 8)
9335                            (const_int 8))
9336           (xor:SI 
9337             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9338             (match_dup 2)))])]
9339   ""
9340   "")
9341
9342 (define_split
9343   [(set (match_operand 0 "register_operand" "")
9344         (xor (match_operand 1 "register_operand" "")
9345              (match_operand 2 "const_int_operand" "")))
9346    (clobber (reg:CC FLAGS_REG))]
9347    "reload_completed
9348     && QI_REG_P (operands[0])
9349     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9350     && !(INTVAL (operands[2]) & ~(255 << 8))
9351     && GET_MODE (operands[0]) != QImode"
9352   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9353                    (xor:SI (zero_extract:SI (match_dup 1)
9354                                             (const_int 8) (const_int 8))
9355                            (match_dup 2)))
9356               (clobber (reg:CC FLAGS_REG))])]
9357   "operands[0] = gen_lowpart (SImode, operands[0]);
9358    operands[1] = gen_lowpart (SImode, operands[1]);
9359    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9360
9361 ;; Since XOR can be encoded with sign extended immediate, this is only
9362 ;; profitable when 7th bit is set.
9363 (define_split
9364   [(set (match_operand 0 "register_operand" "")
9365         (xor (match_operand 1 "general_operand" "")
9366              (match_operand 2 "const_int_operand" "")))
9367    (clobber (reg:CC FLAGS_REG))]
9368    "reload_completed
9369     && ANY_QI_REG_P (operands[0])
9370     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9371     && !(INTVAL (operands[2]) & ~255)
9372     && (INTVAL (operands[2]) & 128)
9373     && GET_MODE (operands[0]) != QImode"
9374   [(parallel [(set (strict_low_part (match_dup 0))
9375                    (xor:QI (match_dup 1)
9376                            (match_dup 2)))
9377               (clobber (reg:CC FLAGS_REG))])]
9378   "operands[0] = gen_lowpart (QImode, operands[0]);
9379    operands[1] = gen_lowpart (QImode, operands[1]);
9380    operands[2] = gen_lowpart (QImode, operands[2]);")
9381 \f
9382 ;; Negation instructions
9383
9384 (define_expand "negdi2"
9385   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9386                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9387               (clobber (reg:CC FLAGS_REG))])]
9388   ""
9389   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9390
9391 (define_insn "*negdi2_1"
9392   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9393         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "!TARGET_64BIT
9396    && ix86_unary_operator_ok (NEG, DImode, operands)"
9397   "#")
9398
9399 (define_split
9400   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9401         (neg:DI (match_operand:DI 1 "general_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "!TARGET_64BIT && reload_completed"
9404   [(parallel
9405     [(set (reg:CCZ FLAGS_REG)
9406           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9407      (set (match_dup 0) (neg:SI (match_dup 2)))])
9408    (parallel
9409     [(set (match_dup 1)
9410           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9411                             (match_dup 3))
9412                    (const_int 0)))
9413      (clobber (reg:CC FLAGS_REG))])
9414    (parallel
9415     [(set (match_dup 1)
9416           (neg:SI (match_dup 1)))
9417      (clobber (reg:CC FLAGS_REG))])]
9418   "split_di (operands+1, 1, operands+2, operands+3);
9419    split_di (operands+0, 1, operands+0, operands+1);")
9420
9421 (define_insn "*negdi2_1_rex64"
9422   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9423         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9424    (clobber (reg:CC FLAGS_REG))]
9425   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9426   "neg{q}\t%0"
9427   [(set_attr "type" "negnot")
9428    (set_attr "mode" "DI")])
9429
9430 ;; The problem with neg is that it does not perform (compare x 0),
9431 ;; it really performs (compare 0 x), which leaves us with the zero
9432 ;; flag being the only useful item.
9433
9434 (define_insn "*negdi2_cmpz_rex64"
9435   [(set (reg:CCZ FLAGS_REG)
9436         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9437                      (const_int 0)))
9438    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9439         (neg:DI (match_dup 1)))]
9440   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9441   "neg{q}\t%0"
9442   [(set_attr "type" "negnot")
9443    (set_attr "mode" "DI")])
9444
9445
9446 (define_expand "negsi2"
9447   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9448                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9449               (clobber (reg:CC FLAGS_REG))])]
9450   ""
9451   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9452
9453 (define_insn "*negsi2_1"
9454   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9455         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9456    (clobber (reg:CC FLAGS_REG))]
9457   "ix86_unary_operator_ok (NEG, SImode, operands)"
9458   "neg{l}\t%0"
9459   [(set_attr "type" "negnot")
9460    (set_attr "mode" "SI")])
9461
9462 ;; Combine is quite creative about this pattern.
9463 (define_insn "*negsi2_1_zext"
9464   [(set (match_operand:DI 0 "register_operand" "=r")
9465         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9466                                         (const_int 32)))
9467                      (const_int 32)))
9468    (clobber (reg:CC FLAGS_REG))]
9469   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9470   "neg{l}\t%k0"
9471   [(set_attr "type" "negnot")
9472    (set_attr "mode" "SI")])
9473
9474 ;; The problem with neg is that it does not perform (compare x 0),
9475 ;; it really performs (compare 0 x), which leaves us with the zero
9476 ;; flag being the only useful item.
9477
9478 (define_insn "*negsi2_cmpz"
9479   [(set (reg:CCZ FLAGS_REG)
9480         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9481                      (const_int 0)))
9482    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9483         (neg:SI (match_dup 1)))]
9484   "ix86_unary_operator_ok (NEG, SImode, operands)"
9485   "neg{l}\t%0"
9486   [(set_attr "type" "negnot")
9487    (set_attr "mode" "SI")])
9488
9489 (define_insn "*negsi2_cmpz_zext"
9490   [(set (reg:CCZ FLAGS_REG)
9491         (compare:CCZ (lshiftrt:DI
9492                        (neg:DI (ashift:DI
9493                                  (match_operand:DI 1 "register_operand" "0")
9494                                  (const_int 32)))
9495                        (const_int 32))
9496                      (const_int 0)))
9497    (set (match_operand:DI 0 "register_operand" "=r")
9498         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9499                                         (const_int 32)))
9500                      (const_int 32)))]
9501   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9502   "neg{l}\t%k0"
9503   [(set_attr "type" "negnot")
9504    (set_attr "mode" "SI")])
9505
9506 (define_expand "neghi2"
9507   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9508                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9509               (clobber (reg:CC FLAGS_REG))])]
9510   "TARGET_HIMODE_MATH"
9511   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9512
9513 (define_insn "*neghi2_1"
9514   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9515         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9516    (clobber (reg:CC FLAGS_REG))]
9517   "ix86_unary_operator_ok (NEG, HImode, operands)"
9518   "neg{w}\t%0"
9519   [(set_attr "type" "negnot")
9520    (set_attr "mode" "HI")])
9521
9522 (define_insn "*neghi2_cmpz"
9523   [(set (reg:CCZ FLAGS_REG)
9524         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9525                      (const_int 0)))
9526    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9527         (neg:HI (match_dup 1)))]
9528   "ix86_unary_operator_ok (NEG, HImode, operands)"
9529   "neg{w}\t%0"
9530   [(set_attr "type" "negnot")
9531    (set_attr "mode" "HI")])
9532
9533 (define_expand "negqi2"
9534   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9535                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9536               (clobber (reg:CC FLAGS_REG))])]
9537   "TARGET_QIMODE_MATH"
9538   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9539
9540 (define_insn "*negqi2_1"
9541   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9542         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "ix86_unary_operator_ok (NEG, QImode, operands)"
9545   "neg{b}\t%0"
9546   [(set_attr "type" "negnot")
9547    (set_attr "mode" "QI")])
9548
9549 (define_insn "*negqi2_cmpz"
9550   [(set (reg:CCZ FLAGS_REG)
9551         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9552                      (const_int 0)))
9553    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9554         (neg:QI (match_dup 1)))]
9555   "ix86_unary_operator_ok (NEG, QImode, operands)"
9556   "neg{b}\t%0"
9557   [(set_attr "type" "negnot")
9558    (set_attr "mode" "QI")])
9559
9560 ;; Changing of sign for FP values is doable using integer unit too.
9561
9562 (define_expand "negsf2"
9563   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9564         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9565   "TARGET_80387 || TARGET_SSE_MATH"
9566   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9567
9568 (define_expand "abssf2"
9569   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9570         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9571   "TARGET_80387 || TARGET_SSE_MATH"
9572   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9573
9574 (define_insn "*absnegsf2_mixed"
9575   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9576         (match_operator:SF 3 "absneg_operator"
9577           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9578    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9579    (clobber (reg:CC FLAGS_REG))]
9580   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9581    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9582   "#")
9583
9584 (define_insn "*absnegsf2_sse"
9585   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9586         (match_operator:SF 3 "absneg_operator"
9587           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9588    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9589    (clobber (reg:CC FLAGS_REG))]
9590   "TARGET_SSE_MATH
9591    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9592   "#")
9593
9594 (define_insn "*absnegsf2_i387"
9595   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9596         (match_operator:SF 3 "absneg_operator"
9597           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9598    (use (match_operand 2 "" ""))
9599    (clobber (reg:CC FLAGS_REG))]
9600   "TARGET_80387 && !TARGET_SSE_MATH
9601    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9602   "#")
9603
9604 (define_expand "negdf2"
9605   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9606         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9607   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9608   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9609
9610 (define_expand "absdf2"
9611   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9612         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9613   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9614   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9615
9616 (define_insn "*absnegdf2_mixed"
9617   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9618         (match_operator:DF 3 "absneg_operator"
9619           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9620    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9621    (clobber (reg:CC FLAGS_REG))]
9622   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9623    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9624   "#")
9625
9626 (define_insn "*absnegdf2_sse"
9627   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9628         (match_operator:DF 3 "absneg_operator"
9629           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9630    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9631    (clobber (reg:CC FLAGS_REG))]
9632   "TARGET_SSE2 && TARGET_SSE_MATH
9633    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9634   "#")
9635
9636 (define_insn "*absnegdf2_i387"
9637   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9638         (match_operator:DF 3 "absneg_operator"
9639           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9640    (use (match_operand 2 "" ""))
9641    (clobber (reg:CC FLAGS_REG))]
9642   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9643    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9644   "#")
9645
9646 (define_expand "negxf2"
9647   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9648         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9649   "TARGET_80387"
9650   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9651
9652 (define_expand "absxf2"
9653   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9654         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9655   "TARGET_80387"
9656   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9657
9658 (define_insn "*absnegxf2_i387"
9659   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9660         (match_operator:XF 3 "absneg_operator"
9661           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9662    (use (match_operand 2 "" ""))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "TARGET_80387
9665    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9666   "#")
9667
9668 ;; Splitters for fp abs and neg.
9669
9670 (define_split
9671   [(set (match_operand 0 "fp_register_operand" "")
9672         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9673    (use (match_operand 2 "" ""))
9674    (clobber (reg:CC FLAGS_REG))]
9675   "reload_completed"
9676   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9677
9678 (define_split
9679   [(set (match_operand 0 "register_operand" "")
9680         (match_operator 3 "absneg_operator"
9681           [(match_operand 1 "register_operand" "")]))
9682    (use (match_operand 2 "nonimmediate_operand" ""))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "reload_completed && SSE_REG_P (operands[0])"
9685   [(set (match_dup 0) (match_dup 3))]
9686 {
9687   enum machine_mode mode = GET_MODE (operands[0]);
9688   enum machine_mode vmode = GET_MODE (operands[2]);
9689   rtx tmp;
9690   
9691   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9692   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9693   if (operands_match_p (operands[0], operands[2]))
9694     {
9695       tmp = operands[1];
9696       operands[1] = operands[2];
9697       operands[2] = tmp;
9698     }
9699   if (GET_CODE (operands[3]) == ABS)
9700     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9701   else
9702     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9703   operands[3] = tmp;
9704 })
9705
9706 (define_split
9707   [(set (match_operand:SF 0 "register_operand" "")
9708         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9709    (use (match_operand:V4SF 2 "" ""))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "reload_completed"
9712   [(parallel [(set (match_dup 0) (match_dup 1))
9713               (clobber (reg:CC FLAGS_REG))])]
9714
9715   rtx tmp;
9716   operands[0] = gen_lowpart (SImode, operands[0]);
9717   if (GET_CODE (operands[1]) == ABS)
9718     {
9719       tmp = gen_int_mode (0x7fffffff, SImode);
9720       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9721     }
9722   else
9723     {
9724       tmp = gen_int_mode (0x80000000, SImode);
9725       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9726     }
9727   operands[1] = tmp;
9728 })
9729
9730 (define_split
9731   [(set (match_operand:DF 0 "register_operand" "")
9732         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9733    (use (match_operand 2 "" ""))
9734    (clobber (reg:CC FLAGS_REG))]
9735   "reload_completed"
9736   [(parallel [(set (match_dup 0) (match_dup 1))
9737               (clobber (reg:CC FLAGS_REG))])]
9738 {
9739   rtx tmp;
9740   if (TARGET_64BIT)
9741     {
9742       tmp = gen_lowpart (DImode, operands[0]);
9743       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9744       operands[0] = tmp;
9745
9746       if (GET_CODE (operands[1]) == ABS)
9747         tmp = const0_rtx;
9748       else
9749         tmp = gen_rtx_NOT (DImode, tmp);
9750     }
9751   else
9752     {
9753       operands[0] = gen_highpart (SImode, operands[0]);
9754       if (GET_CODE (operands[1]) == ABS)
9755         {
9756           tmp = gen_int_mode (0x7fffffff, SImode);
9757           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9758         }
9759       else
9760         {
9761           tmp = gen_int_mode (0x80000000, SImode);
9762           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9763         }
9764     }
9765   operands[1] = tmp;
9766 })
9767
9768 (define_split
9769   [(set (match_operand:XF 0 "register_operand" "")
9770         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9771    (use (match_operand 2 "" ""))
9772    (clobber (reg:CC FLAGS_REG))]
9773   "reload_completed"
9774   [(parallel [(set (match_dup 0) (match_dup 1))
9775               (clobber (reg:CC FLAGS_REG))])]
9776 {
9777   rtx tmp;
9778   operands[0] = gen_rtx_REG (SImode,
9779                              true_regnum (operands[0])
9780                              + (TARGET_64BIT ? 1 : 2));
9781   if (GET_CODE (operands[1]) == ABS)
9782     {
9783       tmp = GEN_INT (0x7fff);
9784       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9785     }
9786   else
9787     {
9788       tmp = GEN_INT (0x8000);
9789       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9790     }
9791   operands[1] = tmp;
9792 })
9793
9794 (define_split
9795   [(set (match_operand 0 "memory_operand" "")
9796         (match_operator 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   enum machine_mode mode = GET_MODE (operands[0]);
9804   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9805   rtx tmp;
9806
9807   operands[0] = adjust_address (operands[0], QImode, size - 1);
9808   if (GET_CODE (operands[1]) == ABS)
9809     {
9810       tmp = gen_int_mode (0x7f, QImode);
9811       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9812     }
9813   else
9814     {
9815       tmp = gen_int_mode (0x80, QImode);
9816       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9817     }
9818   operands[1] = tmp;
9819 })
9820
9821 ;; Conditionalize these after reload. If they match before reload, we 
9822 ;; lose the clobber and ability to use integer instructions.
9823
9824 (define_insn "*negsf2_1"
9825   [(set (match_operand:SF 0 "register_operand" "=f")
9826         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9827   "TARGET_80387 && reload_completed"
9828   "fchs"
9829   [(set_attr "type" "fsgn")
9830    (set_attr "mode" "SF")])
9831
9832 (define_insn "*negdf2_1"
9833   [(set (match_operand:DF 0 "register_operand" "=f")
9834         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9835   "TARGET_80387 && reload_completed"
9836   "fchs"
9837   [(set_attr "type" "fsgn")
9838    (set_attr "mode" "DF")])
9839
9840 (define_insn "*negxf2_1"
9841   [(set (match_operand:XF 0 "register_operand" "=f")
9842         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9843   "TARGET_80387 && reload_completed"
9844   "fchs"
9845   [(set_attr "type" "fsgn")
9846    (set_attr "mode" "XF")])
9847
9848 (define_insn "*abssf2_1"
9849   [(set (match_operand:SF 0 "register_operand" "=f")
9850         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9851   "TARGET_80387 && reload_completed"
9852   "fabs"
9853   [(set_attr "type" "fsgn")
9854    (set_attr "mode" "SF")])
9855
9856 (define_insn "*absdf2_1"
9857   [(set (match_operand:DF 0 "register_operand" "=f")
9858         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9859   "TARGET_80387 && reload_completed"
9860   "fabs"
9861   [(set_attr "type" "fsgn")
9862    (set_attr "mode" "DF")])
9863
9864 (define_insn "*absxf2_1"
9865   [(set (match_operand:XF 0 "register_operand" "=f")
9866         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9867   "TARGET_80387 && reload_completed"
9868   "fabs"
9869   [(set_attr "type" "fsgn")
9870    (set_attr "mode" "DF")])
9871
9872 (define_insn "*negextendsfdf2"
9873   [(set (match_operand:DF 0 "register_operand" "=f")
9874         (neg:DF (float_extend:DF
9875                   (match_operand:SF 1 "register_operand" "0"))))]
9876   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9877   "fchs"
9878   [(set_attr "type" "fsgn")
9879    (set_attr "mode" "DF")])
9880
9881 (define_insn "*negextenddfxf2"
9882   [(set (match_operand:XF 0 "register_operand" "=f")
9883         (neg:XF (float_extend:XF
9884                   (match_operand:DF 1 "register_operand" "0"))))]
9885   "TARGET_80387"
9886   "fchs"
9887   [(set_attr "type" "fsgn")
9888    (set_attr "mode" "XF")])
9889
9890 (define_insn "*negextendsfxf2"
9891   [(set (match_operand:XF 0 "register_operand" "=f")
9892         (neg:XF (float_extend:XF
9893                   (match_operand:SF 1 "register_operand" "0"))))]
9894   "TARGET_80387"
9895   "fchs"
9896   [(set_attr "type" "fsgn")
9897    (set_attr "mode" "XF")])
9898
9899 (define_insn "*absextendsfdf2"
9900   [(set (match_operand:DF 0 "register_operand" "=f")
9901         (abs:DF (float_extend:DF
9902                   (match_operand:SF 1 "register_operand" "0"))))]
9903   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9904   "fabs"
9905   [(set_attr "type" "fsgn")
9906    (set_attr "mode" "DF")])
9907
9908 (define_insn "*absextenddfxf2"
9909   [(set (match_operand:XF 0 "register_operand" "=f")
9910         (abs:XF (float_extend:XF
9911           (match_operand:DF 1 "register_operand" "0"))))]
9912   "TARGET_80387"
9913   "fabs"
9914   [(set_attr "type" "fsgn")
9915    (set_attr "mode" "XF")])
9916
9917 (define_insn "*absextendsfxf2"
9918   [(set (match_operand:XF 0 "register_operand" "=f")
9919         (abs:XF (float_extend:XF
9920           (match_operand:SF 1 "register_operand" "0"))))]
9921   "TARGET_80387"
9922   "fabs"
9923   [(set_attr "type" "fsgn")
9924    (set_attr "mode" "XF")])
9925 \f
9926 ;; One complement instructions
9927
9928 (define_expand "one_cmpldi2"
9929   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9930         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9931   "TARGET_64BIT"
9932   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9933
9934 (define_insn "*one_cmpldi2_1_rex64"
9935   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9936         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9937   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9938   "not{q}\t%0"
9939   [(set_attr "type" "negnot")
9940    (set_attr "mode" "DI")])
9941
9942 (define_insn "*one_cmpldi2_2_rex64"
9943   [(set (reg FLAGS_REG)
9944         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9945                  (const_int 0)))
9946    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9947         (not:DI (match_dup 1)))]
9948   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9949    && ix86_unary_operator_ok (NOT, DImode, operands)"
9950   "#"
9951   [(set_attr "type" "alu1")
9952    (set_attr "mode" "DI")])
9953
9954 (define_split
9955   [(set (match_operand 0 "flags_reg_operand" "")
9956         (match_operator 2 "compare_operator"
9957           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9958            (const_int 0)]))
9959    (set (match_operand:DI 1 "nonimmediate_operand" "")
9960         (not:DI (match_dup 3)))]
9961   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9962   [(parallel [(set (match_dup 0)
9963                    (match_op_dup 2
9964                      [(xor:DI (match_dup 3) (const_int -1))
9965                       (const_int 0)]))
9966               (set (match_dup 1)
9967                    (xor:DI (match_dup 3) (const_int -1)))])]
9968   "")
9969
9970 (define_expand "one_cmplsi2"
9971   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9972         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9973   ""
9974   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9975
9976 (define_insn "*one_cmplsi2_1"
9977   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9978         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9979   "ix86_unary_operator_ok (NOT, SImode, operands)"
9980   "not{l}\t%0"
9981   [(set_attr "type" "negnot")
9982    (set_attr "mode" "SI")])
9983
9984 ;; ??? Currently never generated - xor is used instead.
9985 (define_insn "*one_cmplsi2_1_zext"
9986   [(set (match_operand:DI 0 "register_operand" "=r")
9987         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9988   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9989   "not{l}\t%k0"
9990   [(set_attr "type" "negnot")
9991    (set_attr "mode" "SI")])
9992
9993 (define_insn "*one_cmplsi2_2"
9994   [(set (reg FLAGS_REG)
9995         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9996                  (const_int 0)))
9997    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9998         (not:SI (match_dup 1)))]
9999   "ix86_match_ccmode (insn, CCNOmode)
10000    && ix86_unary_operator_ok (NOT, SImode, operands)"
10001   "#"
10002   [(set_attr "type" "alu1")
10003    (set_attr "mode" "SI")])
10004
10005 (define_split
10006   [(set (match_operand 0 "flags_reg_operand" "")
10007         (match_operator 2 "compare_operator"
10008           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10009            (const_int 0)]))
10010    (set (match_operand:SI 1 "nonimmediate_operand" "")
10011         (not:SI (match_dup 3)))]
10012   "ix86_match_ccmode (insn, CCNOmode)"
10013   [(parallel [(set (match_dup 0)
10014                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10015                                     (const_int 0)]))
10016               (set (match_dup 1)
10017                    (xor:SI (match_dup 3) (const_int -1)))])]
10018   "")
10019
10020 ;; ??? Currently never generated - xor is used instead.
10021 (define_insn "*one_cmplsi2_2_zext"
10022   [(set (reg FLAGS_REG)
10023         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10024                  (const_int 0)))
10025    (set (match_operand:DI 0 "register_operand" "=r")
10026         (zero_extend:DI (not:SI (match_dup 1))))]
10027   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10028    && ix86_unary_operator_ok (NOT, SImode, operands)"
10029   "#"
10030   [(set_attr "type" "alu1")
10031    (set_attr "mode" "SI")])
10032
10033 (define_split
10034   [(set (match_operand 0 "flags_reg_operand" "")
10035         (match_operator 2 "compare_operator"
10036           [(not:SI (match_operand:SI 3 "register_operand" ""))
10037            (const_int 0)]))
10038    (set (match_operand:DI 1 "register_operand" "")
10039         (zero_extend:DI (not:SI (match_dup 3))))]
10040   "ix86_match_ccmode (insn, CCNOmode)"
10041   [(parallel [(set (match_dup 0)
10042                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10043                                     (const_int 0)]))
10044               (set (match_dup 1)
10045                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10046   "")
10047
10048 (define_expand "one_cmplhi2"
10049   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10050         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10051   "TARGET_HIMODE_MATH"
10052   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10053
10054 (define_insn "*one_cmplhi2_1"
10055   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10056         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10057   "ix86_unary_operator_ok (NOT, HImode, operands)"
10058   "not{w}\t%0"
10059   [(set_attr "type" "negnot")
10060    (set_attr "mode" "HI")])
10061
10062 (define_insn "*one_cmplhi2_2"
10063   [(set (reg FLAGS_REG)
10064         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10065                  (const_int 0)))
10066    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10067         (not:HI (match_dup 1)))]
10068   "ix86_match_ccmode (insn, CCNOmode)
10069    && ix86_unary_operator_ok (NEG, HImode, operands)"
10070   "#"
10071   [(set_attr "type" "alu1")
10072    (set_attr "mode" "HI")])
10073
10074 (define_split
10075   [(set (match_operand 0 "flags_reg_operand" "")
10076         (match_operator 2 "compare_operator"
10077           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10078            (const_int 0)]))
10079    (set (match_operand:HI 1 "nonimmediate_operand" "")
10080         (not:HI (match_dup 3)))]
10081   "ix86_match_ccmode (insn, CCNOmode)"
10082   [(parallel [(set (match_dup 0)
10083                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10084                                     (const_int 0)]))
10085               (set (match_dup 1)
10086                    (xor:HI (match_dup 3) (const_int -1)))])]
10087   "")
10088
10089 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10090 (define_expand "one_cmplqi2"
10091   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10092         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10093   "TARGET_QIMODE_MATH"
10094   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10095
10096 (define_insn "*one_cmplqi2_1"
10097   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10098         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10099   "ix86_unary_operator_ok (NOT, QImode, operands)"
10100   "@
10101    not{b}\t%0
10102    not{l}\t%k0"
10103   [(set_attr "type" "negnot")
10104    (set_attr "mode" "QI,SI")])
10105
10106 (define_insn "*one_cmplqi2_2"
10107   [(set (reg FLAGS_REG)
10108         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10109                  (const_int 0)))
10110    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10111         (not:QI (match_dup 1)))]
10112   "ix86_match_ccmode (insn, CCNOmode)
10113    && ix86_unary_operator_ok (NOT, QImode, operands)"
10114   "#"
10115   [(set_attr "type" "alu1")
10116    (set_attr "mode" "QI")])
10117
10118 (define_split
10119   [(set (match_operand 0 "flags_reg_operand" "")
10120         (match_operator 2 "compare_operator"
10121           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10122            (const_int 0)]))
10123    (set (match_operand:QI 1 "nonimmediate_operand" "")
10124         (not:QI (match_dup 3)))]
10125   "ix86_match_ccmode (insn, CCNOmode)"
10126   [(parallel [(set (match_dup 0)
10127                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10128                                     (const_int 0)]))
10129               (set (match_dup 1)
10130                    (xor:QI (match_dup 3) (const_int -1)))])]
10131   "")
10132 \f
10133 ;; Arithmetic shift instructions
10134
10135 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10136 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10137 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10138 ;; from the assembler input.
10139 ;;
10140 ;; This instruction shifts the target reg/mem as usual, but instead of
10141 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10142 ;; is a left shift double, bits are taken from the high order bits of
10143 ;; reg, else if the insn is a shift right double, bits are taken from the
10144 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10145 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10146 ;;
10147 ;; Since sh[lr]d does not change the `reg' operand, that is done
10148 ;; separately, making all shifts emit pairs of shift double and normal
10149 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10150 ;; support a 63 bit shift, each shift where the count is in a reg expands
10151 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10152 ;;
10153 ;; If the shift count is a constant, we need never emit more than one
10154 ;; shift pair, instead using moves and sign extension for counts greater
10155 ;; than 31.
10156
10157 (define_expand "ashldi3"
10158   [(set (match_operand:DI 0 "shiftdi_operand" "")
10159         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10160                    (match_operand:QI 2 "nonmemory_operand" "")))]
10161   ""
10162   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10163
10164 (define_insn "*ashldi3_1_rex64"
10165   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10166         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10167                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10168    (clobber (reg:CC FLAGS_REG))]
10169   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10170 {
10171   switch (get_attr_type (insn))
10172     {
10173     case TYPE_ALU:
10174       if (operands[2] != const1_rtx)
10175         abort ();
10176       if (!rtx_equal_p (operands[0], operands[1]))
10177         abort ();
10178       return "add{q}\t{%0, %0|%0, %0}";
10179
10180     case TYPE_LEA:
10181       if (GET_CODE (operands[2]) != CONST_INT
10182           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10183         abort ();
10184       operands[1] = gen_rtx_MULT (DImode, operands[1],
10185                                   GEN_INT (1 << INTVAL (operands[2])));
10186       return "lea{q}\t{%a1, %0|%0, %a1}";
10187
10188     default:
10189       if (REG_P (operands[2]))
10190         return "sal{q}\t{%b2, %0|%0, %b2}";
10191       else if (operands[2] == const1_rtx
10192                && (TARGET_SHIFT1 || optimize_size))
10193         return "sal{q}\t%0";
10194       else
10195         return "sal{q}\t{%2, %0|%0, %2}";
10196     }
10197 }
10198   [(set (attr "type")
10199      (cond [(eq_attr "alternative" "1")
10200               (const_string "lea")
10201             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10202                           (const_int 0))
10203                       (match_operand 0 "register_operand" ""))
10204                  (match_operand 2 "const1_operand" ""))
10205               (const_string "alu")
10206            ]
10207            (const_string "ishift")))
10208    (set_attr "mode" "DI")])
10209
10210 ;; Convert lea to the lea pattern to avoid flags dependency.
10211 (define_split
10212   [(set (match_operand:DI 0 "register_operand" "")
10213         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10214                    (match_operand:QI 2 "immediate_operand" "")))
10215    (clobber (reg:CC FLAGS_REG))]
10216   "TARGET_64BIT && reload_completed
10217    && true_regnum (operands[0]) != true_regnum (operands[1])"
10218   [(set (match_dup 0)
10219         (mult:DI (match_dup 1)
10220                  (match_dup 2)))]
10221   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10222
10223 ;; This pattern can't accept a variable shift count, since shifts by
10224 ;; zero don't affect the flags.  We assume that shifts by constant
10225 ;; zero are optimized away.
10226 (define_insn "*ashldi3_cmp_rex64"
10227   [(set (reg FLAGS_REG)
10228         (compare
10229           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10230                      (match_operand:QI 2 "immediate_operand" "e"))
10231           (const_int 0)))
10232    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10233         (ashift:DI (match_dup 1) (match_dup 2)))]
10234   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10235    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10236 {
10237   switch (get_attr_type (insn))
10238     {
10239     case TYPE_ALU:
10240       if (operands[2] != const1_rtx)
10241         abort ();
10242       return "add{q}\t{%0, %0|%0, %0}";
10243
10244     default:
10245       if (REG_P (operands[2]))
10246         return "sal{q}\t{%b2, %0|%0, %b2}";
10247       else if (operands[2] == const1_rtx
10248                && (TARGET_SHIFT1 || optimize_size))
10249         return "sal{q}\t%0";
10250       else
10251         return "sal{q}\t{%2, %0|%0, %2}";
10252     }
10253 }
10254   [(set (attr "type")
10255      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10256                           (const_int 0))
10257                       (match_operand 0 "register_operand" ""))
10258                  (match_operand 2 "const1_operand" ""))
10259               (const_string "alu")
10260            ]
10261            (const_string "ishift")))
10262    (set_attr "mode" "DI")])
10263
10264 (define_insn "*ashldi3_1"
10265   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10266         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10267                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "!TARGET_64BIT"
10270   "#"
10271   [(set_attr "type" "multi")])
10272
10273 ;; By default we don't ask for a scratch register, because when DImode
10274 ;; values are manipulated, registers are already at a premium.  But if
10275 ;; we have one handy, we won't turn it away.
10276 (define_peephole2
10277   [(match_scratch:SI 3 "r")
10278    (parallel [(set (match_operand:DI 0 "register_operand" "")
10279                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10280                               (match_operand:QI 2 "nonmemory_operand" "")))
10281               (clobber (reg:CC FLAGS_REG))])
10282    (match_dup 3)]
10283   "!TARGET_64BIT && TARGET_CMOVE"
10284   [(const_int 0)]
10285   "ix86_split_ashldi (operands, operands[3]); DONE;")
10286
10287 (define_split
10288   [(set (match_operand:DI 0 "register_operand" "")
10289         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10290                    (match_operand:QI 2 "nonmemory_operand" "")))
10291    (clobber (reg:CC FLAGS_REG))]
10292   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10293   [(const_int 0)]
10294   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10295
10296 (define_insn "x86_shld_1"
10297   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10298         (ior:SI (ashift:SI (match_dup 0)
10299                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10300                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10301                   (minus:QI (const_int 32) (match_dup 2)))))
10302    (clobber (reg:CC FLAGS_REG))]
10303   ""
10304   "@
10305    shld{l}\t{%2, %1, %0|%0, %1, %2}
10306    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10307   [(set_attr "type" "ishift")
10308    (set_attr "prefix_0f" "1")
10309    (set_attr "mode" "SI")
10310    (set_attr "pent_pair" "np")
10311    (set_attr "athlon_decode" "vector")])
10312
10313 (define_expand "x86_shift_adj_1"
10314   [(set (reg:CCZ FLAGS_REG)
10315         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10316                              (const_int 32))
10317                      (const_int 0)))
10318    (set (match_operand:SI 0 "register_operand" "")
10319         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10320                          (match_operand:SI 1 "register_operand" "")
10321                          (match_dup 0)))
10322    (set (match_dup 1)
10323         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10324                          (match_operand:SI 3 "register_operand" "r")
10325                          (match_dup 1)))]
10326   "TARGET_CMOVE"
10327   "")
10328
10329 (define_expand "x86_shift_adj_2"
10330   [(use (match_operand:SI 0 "register_operand" ""))
10331    (use (match_operand:SI 1 "register_operand" ""))
10332    (use (match_operand:QI 2 "register_operand" ""))]
10333   ""
10334 {
10335   rtx label = gen_label_rtx ();
10336   rtx tmp;
10337
10338   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10339
10340   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10341   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10342   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10343                               gen_rtx_LABEL_REF (VOIDmode, label),
10344                               pc_rtx);
10345   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10346   JUMP_LABEL (tmp) = label;
10347
10348   emit_move_insn (operands[0], operands[1]);
10349   ix86_expand_clear (operands[1]);
10350
10351   emit_label (label);
10352   LABEL_NUSES (label) = 1;
10353
10354   DONE;
10355 })
10356
10357 (define_expand "ashlsi3"
10358   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10359         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10360                    (match_operand:QI 2 "nonmemory_operand" "")))
10361    (clobber (reg:CC FLAGS_REG))]
10362   ""
10363   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10364
10365 (define_insn "*ashlsi3_1"
10366   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10367         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10368                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10369    (clobber (reg:CC FLAGS_REG))]
10370   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10371 {
10372   switch (get_attr_type (insn))
10373     {
10374     case TYPE_ALU:
10375       if (operands[2] != const1_rtx)
10376         abort ();
10377       if (!rtx_equal_p (operands[0], operands[1]))
10378         abort ();
10379       return "add{l}\t{%0, %0|%0, %0}";
10380
10381     case TYPE_LEA:
10382       return "#";
10383
10384     default:
10385       if (REG_P (operands[2]))
10386         return "sal{l}\t{%b2, %0|%0, %b2}";
10387       else if (operands[2] == const1_rtx
10388                && (TARGET_SHIFT1 || optimize_size))
10389         return "sal{l}\t%0";
10390       else
10391         return "sal{l}\t{%2, %0|%0, %2}";
10392     }
10393 }
10394   [(set (attr "type")
10395      (cond [(eq_attr "alternative" "1")
10396               (const_string "lea")
10397             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10398                           (const_int 0))
10399                       (match_operand 0 "register_operand" ""))
10400                  (match_operand 2 "const1_operand" ""))
10401               (const_string "alu")
10402            ]
10403            (const_string "ishift")))
10404    (set_attr "mode" "SI")])
10405
10406 ;; Convert lea to the lea pattern to avoid flags dependency.
10407 (define_split
10408   [(set (match_operand 0 "register_operand" "")
10409         (ashift (match_operand 1 "index_register_operand" "")
10410                 (match_operand:QI 2 "const_int_operand" "")))
10411    (clobber (reg:CC FLAGS_REG))]
10412   "reload_completed
10413    && true_regnum (operands[0]) != true_regnum (operands[1])
10414    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10415   [(const_int 0)]
10416 {
10417   rtx pat;
10418   enum machine_mode mode = GET_MODE (operands[0]);
10419
10420   if (GET_MODE_SIZE (mode) < 4)
10421     operands[0] = gen_lowpart (SImode, operands[0]);
10422   if (mode != Pmode)
10423     operands[1] = gen_lowpart (Pmode, operands[1]);
10424   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10425
10426   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10427   if (Pmode != SImode)
10428     pat = gen_rtx_SUBREG (SImode, pat, 0);
10429   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10430   DONE;
10431 })
10432
10433 ;; Rare case of shifting RSP is handled by generating move and shift
10434 (define_split
10435   [(set (match_operand 0 "register_operand" "")
10436         (ashift (match_operand 1 "register_operand" "")
10437                 (match_operand:QI 2 "const_int_operand" "")))
10438    (clobber (reg:CC FLAGS_REG))]
10439   "reload_completed
10440    && true_regnum (operands[0]) != true_regnum (operands[1])"
10441   [(const_int 0)]
10442 {
10443   rtx pat, clob;
10444   emit_move_insn (operands[1], operands[0]);
10445   pat = gen_rtx_SET (VOIDmode, operands[0],
10446                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10447                                      operands[0], operands[2]));
10448   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10449   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10450   DONE;
10451 })
10452
10453 (define_insn "*ashlsi3_1_zext"
10454   [(set (match_operand:DI 0 "register_operand" "=r,r")
10455         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10456                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10457    (clobber (reg:CC FLAGS_REG))]
10458   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10459 {
10460   switch (get_attr_type (insn))
10461     {
10462     case TYPE_ALU:
10463       if (operands[2] != const1_rtx)
10464         abort ();
10465       return "add{l}\t{%k0, %k0|%k0, %k0}";
10466
10467     case TYPE_LEA:
10468       return "#";
10469
10470     default:
10471       if (REG_P (operands[2]))
10472         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10473       else if (operands[2] == const1_rtx
10474                && (TARGET_SHIFT1 || optimize_size))
10475         return "sal{l}\t%k0";
10476       else
10477         return "sal{l}\t{%2, %k0|%k0, %2}";
10478     }
10479 }
10480   [(set (attr "type")
10481      (cond [(eq_attr "alternative" "1")
10482               (const_string "lea")
10483             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10484                      (const_int 0))
10485                  (match_operand 2 "const1_operand" ""))
10486               (const_string "alu")
10487            ]
10488            (const_string "ishift")))
10489    (set_attr "mode" "SI")])
10490
10491 ;; Convert lea to the lea pattern to avoid flags dependency.
10492 (define_split
10493   [(set (match_operand:DI 0 "register_operand" "")
10494         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10495                                 (match_operand:QI 2 "const_int_operand" ""))))
10496    (clobber (reg:CC FLAGS_REG))]
10497   "TARGET_64BIT && reload_completed
10498    && true_regnum (operands[0]) != true_regnum (operands[1])"
10499   [(set (match_dup 0) (zero_extend:DI
10500                         (subreg:SI (mult:SI (match_dup 1)
10501                                             (match_dup 2)) 0)))]
10502 {
10503   operands[1] = gen_lowpart (Pmode, operands[1]);
10504   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10505 })
10506
10507 ;; This pattern can't accept a variable shift count, since shifts by
10508 ;; zero don't affect the flags.  We assume that shifts by constant
10509 ;; zero are optimized away.
10510 (define_insn "*ashlsi3_cmp"
10511   [(set (reg FLAGS_REG)
10512         (compare
10513           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10514                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10515           (const_int 0)))
10516    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10517         (ashift:SI (match_dup 1) (match_dup 2)))]
10518   "ix86_match_ccmode (insn, CCGOCmode)
10519    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10520 {
10521   switch (get_attr_type (insn))
10522     {
10523     case TYPE_ALU:
10524       if (operands[2] != const1_rtx)
10525         abort ();
10526       return "add{l}\t{%0, %0|%0, %0}";
10527
10528     default:
10529       if (REG_P (operands[2]))
10530         return "sal{l}\t{%b2, %0|%0, %b2}";
10531       else if (operands[2] == const1_rtx
10532                && (TARGET_SHIFT1 || optimize_size))
10533         return "sal{l}\t%0";
10534       else
10535         return "sal{l}\t{%2, %0|%0, %2}";
10536     }
10537 }
10538   [(set (attr "type")
10539      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10540                           (const_int 0))
10541                       (match_operand 0 "register_operand" ""))
10542                  (match_operand 2 "const1_operand" ""))
10543               (const_string "alu")
10544            ]
10545            (const_string "ishift")))
10546    (set_attr "mode" "SI")])
10547
10548 (define_insn "*ashlsi3_cmp_zext"
10549   [(set (reg FLAGS_REG)
10550         (compare
10551           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10552                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10553           (const_int 0)))
10554    (set (match_operand:DI 0 "register_operand" "=r")
10555         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10556   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10557    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10558 {
10559   switch (get_attr_type (insn))
10560     {
10561     case TYPE_ALU:
10562       if (operands[2] != const1_rtx)
10563         abort ();
10564       return "add{l}\t{%k0, %k0|%k0, %k0}";
10565
10566     default:
10567       if (REG_P (operands[2]))
10568         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10569       else if (operands[2] == const1_rtx
10570                && (TARGET_SHIFT1 || optimize_size))
10571         return "sal{l}\t%k0";
10572       else
10573         return "sal{l}\t{%2, %k0|%k0, %2}";
10574     }
10575 }
10576   [(set (attr "type")
10577      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10578                      (const_int 0))
10579                  (match_operand 2 "const1_operand" ""))
10580               (const_string "alu")
10581            ]
10582            (const_string "ishift")))
10583    (set_attr "mode" "SI")])
10584
10585 (define_expand "ashlhi3"
10586   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10587         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10588                    (match_operand:QI 2 "nonmemory_operand" "")))
10589    (clobber (reg:CC FLAGS_REG))]
10590   "TARGET_HIMODE_MATH"
10591   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10592
10593 (define_insn "*ashlhi3_1_lea"
10594   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10595         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10596                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10597    (clobber (reg:CC FLAGS_REG))]
10598   "!TARGET_PARTIAL_REG_STALL
10599    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10600 {
10601   switch (get_attr_type (insn))
10602     {
10603     case TYPE_LEA:
10604       return "#";
10605     case TYPE_ALU:
10606       if (operands[2] != const1_rtx)
10607         abort ();
10608       return "add{w}\t{%0, %0|%0, %0}";
10609
10610     default:
10611       if (REG_P (operands[2]))
10612         return "sal{w}\t{%b2, %0|%0, %b2}";
10613       else if (operands[2] == const1_rtx
10614                && (TARGET_SHIFT1 || optimize_size))
10615         return "sal{w}\t%0";
10616       else
10617         return "sal{w}\t{%2, %0|%0, %2}";
10618     }
10619 }
10620   [(set (attr "type")
10621      (cond [(eq_attr "alternative" "1")
10622               (const_string "lea")
10623             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10624                           (const_int 0))
10625                       (match_operand 0 "register_operand" ""))
10626                  (match_operand 2 "const1_operand" ""))
10627               (const_string "alu")
10628            ]
10629            (const_string "ishift")))
10630    (set_attr "mode" "HI,SI")])
10631
10632 (define_insn "*ashlhi3_1"
10633   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10634         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10635                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10636    (clobber (reg:CC FLAGS_REG))]
10637   "TARGET_PARTIAL_REG_STALL
10638    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10639 {
10640   switch (get_attr_type (insn))
10641     {
10642     case TYPE_ALU:
10643       if (operands[2] != const1_rtx)
10644         abort ();
10645       return "add{w}\t{%0, %0|%0, %0}";
10646
10647     default:
10648       if (REG_P (operands[2]))
10649         return "sal{w}\t{%b2, %0|%0, %b2}";
10650       else if (operands[2] == const1_rtx
10651                && (TARGET_SHIFT1 || optimize_size))
10652         return "sal{w}\t%0";
10653       else
10654         return "sal{w}\t{%2, %0|%0, %2}";
10655     }
10656 }
10657   [(set (attr "type")
10658      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10659                           (const_int 0))
10660                       (match_operand 0 "register_operand" ""))
10661                  (match_operand 2 "const1_operand" ""))
10662               (const_string "alu")
10663            ]
10664            (const_string "ishift")))
10665    (set_attr "mode" "HI")])
10666
10667 ;; This pattern can't accept a variable shift count, since shifts by
10668 ;; zero don't affect the flags.  We assume that shifts by constant
10669 ;; zero are optimized away.
10670 (define_insn "*ashlhi3_cmp"
10671   [(set (reg FLAGS_REG)
10672         (compare
10673           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10674                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10675           (const_int 0)))
10676    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10677         (ashift:HI (match_dup 1) (match_dup 2)))]
10678   "ix86_match_ccmode (insn, CCGOCmode)
10679    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10680 {
10681   switch (get_attr_type (insn))
10682     {
10683     case TYPE_ALU:
10684       if (operands[2] != const1_rtx)
10685         abort ();
10686       return "add{w}\t{%0, %0|%0, %0}";
10687
10688     default:
10689       if (REG_P (operands[2]))
10690         return "sal{w}\t{%b2, %0|%0, %b2}";
10691       else if (operands[2] == const1_rtx
10692                && (TARGET_SHIFT1 || optimize_size))
10693         return "sal{w}\t%0";
10694       else
10695         return "sal{w}\t{%2, %0|%0, %2}";
10696     }
10697 }
10698   [(set (attr "type")
10699      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10700                           (const_int 0))
10701                       (match_operand 0 "register_operand" ""))
10702                  (match_operand 2 "const1_operand" ""))
10703               (const_string "alu")
10704            ]
10705            (const_string "ishift")))
10706    (set_attr "mode" "HI")])
10707
10708 (define_expand "ashlqi3"
10709   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10710         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10711                    (match_operand:QI 2 "nonmemory_operand" "")))
10712    (clobber (reg:CC FLAGS_REG))]
10713   "TARGET_QIMODE_MATH"
10714   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10715
10716 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10717
10718 (define_insn "*ashlqi3_1_lea"
10719   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10720         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10721                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10722    (clobber (reg:CC FLAGS_REG))]
10723   "!TARGET_PARTIAL_REG_STALL
10724    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10725 {
10726   switch (get_attr_type (insn))
10727     {
10728     case TYPE_LEA:
10729       return "#";
10730     case TYPE_ALU:
10731       if (operands[2] != const1_rtx)
10732         abort ();
10733       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10734         return "add{l}\t{%k0, %k0|%k0, %k0}";
10735       else
10736         return "add{b}\t{%0, %0|%0, %0}";
10737
10738     default:
10739       if (REG_P (operands[2]))
10740         {
10741           if (get_attr_mode (insn) == MODE_SI)
10742             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10743           else
10744             return "sal{b}\t{%b2, %0|%0, %b2}";
10745         }
10746       else if (operands[2] == const1_rtx
10747                && (TARGET_SHIFT1 || optimize_size))
10748         {
10749           if (get_attr_mode (insn) == MODE_SI)
10750             return "sal{l}\t%0";
10751           else
10752             return "sal{b}\t%0";
10753         }
10754       else
10755         {
10756           if (get_attr_mode (insn) == MODE_SI)
10757             return "sal{l}\t{%2, %k0|%k0, %2}";
10758           else
10759             return "sal{b}\t{%2, %0|%0, %2}";
10760         }
10761     }
10762 }
10763   [(set (attr "type")
10764      (cond [(eq_attr "alternative" "2")
10765               (const_string "lea")
10766             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10767                           (const_int 0))
10768                       (match_operand 0 "register_operand" ""))
10769                  (match_operand 2 "const1_operand" ""))
10770               (const_string "alu")
10771            ]
10772            (const_string "ishift")))
10773    (set_attr "mode" "QI,SI,SI")])
10774
10775 (define_insn "*ashlqi3_1"
10776   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10777         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10778                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10779    (clobber (reg:CC FLAGS_REG))]
10780   "TARGET_PARTIAL_REG_STALL
10781    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10782 {
10783   switch (get_attr_type (insn))
10784     {
10785     case TYPE_ALU:
10786       if (operands[2] != const1_rtx)
10787         abort ();
10788       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10789         return "add{l}\t{%k0, %k0|%k0, %k0}";
10790       else
10791         return "add{b}\t{%0, %0|%0, %0}";
10792
10793     default:
10794       if (REG_P (operands[2]))
10795         {
10796           if (get_attr_mode (insn) == MODE_SI)
10797             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10798           else
10799             return "sal{b}\t{%b2, %0|%0, %b2}";
10800         }
10801       else if (operands[2] == const1_rtx
10802                && (TARGET_SHIFT1 || optimize_size))
10803         {
10804           if (get_attr_mode (insn) == MODE_SI)
10805             return "sal{l}\t%0";
10806           else
10807             return "sal{b}\t%0";
10808         }
10809       else
10810         {
10811           if (get_attr_mode (insn) == MODE_SI)
10812             return "sal{l}\t{%2, %k0|%k0, %2}";
10813           else
10814             return "sal{b}\t{%2, %0|%0, %2}";
10815         }
10816     }
10817 }
10818   [(set (attr "type")
10819      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10820                           (const_int 0))
10821                       (match_operand 0 "register_operand" ""))
10822                  (match_operand 2 "const1_operand" ""))
10823               (const_string "alu")
10824            ]
10825            (const_string "ishift")))
10826    (set_attr "mode" "QI,SI")])
10827
10828 ;; This pattern can't accept a variable shift count, since shifts by
10829 ;; zero don't affect the flags.  We assume that shifts by constant
10830 ;; zero are optimized away.
10831 (define_insn "*ashlqi3_cmp"
10832   [(set (reg FLAGS_REG)
10833         (compare
10834           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10835                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10836           (const_int 0)))
10837    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10838         (ashift:QI (match_dup 1) (match_dup 2)))]
10839   "ix86_match_ccmode (insn, CCGOCmode)
10840    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10841 {
10842   switch (get_attr_type (insn))
10843     {
10844     case TYPE_ALU:
10845       if (operands[2] != const1_rtx)
10846         abort ();
10847       return "add{b}\t{%0, %0|%0, %0}";
10848
10849     default:
10850       if (REG_P (operands[2]))
10851         return "sal{b}\t{%b2, %0|%0, %b2}";
10852       else if (operands[2] == const1_rtx
10853                && (TARGET_SHIFT1 || optimize_size))
10854         return "sal{b}\t%0";
10855       else
10856         return "sal{b}\t{%2, %0|%0, %2}";
10857     }
10858 }
10859   [(set (attr "type")
10860      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10861                           (const_int 0))
10862                       (match_operand 0 "register_operand" ""))
10863                  (match_operand 2 "const1_operand" ""))
10864               (const_string "alu")
10865            ]
10866            (const_string "ishift")))
10867    (set_attr "mode" "QI")])
10868
10869 ;; See comment above `ashldi3' about how this works.
10870
10871 (define_expand "ashrdi3"
10872   [(set (match_operand:DI 0 "shiftdi_operand" "")
10873         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10874                      (match_operand:QI 2 "nonmemory_operand" "")))]
10875   ""
10876   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10877
10878 (define_insn "*ashrdi3_63_rex64"
10879   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10880         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10881                      (match_operand:DI 2 "const_int_operand" "i,i")))
10882    (clobber (reg:CC FLAGS_REG))]
10883   "TARGET_64BIT && INTVAL (operands[2]) == 63
10884    && (TARGET_USE_CLTD || optimize_size)
10885    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10886   "@
10887    {cqto|cqo}
10888    sar{q}\t{%2, %0|%0, %2}"
10889   [(set_attr "type" "imovx,ishift")
10890    (set_attr "prefix_0f" "0,*")
10891    (set_attr "length_immediate" "0,*")
10892    (set_attr "modrm" "0,1")
10893    (set_attr "mode" "DI")])
10894
10895 (define_insn "*ashrdi3_1_one_bit_rex64"
10896   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10897         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10898                      (match_operand:QI 2 "const1_operand" "")))
10899    (clobber (reg:CC FLAGS_REG))]
10900   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10901    && (TARGET_SHIFT1 || optimize_size)"
10902   "sar{q}\t%0"
10903   [(set_attr "type" "ishift")
10904    (set (attr "length") 
10905      (if_then_else (match_operand:DI 0 "register_operand" "") 
10906         (const_string "2")
10907         (const_string "*")))])
10908
10909 (define_insn "*ashrdi3_1_rex64"
10910   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10911         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10912                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10913    (clobber (reg:CC FLAGS_REG))]
10914   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10915   "@
10916    sar{q}\t{%2, %0|%0, %2}
10917    sar{q}\t{%b2, %0|%0, %b2}"
10918   [(set_attr "type" "ishift")
10919    (set_attr "mode" "DI")])
10920
10921 ;; This pattern can't accept a variable shift count, since shifts by
10922 ;; zero don't affect the flags.  We assume that shifts by constant
10923 ;; zero are optimized away.
10924 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10925   [(set (reg FLAGS_REG)
10926         (compare
10927           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10928                        (match_operand:QI 2 "const1_operand" ""))
10929           (const_int 0)))
10930    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10931         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10932   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10933    && (TARGET_SHIFT1 || optimize_size)
10934    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10935   "sar{q}\t%0"
10936   [(set_attr "type" "ishift")
10937    (set (attr "length") 
10938      (if_then_else (match_operand:DI 0 "register_operand" "") 
10939         (const_string "2")
10940         (const_string "*")))])
10941
10942 ;; This pattern can't accept a variable shift count, since shifts by
10943 ;; zero don't affect the flags.  We assume that shifts by constant
10944 ;; zero are optimized away.
10945 (define_insn "*ashrdi3_cmp_rex64"
10946   [(set (reg FLAGS_REG)
10947         (compare
10948           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10949                        (match_operand:QI 2 "const_int_operand" "n"))
10950           (const_int 0)))
10951    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10952         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10953   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10954    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10955   "sar{q}\t{%2, %0|%0, %2}"
10956   [(set_attr "type" "ishift")
10957    (set_attr "mode" "DI")])
10958
10959 (define_insn "*ashrdi3_1"
10960   [(set (match_operand:DI 0 "register_operand" "=r")
10961         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10962                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10963    (clobber (reg:CC FLAGS_REG))]
10964   "!TARGET_64BIT"
10965   "#"
10966   [(set_attr "type" "multi")])
10967
10968 ;; By default we don't ask for a scratch register, because when DImode
10969 ;; values are manipulated, registers are already at a premium.  But if
10970 ;; we have one handy, we won't turn it away.
10971 (define_peephole2
10972   [(match_scratch:SI 3 "r")
10973    (parallel [(set (match_operand:DI 0 "register_operand" "")
10974                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10975                                 (match_operand:QI 2 "nonmemory_operand" "")))
10976               (clobber (reg:CC FLAGS_REG))])
10977    (match_dup 3)]
10978   "!TARGET_64BIT && TARGET_CMOVE"
10979   [(const_int 0)]
10980   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10981
10982 (define_split
10983   [(set (match_operand:DI 0 "register_operand" "")
10984         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10985                      (match_operand:QI 2 "nonmemory_operand" "")))
10986    (clobber (reg:CC FLAGS_REG))]
10987   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10988   [(const_int 0)]
10989   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10990
10991 (define_insn "x86_shrd_1"
10992   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10993         (ior:SI (ashiftrt:SI (match_dup 0)
10994                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10995                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10996                   (minus:QI (const_int 32) (match_dup 2)))))
10997    (clobber (reg:CC FLAGS_REG))]
10998   ""
10999   "@
11000    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11001    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11002   [(set_attr "type" "ishift")
11003    (set_attr "prefix_0f" "1")
11004    (set_attr "pent_pair" "np")
11005    (set_attr "mode" "SI")])
11006
11007 (define_expand "x86_shift_adj_3"
11008   [(use (match_operand:SI 0 "register_operand" ""))
11009    (use (match_operand:SI 1 "register_operand" ""))
11010    (use (match_operand:QI 2 "register_operand" ""))]
11011   ""
11012 {
11013   rtx label = gen_label_rtx ();
11014   rtx tmp;
11015
11016   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11017
11018   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11019   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11020   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11021                               gen_rtx_LABEL_REF (VOIDmode, label),
11022                               pc_rtx);
11023   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11024   JUMP_LABEL (tmp) = label;
11025
11026   emit_move_insn (operands[0], operands[1]);
11027   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11028
11029   emit_label (label);
11030   LABEL_NUSES (label) = 1;
11031
11032   DONE;
11033 })
11034
11035 (define_insn "ashrsi3_31"
11036   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11037         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11038                      (match_operand:SI 2 "const_int_operand" "i,i")))
11039    (clobber (reg:CC FLAGS_REG))]
11040   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11041    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11042   "@
11043    {cltd|cdq}
11044    sar{l}\t{%2, %0|%0, %2}"
11045   [(set_attr "type" "imovx,ishift")
11046    (set_attr "prefix_0f" "0,*")
11047    (set_attr "length_immediate" "0,*")
11048    (set_attr "modrm" "0,1")
11049    (set_attr "mode" "SI")])
11050
11051 (define_insn "*ashrsi3_31_zext"
11052   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11053         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11054                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11055    (clobber (reg:CC FLAGS_REG))]
11056   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11057    && INTVAL (operands[2]) == 31
11058    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11059   "@
11060    {cltd|cdq}
11061    sar{l}\t{%2, %k0|%k0, %2}"
11062   [(set_attr "type" "imovx,ishift")
11063    (set_attr "prefix_0f" "0,*")
11064    (set_attr "length_immediate" "0,*")
11065    (set_attr "modrm" "0,1")
11066    (set_attr "mode" "SI")])
11067
11068 (define_expand "ashrsi3"
11069   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11070         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11071                      (match_operand:QI 2 "nonmemory_operand" "")))
11072    (clobber (reg:CC FLAGS_REG))]
11073   ""
11074   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11075
11076 (define_insn "*ashrsi3_1_one_bit"
11077   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11078         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11079                      (match_operand:QI 2 "const1_operand" "")))
11080    (clobber (reg:CC FLAGS_REG))]
11081   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11082    && (TARGET_SHIFT1 || optimize_size)"
11083   "sar{l}\t%0"
11084   [(set_attr "type" "ishift")
11085    (set (attr "length") 
11086      (if_then_else (match_operand:SI 0 "register_operand" "") 
11087         (const_string "2")
11088         (const_string "*")))])
11089
11090 (define_insn "*ashrsi3_1_one_bit_zext"
11091   [(set (match_operand:DI 0 "register_operand" "=r")
11092         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11093                                      (match_operand:QI 2 "const1_operand" ""))))
11094    (clobber (reg:CC FLAGS_REG))]
11095   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11096    && (TARGET_SHIFT1 || optimize_size)"
11097   "sar{l}\t%k0"
11098   [(set_attr "type" "ishift")
11099    (set_attr "length" "2")])
11100
11101 (define_insn "*ashrsi3_1"
11102   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11103         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11104                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11107   "@
11108    sar{l}\t{%2, %0|%0, %2}
11109    sar{l}\t{%b2, %0|%0, %b2}"
11110   [(set_attr "type" "ishift")
11111    (set_attr "mode" "SI")])
11112
11113 (define_insn "*ashrsi3_1_zext"
11114   [(set (match_operand:DI 0 "register_operand" "=r,r")
11115         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11116                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11117    (clobber (reg:CC FLAGS_REG))]
11118   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11119   "@
11120    sar{l}\t{%2, %k0|%k0, %2}
11121    sar{l}\t{%b2, %k0|%k0, %b2}"
11122   [(set_attr "type" "ishift")
11123    (set_attr "mode" "SI")])
11124
11125 ;; This pattern can't accept a variable shift count, since shifts by
11126 ;; zero don't affect the flags.  We assume that shifts by constant
11127 ;; zero are optimized away.
11128 (define_insn "*ashrsi3_one_bit_cmp"
11129   [(set (reg FLAGS_REG)
11130         (compare
11131           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11132                        (match_operand:QI 2 "const1_operand" ""))
11133           (const_int 0)))
11134    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11135         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11136   "ix86_match_ccmode (insn, CCGOCmode)
11137    && (TARGET_SHIFT1 || optimize_size)
11138    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11139   "sar{l}\t%0"
11140   [(set_attr "type" "ishift")
11141    (set (attr "length") 
11142      (if_then_else (match_operand:SI 0 "register_operand" "") 
11143         (const_string "2")
11144         (const_string "*")))])
11145
11146 (define_insn "*ashrsi3_one_bit_cmp_zext"
11147   [(set (reg FLAGS_REG)
11148         (compare
11149           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11150                        (match_operand:QI 2 "const1_operand" ""))
11151           (const_int 0)))
11152    (set (match_operand:DI 0 "register_operand" "=r")
11153         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11154   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11155    && (TARGET_SHIFT1 || optimize_size)
11156    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11157   "sar{l}\t%k0"
11158   [(set_attr "type" "ishift")
11159    (set_attr "length" "2")])
11160
11161 ;; This pattern can't accept a variable shift count, since shifts by
11162 ;; zero don't affect the flags.  We assume that shifts by constant
11163 ;; zero are optimized away.
11164 (define_insn "*ashrsi3_cmp"
11165   [(set (reg FLAGS_REG)
11166         (compare
11167           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11168                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11169           (const_int 0)))
11170    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11171         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11172   "ix86_match_ccmode (insn, CCGOCmode)
11173    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11174   "sar{l}\t{%2, %0|%0, %2}"
11175   [(set_attr "type" "ishift")
11176    (set_attr "mode" "SI")])
11177
11178 (define_insn "*ashrsi3_cmp_zext"
11179   [(set (reg FLAGS_REG)
11180         (compare
11181           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11182                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11183           (const_int 0)))
11184    (set (match_operand:DI 0 "register_operand" "=r")
11185         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11186   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11187    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11188   "sar{l}\t{%2, %k0|%k0, %2}"
11189   [(set_attr "type" "ishift")
11190    (set_attr "mode" "SI")])
11191
11192 (define_expand "ashrhi3"
11193   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11194         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11195                      (match_operand:QI 2 "nonmemory_operand" "")))
11196    (clobber (reg:CC FLAGS_REG))]
11197   "TARGET_HIMODE_MATH"
11198   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11199
11200 (define_insn "*ashrhi3_1_one_bit"
11201   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11202         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11203                      (match_operand:QI 2 "const1_operand" "")))
11204    (clobber (reg:CC FLAGS_REG))]
11205   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11206    && (TARGET_SHIFT1 || optimize_size)"
11207   "sar{w}\t%0"
11208   [(set_attr "type" "ishift")
11209    (set (attr "length") 
11210      (if_then_else (match_operand 0 "register_operand" "") 
11211         (const_string "2")
11212         (const_string "*")))])
11213
11214 (define_insn "*ashrhi3_1"
11215   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11216         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11217                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11218    (clobber (reg:CC FLAGS_REG))]
11219   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11220   "@
11221    sar{w}\t{%2, %0|%0, %2}
11222    sar{w}\t{%b2, %0|%0, %b2}"
11223   [(set_attr "type" "ishift")
11224    (set_attr "mode" "HI")])
11225
11226 ;; This pattern can't accept a variable shift count, since shifts by
11227 ;; zero don't affect the flags.  We assume that shifts by constant
11228 ;; zero are optimized away.
11229 (define_insn "*ashrhi3_one_bit_cmp"
11230   [(set (reg FLAGS_REG)
11231         (compare
11232           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11233                        (match_operand:QI 2 "const1_operand" ""))
11234           (const_int 0)))
11235    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11236         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11237   "ix86_match_ccmode (insn, CCGOCmode)
11238    && (TARGET_SHIFT1 || optimize_size)
11239    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11240   "sar{w}\t%0"
11241   [(set_attr "type" "ishift")
11242    (set (attr "length") 
11243      (if_then_else (match_operand 0 "register_operand" "") 
11244         (const_string "2")
11245         (const_string "*")))])
11246
11247 ;; This pattern can't accept a variable shift count, since shifts by
11248 ;; zero don't affect the flags.  We assume that shifts by constant
11249 ;; zero are optimized away.
11250 (define_insn "*ashrhi3_cmp"
11251   [(set (reg FLAGS_REG)
11252         (compare
11253           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11254                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11255           (const_int 0)))
11256    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11257         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11258   "ix86_match_ccmode (insn, CCGOCmode)
11259    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11260   "sar{w}\t{%2, %0|%0, %2}"
11261   [(set_attr "type" "ishift")
11262    (set_attr "mode" "HI")])
11263
11264 (define_expand "ashrqi3"
11265   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11266         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11267                      (match_operand:QI 2 "nonmemory_operand" "")))
11268    (clobber (reg:CC FLAGS_REG))]
11269   "TARGET_QIMODE_MATH"
11270   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11271
11272 (define_insn "*ashrqi3_1_one_bit"
11273   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11274         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11275                      (match_operand:QI 2 "const1_operand" "")))
11276    (clobber (reg:CC FLAGS_REG))]
11277   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11278    && (TARGET_SHIFT1 || optimize_size)"
11279   "sar{b}\t%0"
11280   [(set_attr "type" "ishift")
11281    (set (attr "length") 
11282      (if_then_else (match_operand 0 "register_operand" "") 
11283         (const_string "2")
11284         (const_string "*")))])
11285
11286 (define_insn "*ashrqi3_1_one_bit_slp"
11287   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11288         (ashiftrt:QI (match_dup 0)
11289                      (match_operand:QI 1 "const1_operand" "")))
11290    (clobber (reg:CC FLAGS_REG))]
11291   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11292    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11293    && (TARGET_SHIFT1 || optimize_size)"
11294   "sar{b}\t%0"
11295   [(set_attr "type" "ishift1")
11296    (set (attr "length") 
11297      (if_then_else (match_operand 0 "register_operand" "") 
11298         (const_string "2")
11299         (const_string "*")))])
11300
11301 (define_insn "*ashrqi3_1"
11302   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11303         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11304                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11305    (clobber (reg:CC FLAGS_REG))]
11306   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11307   "@
11308    sar{b}\t{%2, %0|%0, %2}
11309    sar{b}\t{%b2, %0|%0, %b2}"
11310   [(set_attr "type" "ishift")
11311    (set_attr "mode" "QI")])
11312
11313 (define_insn "*ashrqi3_1_slp"
11314   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11315         (ashiftrt:QI (match_dup 0)
11316                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11319    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11320   "@
11321    sar{b}\t{%1, %0|%0, %1}
11322    sar{b}\t{%b1, %0|%0, %b1}"
11323   [(set_attr "type" "ishift1")
11324    (set_attr "mode" "QI")])
11325
11326 ;; This pattern can't accept a variable shift count, since shifts by
11327 ;; zero don't affect the flags.  We assume that shifts by constant
11328 ;; zero are optimized away.
11329 (define_insn "*ashrqi3_one_bit_cmp"
11330   [(set (reg FLAGS_REG)
11331         (compare
11332           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11333                        (match_operand:QI 2 "const1_operand" "I"))
11334           (const_int 0)))
11335    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11336         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11337   "ix86_match_ccmode (insn, CCGOCmode)
11338    && (TARGET_SHIFT1 || optimize_size)
11339    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11340   "sar{b}\t%0"
11341   [(set_attr "type" "ishift")
11342    (set (attr "length") 
11343      (if_then_else (match_operand 0 "register_operand" "") 
11344         (const_string "2")
11345         (const_string "*")))])
11346
11347 ;; This pattern can't accept a variable shift count, since shifts by
11348 ;; zero don't affect the flags.  We assume that shifts by constant
11349 ;; zero are optimized away.
11350 (define_insn "*ashrqi3_cmp"
11351   [(set (reg FLAGS_REG)
11352         (compare
11353           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11354                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11355           (const_int 0)))
11356    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11357         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11358   "ix86_match_ccmode (insn, CCGOCmode)
11359    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11360   "sar{b}\t{%2, %0|%0, %2}"
11361   [(set_attr "type" "ishift")
11362    (set_attr "mode" "QI")])
11363 \f
11364 ;; Logical shift instructions
11365
11366 ;; See comment above `ashldi3' about how this works.
11367
11368 (define_expand "lshrdi3"
11369   [(set (match_operand:DI 0 "shiftdi_operand" "")
11370         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11371                      (match_operand:QI 2 "nonmemory_operand" "")))]
11372   ""
11373   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11374
11375 (define_insn "*lshrdi3_1_one_bit_rex64"
11376   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11377         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11378                      (match_operand:QI 2 "const1_operand" "")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11381    && (TARGET_SHIFT1 || optimize_size)"
11382   "shr{q}\t%0"
11383   [(set_attr "type" "ishift")
11384    (set (attr "length") 
11385      (if_then_else (match_operand:DI 0 "register_operand" "") 
11386         (const_string "2")
11387         (const_string "*")))])
11388
11389 (define_insn "*lshrdi3_1_rex64"
11390   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11391         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11392                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11393    (clobber (reg:CC FLAGS_REG))]
11394   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11395   "@
11396    shr{q}\t{%2, %0|%0, %2}
11397    shr{q}\t{%b2, %0|%0, %b2}"
11398   [(set_attr "type" "ishift")
11399    (set_attr "mode" "DI")])
11400
11401 ;; This pattern can't accept a variable shift count, since shifts by
11402 ;; zero don't affect the flags.  We assume that shifts by constant
11403 ;; zero are optimized away.
11404 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11405   [(set (reg FLAGS_REG)
11406         (compare
11407           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11408                        (match_operand:QI 2 "const1_operand" ""))
11409           (const_int 0)))
11410    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11412   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11413    && (TARGET_SHIFT1 || optimize_size)
11414    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11415   "shr{q}\t%0"
11416   [(set_attr "type" "ishift")
11417    (set (attr "length") 
11418      (if_then_else (match_operand:DI 0 "register_operand" "") 
11419         (const_string "2")
11420         (const_string "*")))])
11421
11422 ;; This pattern can't accept a variable shift count, since shifts by
11423 ;; zero don't affect the flags.  We assume that shifts by constant
11424 ;; zero are optimized away.
11425 (define_insn "*lshrdi3_cmp_rex64"
11426   [(set (reg FLAGS_REG)
11427         (compare
11428           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11429                        (match_operand:QI 2 "const_int_operand" "e"))
11430           (const_int 0)))
11431    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11432         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11433   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11434    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11435   "shr{q}\t{%2, %0|%0, %2}"
11436   [(set_attr "type" "ishift")
11437    (set_attr "mode" "DI")])
11438
11439 (define_insn "*lshrdi3_1"
11440   [(set (match_operand:DI 0 "register_operand" "=r")
11441         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11442                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11443    (clobber (reg:CC FLAGS_REG))]
11444   "!TARGET_64BIT"
11445   "#"
11446   [(set_attr "type" "multi")])
11447
11448 ;; By default we don't ask for a scratch register, because when DImode
11449 ;; values are manipulated, registers are already at a premium.  But if
11450 ;; we have one handy, we won't turn it away.
11451 (define_peephole2
11452   [(match_scratch:SI 3 "r")
11453    (parallel [(set (match_operand:DI 0 "register_operand" "")
11454                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11455                                 (match_operand:QI 2 "nonmemory_operand" "")))
11456               (clobber (reg:CC FLAGS_REG))])
11457    (match_dup 3)]
11458   "!TARGET_64BIT && TARGET_CMOVE"
11459   [(const_int 0)]
11460   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11461
11462 (define_split 
11463   [(set (match_operand:DI 0 "register_operand" "")
11464         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11465                      (match_operand:QI 2 "nonmemory_operand" "")))
11466    (clobber (reg:CC FLAGS_REG))]
11467   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11468   [(const_int 0)]
11469   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11470
11471 (define_expand "lshrsi3"
11472   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11473         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11474                      (match_operand:QI 2 "nonmemory_operand" "")))
11475    (clobber (reg:CC FLAGS_REG))]
11476   ""
11477   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11478
11479 (define_insn "*lshrsi3_1_one_bit"
11480   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11481         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11482                      (match_operand:QI 2 "const1_operand" "")))
11483    (clobber (reg:CC FLAGS_REG))]
11484   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11485    && (TARGET_SHIFT1 || optimize_size)"
11486   "shr{l}\t%0"
11487   [(set_attr "type" "ishift")
11488    (set (attr "length") 
11489      (if_then_else (match_operand:SI 0 "register_operand" "") 
11490         (const_string "2")
11491         (const_string "*")))])
11492
11493 (define_insn "*lshrsi3_1_one_bit_zext"
11494   [(set (match_operand:DI 0 "register_operand" "=r")
11495         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11496                      (match_operand:QI 2 "const1_operand" "")))
11497    (clobber (reg:CC FLAGS_REG))]
11498   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11499    && (TARGET_SHIFT1 || optimize_size)"
11500   "shr{l}\t%k0"
11501   [(set_attr "type" "ishift")
11502    (set_attr "length" "2")])
11503
11504 (define_insn "*lshrsi3_1"
11505   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11506         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11507                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11508    (clobber (reg:CC FLAGS_REG))]
11509   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11510   "@
11511    shr{l}\t{%2, %0|%0, %2}
11512    shr{l}\t{%b2, %0|%0, %b2}"
11513   [(set_attr "type" "ishift")
11514    (set_attr "mode" "SI")])
11515
11516 (define_insn "*lshrsi3_1_zext"
11517   [(set (match_operand:DI 0 "register_operand" "=r,r")
11518         (zero_extend:DI
11519           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11520                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11521    (clobber (reg:CC FLAGS_REG))]
11522   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11523   "@
11524    shr{l}\t{%2, %k0|%k0, %2}
11525    shr{l}\t{%b2, %k0|%k0, %b2}"
11526   [(set_attr "type" "ishift")
11527    (set_attr "mode" "SI")])
11528
11529 ;; This pattern can't accept a variable shift count, since shifts by
11530 ;; zero don't affect the flags.  We assume that shifts by constant
11531 ;; zero are optimized away.
11532 (define_insn "*lshrsi3_one_bit_cmp"
11533   [(set (reg FLAGS_REG)
11534         (compare
11535           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11536                        (match_operand:QI 2 "const1_operand" ""))
11537           (const_int 0)))
11538    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11539         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11540   "ix86_match_ccmode (insn, CCGOCmode)
11541    && (TARGET_SHIFT1 || optimize_size)
11542    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11543   "shr{l}\t%0"
11544   [(set_attr "type" "ishift")
11545    (set (attr "length") 
11546      (if_then_else (match_operand:SI 0 "register_operand" "") 
11547         (const_string "2")
11548         (const_string "*")))])
11549
11550 (define_insn "*lshrsi3_cmp_one_bit_zext"
11551   [(set (reg FLAGS_REG)
11552         (compare
11553           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11554                        (match_operand:QI 2 "const1_operand" ""))
11555           (const_int 0)))
11556    (set (match_operand:DI 0 "register_operand" "=r")
11557         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11558   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11559    && (TARGET_SHIFT1 || optimize_size)
11560    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11561   "shr{l}\t%k0"
11562   [(set_attr "type" "ishift")
11563    (set_attr "length" "2")])
11564
11565 ;; This pattern can't accept a variable shift count, since shifts by
11566 ;; zero don't affect the flags.  We assume that shifts by constant
11567 ;; zero are optimized away.
11568 (define_insn "*lshrsi3_cmp"
11569   [(set (reg FLAGS_REG)
11570         (compare
11571           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11572                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11573           (const_int 0)))
11574    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11575         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11576   "ix86_match_ccmode (insn, CCGOCmode)
11577    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11578   "shr{l}\t{%2, %0|%0, %2}"
11579   [(set_attr "type" "ishift")
11580    (set_attr "mode" "SI")])
11581
11582 (define_insn "*lshrsi3_cmp_zext"
11583   [(set (reg FLAGS_REG)
11584         (compare
11585           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11586                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11587           (const_int 0)))
11588    (set (match_operand:DI 0 "register_operand" "=r")
11589         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11590   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11591    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11592   "shr{l}\t{%2, %k0|%k0, %2}"
11593   [(set_attr "type" "ishift")
11594    (set_attr "mode" "SI")])
11595
11596 (define_expand "lshrhi3"
11597   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11598         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11599                      (match_operand:QI 2 "nonmemory_operand" "")))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "TARGET_HIMODE_MATH"
11602   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11603
11604 (define_insn "*lshrhi3_1_one_bit"
11605   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11606         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11607                      (match_operand:QI 2 "const1_operand" "")))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11610    && (TARGET_SHIFT1 || optimize_size)"
11611   "shr{w}\t%0"
11612   [(set_attr "type" "ishift")
11613    (set (attr "length") 
11614      (if_then_else (match_operand 0 "register_operand" "") 
11615         (const_string "2")
11616         (const_string "*")))])
11617
11618 (define_insn "*lshrhi3_1"
11619   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11620         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11621                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11622    (clobber (reg:CC FLAGS_REG))]
11623   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11624   "@
11625    shr{w}\t{%2, %0|%0, %2}
11626    shr{w}\t{%b2, %0|%0, %b2}"
11627   [(set_attr "type" "ishift")
11628    (set_attr "mode" "HI")])
11629
11630 ;; This pattern can't accept a variable shift count, since shifts by
11631 ;; zero don't affect the flags.  We assume that shifts by constant
11632 ;; zero are optimized away.
11633 (define_insn "*lshrhi3_one_bit_cmp"
11634   [(set (reg FLAGS_REG)
11635         (compare
11636           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11637                        (match_operand:QI 2 "const1_operand" ""))
11638           (const_int 0)))
11639    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11640         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11641   "ix86_match_ccmode (insn, CCGOCmode)
11642    && (TARGET_SHIFT1 || optimize_size)
11643    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11644   "shr{w}\t%0"
11645   [(set_attr "type" "ishift")
11646    (set (attr "length") 
11647      (if_then_else (match_operand:SI 0 "register_operand" "") 
11648         (const_string "2")
11649         (const_string "*")))])
11650
11651 ;; This pattern can't accept a variable shift count, since shifts by
11652 ;; zero don't affect the flags.  We assume that shifts by constant
11653 ;; zero are optimized away.
11654 (define_insn "*lshrhi3_cmp"
11655   [(set (reg FLAGS_REG)
11656         (compare
11657           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11658                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11659           (const_int 0)))
11660    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11661         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11662   "ix86_match_ccmode (insn, CCGOCmode)
11663    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11664   "shr{w}\t{%2, %0|%0, %2}"
11665   [(set_attr "type" "ishift")
11666    (set_attr "mode" "HI")])
11667
11668 (define_expand "lshrqi3"
11669   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11670         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11671                      (match_operand:QI 2 "nonmemory_operand" "")))
11672    (clobber (reg:CC FLAGS_REG))]
11673   "TARGET_QIMODE_MATH"
11674   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11675
11676 (define_insn "*lshrqi3_1_one_bit"
11677   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11678         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11679                      (match_operand:QI 2 "const1_operand" "")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11682    && (TARGET_SHIFT1 || optimize_size)"
11683   "shr{b}\t%0"
11684   [(set_attr "type" "ishift")
11685    (set (attr "length") 
11686      (if_then_else (match_operand 0 "register_operand" "") 
11687         (const_string "2")
11688         (const_string "*")))])
11689
11690 (define_insn "*lshrqi3_1_one_bit_slp"
11691   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11692         (lshiftrt:QI (match_dup 0)
11693                      (match_operand:QI 1 "const1_operand" "")))
11694    (clobber (reg:CC FLAGS_REG))]
11695   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11696    && (TARGET_SHIFT1 || optimize_size)"
11697   "shr{b}\t%0"
11698   [(set_attr "type" "ishift1")
11699    (set (attr "length") 
11700      (if_then_else (match_operand 0 "register_operand" "") 
11701         (const_string "2")
11702         (const_string "*")))])
11703
11704 (define_insn "*lshrqi3_1"
11705   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11706         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11707                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11708    (clobber (reg:CC FLAGS_REG))]
11709   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11710   "@
11711    shr{b}\t{%2, %0|%0, %2}
11712    shr{b}\t{%b2, %0|%0, %b2}"
11713   [(set_attr "type" "ishift")
11714    (set_attr "mode" "QI")])
11715
11716 (define_insn "*lshrqi3_1_slp"
11717   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11718         (lshiftrt:QI (match_dup 0)
11719                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11723   "@
11724    shr{b}\t{%1, %0|%0, %1}
11725    shr{b}\t{%b1, %0|%0, %b1}"
11726   [(set_attr "type" "ishift1")
11727    (set_attr "mode" "QI")])
11728
11729 ;; This pattern can't accept a variable shift count, since shifts by
11730 ;; zero don't affect the flags.  We assume that shifts by constant
11731 ;; zero are optimized away.
11732 (define_insn "*lshrqi2_one_bit_cmp"
11733   [(set (reg FLAGS_REG)
11734         (compare
11735           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11736                        (match_operand:QI 2 "const1_operand" ""))
11737           (const_int 0)))
11738    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11739         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11740   "ix86_match_ccmode (insn, CCGOCmode)
11741    && (TARGET_SHIFT1 || optimize_size)
11742    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11743   "shr{b}\t%0"
11744   [(set_attr "type" "ishift")
11745    (set (attr "length") 
11746      (if_then_else (match_operand:SI 0 "register_operand" "") 
11747         (const_string "2")
11748         (const_string "*")))])
11749
11750 ;; This pattern can't accept a variable shift count, since shifts by
11751 ;; zero don't affect the flags.  We assume that shifts by constant
11752 ;; zero are optimized away.
11753 (define_insn "*lshrqi2_cmp"
11754   [(set (reg FLAGS_REG)
11755         (compare
11756           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11757                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11758           (const_int 0)))
11759    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11760         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11761   "ix86_match_ccmode (insn, CCGOCmode)
11762    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11763   "shr{b}\t{%2, %0|%0, %2}"
11764   [(set_attr "type" "ishift")
11765    (set_attr "mode" "QI")])
11766 \f
11767 ;; Rotate instructions
11768
11769 (define_expand "rotldi3"
11770   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11771         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11772                    (match_operand:QI 2 "nonmemory_operand" "")))
11773    (clobber (reg:CC FLAGS_REG))]
11774   "TARGET_64BIT"
11775   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11776
11777 (define_insn "*rotlsi3_1_one_bit_rex64"
11778   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11779         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11780                    (match_operand:QI 2 "const1_operand" "")))
11781    (clobber (reg:CC FLAGS_REG))]
11782   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11783    && (TARGET_SHIFT1 || optimize_size)"
11784   "rol{q}\t%0"
11785   [(set_attr "type" "rotate")
11786    (set (attr "length") 
11787      (if_then_else (match_operand:DI 0 "register_operand" "") 
11788         (const_string "2")
11789         (const_string "*")))])
11790
11791 (define_insn "*rotldi3_1_rex64"
11792   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11793         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11794                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11795    (clobber (reg:CC FLAGS_REG))]
11796   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11797   "@
11798    rol{q}\t{%2, %0|%0, %2}
11799    rol{q}\t{%b2, %0|%0, %b2}"
11800   [(set_attr "type" "rotate")
11801    (set_attr "mode" "DI")])
11802
11803 (define_expand "rotlsi3"
11804   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11805         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11806                    (match_operand:QI 2 "nonmemory_operand" "")))
11807    (clobber (reg:CC FLAGS_REG))]
11808   ""
11809   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11810
11811 (define_insn "*rotlsi3_1_one_bit"
11812   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11813         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11814                    (match_operand:QI 2 "const1_operand" "")))
11815    (clobber (reg:CC FLAGS_REG))]
11816   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11817    && (TARGET_SHIFT1 || optimize_size)"
11818   "rol{l}\t%0"
11819   [(set_attr "type" "rotate")
11820    (set (attr "length") 
11821      (if_then_else (match_operand:SI 0 "register_operand" "") 
11822         (const_string "2")
11823         (const_string "*")))])
11824
11825 (define_insn "*rotlsi3_1_one_bit_zext"
11826   [(set (match_operand:DI 0 "register_operand" "=r")
11827         (zero_extend:DI
11828           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11829                      (match_operand:QI 2 "const1_operand" ""))))
11830    (clobber (reg:CC FLAGS_REG))]
11831   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11832    && (TARGET_SHIFT1 || optimize_size)"
11833   "rol{l}\t%k0"
11834   [(set_attr "type" "rotate")
11835    (set_attr "length" "2")])
11836
11837 (define_insn "*rotlsi3_1"
11838   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11839         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11840                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11841    (clobber (reg:CC FLAGS_REG))]
11842   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11843   "@
11844    rol{l}\t{%2, %0|%0, %2}
11845    rol{l}\t{%b2, %0|%0, %b2}"
11846   [(set_attr "type" "rotate")
11847    (set_attr "mode" "SI")])
11848
11849 (define_insn "*rotlsi3_1_zext"
11850   [(set (match_operand:DI 0 "register_operand" "=r,r")
11851         (zero_extend:DI
11852           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11853                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11854    (clobber (reg:CC FLAGS_REG))]
11855   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11856   "@
11857    rol{l}\t{%2, %k0|%k0, %2}
11858    rol{l}\t{%b2, %k0|%k0, %b2}"
11859   [(set_attr "type" "rotate")
11860    (set_attr "mode" "SI")])
11861
11862 (define_expand "rotlhi3"
11863   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11864         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11865                    (match_operand:QI 2 "nonmemory_operand" "")))
11866    (clobber (reg:CC FLAGS_REG))]
11867   "TARGET_HIMODE_MATH"
11868   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11869
11870 (define_insn "*rotlhi3_1_one_bit"
11871   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11872         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11873                    (match_operand:QI 2 "const1_operand" "")))
11874    (clobber (reg:CC FLAGS_REG))]
11875   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11876    && (TARGET_SHIFT1 || optimize_size)"
11877   "rol{w}\t%0"
11878   [(set_attr "type" "rotate")
11879    (set (attr "length") 
11880      (if_then_else (match_operand 0 "register_operand" "") 
11881         (const_string "2")
11882         (const_string "*")))])
11883
11884 (define_insn "*rotlhi3_1"
11885   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11886         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11887                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11888    (clobber (reg:CC FLAGS_REG))]
11889   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11890   "@
11891    rol{w}\t{%2, %0|%0, %2}
11892    rol{w}\t{%b2, %0|%0, %b2}"
11893   [(set_attr "type" "rotate")
11894    (set_attr "mode" "HI")])
11895
11896 (define_expand "rotlqi3"
11897   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11898         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11899                    (match_operand:QI 2 "nonmemory_operand" "")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "TARGET_QIMODE_MATH"
11902   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11903
11904 (define_insn "*rotlqi3_1_one_bit_slp"
11905   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11906         (rotate:QI (match_dup 0)
11907                    (match_operand:QI 1 "const1_operand" "")))
11908    (clobber (reg:CC FLAGS_REG))]
11909   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11910    && (TARGET_SHIFT1 || optimize_size)"
11911   "rol{b}\t%0"
11912   [(set_attr "type" "rotate1")
11913    (set (attr "length") 
11914      (if_then_else (match_operand 0 "register_operand" "") 
11915         (const_string "2")
11916         (const_string "*")))])
11917
11918 (define_insn "*rotlqi3_1_one_bit"
11919   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11920         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11921                    (match_operand:QI 2 "const1_operand" "")))
11922    (clobber (reg:CC FLAGS_REG))]
11923   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11924    && (TARGET_SHIFT1 || optimize_size)"
11925   "rol{b}\t%0"
11926   [(set_attr "type" "rotate")
11927    (set (attr "length") 
11928      (if_then_else (match_operand 0 "register_operand" "") 
11929         (const_string "2")
11930         (const_string "*")))])
11931
11932 (define_insn "*rotlqi3_1_slp"
11933   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11934         (rotate:QI (match_dup 0)
11935                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11938    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11939   "@
11940    rol{b}\t{%1, %0|%0, %1}
11941    rol{b}\t{%b1, %0|%0, %b1}"
11942   [(set_attr "type" "rotate1")
11943    (set_attr "mode" "QI")])
11944
11945 (define_insn "*rotlqi3_1"
11946   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11947         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11948                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11949    (clobber (reg:CC FLAGS_REG))]
11950   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11951   "@
11952    rol{b}\t{%2, %0|%0, %2}
11953    rol{b}\t{%b2, %0|%0, %b2}"
11954   [(set_attr "type" "rotate")
11955    (set_attr "mode" "QI")])
11956
11957 (define_expand "rotrdi3"
11958   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11959         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11960                      (match_operand:QI 2 "nonmemory_operand" "")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "TARGET_64BIT"
11963   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11964
11965 (define_insn "*rotrdi3_1_one_bit_rex64"
11966   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11967         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11968                      (match_operand:QI 2 "const1_operand" "")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11971    && (TARGET_SHIFT1 || optimize_size)"
11972   "ror{q}\t%0"
11973   [(set_attr "type" "rotate")
11974    (set (attr "length") 
11975      (if_then_else (match_operand:DI 0 "register_operand" "") 
11976         (const_string "2")
11977         (const_string "*")))])
11978
11979 (define_insn "*rotrdi3_1_rex64"
11980   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11981         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11982                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11983    (clobber (reg:CC FLAGS_REG))]
11984   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11985   "@
11986    ror{q}\t{%2, %0|%0, %2}
11987    ror{q}\t{%b2, %0|%0, %b2}"
11988   [(set_attr "type" "rotate")
11989    (set_attr "mode" "DI")])
11990
11991 (define_expand "rotrsi3"
11992   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11993         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11994                      (match_operand:QI 2 "nonmemory_operand" "")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   ""
11997   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11998
11999 (define_insn "*rotrsi3_1_one_bit"
12000   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12001         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12002                      (match_operand:QI 2 "const1_operand" "")))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12005    && (TARGET_SHIFT1 || optimize_size)"
12006   "ror{l}\t%0"
12007   [(set_attr "type" "rotate")
12008    (set (attr "length") 
12009      (if_then_else (match_operand:SI 0 "register_operand" "") 
12010         (const_string "2")
12011         (const_string "*")))])
12012
12013 (define_insn "*rotrsi3_1_one_bit_zext"
12014   [(set (match_operand:DI 0 "register_operand" "=r")
12015         (zero_extend:DI
12016           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12017                        (match_operand:QI 2 "const1_operand" ""))))
12018    (clobber (reg:CC FLAGS_REG))]
12019   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12020    && (TARGET_SHIFT1 || optimize_size)"
12021   "ror{l}\t%k0"
12022   [(set_attr "type" "rotate")
12023    (set (attr "length") 
12024      (if_then_else (match_operand:SI 0 "register_operand" "") 
12025         (const_string "2")
12026         (const_string "*")))])
12027
12028 (define_insn "*rotrsi3_1"
12029   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12030         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12031                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12032    (clobber (reg:CC FLAGS_REG))]
12033   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12034   "@
12035    ror{l}\t{%2, %0|%0, %2}
12036    ror{l}\t{%b2, %0|%0, %b2}"
12037   [(set_attr "type" "rotate")
12038    (set_attr "mode" "SI")])
12039
12040 (define_insn "*rotrsi3_1_zext"
12041   [(set (match_operand:DI 0 "register_operand" "=r,r")
12042         (zero_extend:DI
12043           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12044                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12045    (clobber (reg:CC FLAGS_REG))]
12046   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12047   "@
12048    ror{l}\t{%2, %k0|%k0, %2}
12049    ror{l}\t{%b2, %k0|%k0, %b2}"
12050   [(set_attr "type" "rotate")
12051    (set_attr "mode" "SI")])
12052
12053 (define_expand "rotrhi3"
12054   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12055         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12056                      (match_operand:QI 2 "nonmemory_operand" "")))
12057    (clobber (reg:CC FLAGS_REG))]
12058   "TARGET_HIMODE_MATH"
12059   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12060
12061 (define_insn "*rotrhi3_one_bit"
12062   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12063         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12064                      (match_operand:QI 2 "const1_operand" "")))
12065    (clobber (reg:CC FLAGS_REG))]
12066   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12067    && (TARGET_SHIFT1 || optimize_size)"
12068   "ror{w}\t%0"
12069   [(set_attr "type" "rotate")
12070    (set (attr "length") 
12071      (if_then_else (match_operand 0 "register_operand" "") 
12072         (const_string "2")
12073         (const_string "*")))])
12074
12075 (define_insn "*rotrhi3"
12076   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12077         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12078                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12079    (clobber (reg:CC FLAGS_REG))]
12080   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12081   "@
12082    ror{w}\t{%2, %0|%0, %2}
12083    ror{w}\t{%b2, %0|%0, %b2}"
12084   [(set_attr "type" "rotate")
12085    (set_attr "mode" "HI")])
12086
12087 (define_expand "rotrqi3"
12088   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12089         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12090                      (match_operand:QI 2 "nonmemory_operand" "")))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "TARGET_QIMODE_MATH"
12093   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12094
12095 (define_insn "*rotrqi3_1_one_bit"
12096   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12097         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12098                      (match_operand:QI 2 "const1_operand" "")))
12099    (clobber (reg:CC FLAGS_REG))]
12100   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12101    && (TARGET_SHIFT1 || optimize_size)"
12102   "ror{b}\t%0"
12103   [(set_attr "type" "rotate")
12104    (set (attr "length") 
12105      (if_then_else (match_operand 0 "register_operand" "") 
12106         (const_string "2")
12107         (const_string "*")))])
12108
12109 (define_insn "*rotrqi3_1_one_bit_slp"
12110   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12111         (rotatert:QI (match_dup 0)
12112                      (match_operand:QI 1 "const1_operand" "")))
12113    (clobber (reg:CC FLAGS_REG))]
12114   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12115    && (TARGET_SHIFT1 || optimize_size)"
12116   "ror{b}\t%0"
12117   [(set_attr "type" "rotate1")
12118    (set (attr "length") 
12119      (if_then_else (match_operand 0 "register_operand" "") 
12120         (const_string "2")
12121         (const_string "*")))])
12122
12123 (define_insn "*rotrqi3_1"
12124   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12125         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12126                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12129   "@
12130    ror{b}\t{%2, %0|%0, %2}
12131    ror{b}\t{%b2, %0|%0, %b2}"
12132   [(set_attr "type" "rotate")
12133    (set_attr "mode" "QI")])
12134
12135 (define_insn "*rotrqi3_1_slp"
12136   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12137         (rotatert:QI (match_dup 0)
12138                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12141    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12142   "@
12143    ror{b}\t{%1, %0|%0, %1}
12144    ror{b}\t{%b1, %0|%0, %b1}"
12145   [(set_attr "type" "rotate1")
12146    (set_attr "mode" "QI")])
12147 \f
12148 ;; Bit set / bit test instructions
12149
12150 (define_expand "extv"
12151   [(set (match_operand:SI 0 "register_operand" "")
12152         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12153                          (match_operand:SI 2 "immediate_operand" "")
12154                          (match_operand:SI 3 "immediate_operand" "")))]
12155   ""
12156 {
12157   /* Handle extractions from %ah et al.  */
12158   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12159     FAIL;
12160
12161   /* From mips.md: extract_bit_field doesn't verify that our source
12162      matches the predicate, so check it again here.  */
12163   if (! ext_register_operand (operands[1], VOIDmode))
12164     FAIL;
12165 })
12166
12167 (define_expand "extzv"
12168   [(set (match_operand:SI 0 "register_operand" "")
12169         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12170                          (match_operand:SI 2 "immediate_operand" "")
12171                          (match_operand:SI 3 "immediate_operand" "")))]
12172   ""
12173 {
12174   /* Handle extractions from %ah et al.  */
12175   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12176     FAIL;
12177
12178   /* From mips.md: extract_bit_field doesn't verify that our source
12179      matches the predicate, so check it again here.  */
12180   if (! ext_register_operand (operands[1], VOIDmode))
12181     FAIL;
12182 })
12183
12184 (define_expand "insv"
12185   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12186                       (match_operand 1 "immediate_operand" "")
12187                       (match_operand 2 "immediate_operand" ""))
12188         (match_operand 3 "register_operand" ""))]
12189   ""
12190 {
12191   /* Handle extractions from %ah et al.  */
12192   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12193     FAIL;
12194
12195   /* From mips.md: insert_bit_field doesn't verify that our source
12196      matches the predicate, so check it again here.  */
12197   if (! ext_register_operand (operands[0], VOIDmode))
12198     FAIL;
12199
12200   if (TARGET_64BIT)
12201     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12202   else
12203     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12204
12205   DONE;
12206 })
12207
12208 ;; %%% bts, btr, btc, bt.
12209 ;; In general these instructions are *slow* when applied to memory,
12210 ;; since they enforce atomic operation.  When applied to registers,
12211 ;; it depends on the cpu implementation.  They're never faster than
12212 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12213 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12214 ;; within the instruction itself, so operating on bits in the high
12215 ;; 32-bits of a register becomes easier.
12216 ;;
12217 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12218 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12219 ;; negdf respectively, so they can never be disabled entirely.
12220
12221 (define_insn "*btsq"
12222   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12223                          (const_int 1)
12224                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12225         (const_int 1))
12226    (clobber (reg:CC FLAGS_REG))]
12227   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12228   "bts{q} %1,%0"
12229   [(set_attr "type" "alu1")])
12230
12231 (define_insn "*btrq"
12232   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12233                          (const_int 1)
12234                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12235         (const_int 0))
12236    (clobber (reg:CC FLAGS_REG))]
12237   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12238   "btr{q} %1,%0"
12239   [(set_attr "type" "alu1")])
12240
12241 (define_insn "*btcq"
12242   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12243                          (const_int 1)
12244                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12245         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12246    (clobber (reg:CC FLAGS_REG))]
12247   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12248   "btc{q} %1,%0"
12249   [(set_attr "type" "alu1")])
12250
12251 ;; Allow Nocona to avoid these instructions if a register is available.
12252
12253 (define_peephole2
12254   [(match_scratch:DI 2 "r")
12255    (parallel [(set (zero_extract:DI
12256                      (match_operand:DI 0 "register_operand" "")
12257                      (const_int 1)
12258                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12259                    (const_int 1))
12260               (clobber (reg:CC FLAGS_REG))])]
12261   "TARGET_64BIT && !TARGET_USE_BT"
12262   [(const_int 0)]
12263 {
12264   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12265   rtx op1;
12266
12267   if (HOST_BITS_PER_WIDE_INT >= 64)
12268     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12269   else if (i < HOST_BITS_PER_WIDE_INT)
12270     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12271   else
12272     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12273
12274   op1 = immed_double_const (lo, hi, DImode);
12275   if (i >= 31)
12276     {
12277       emit_move_insn (operands[2], op1);
12278       op1 = operands[2];
12279     }
12280
12281   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12282   DONE;
12283 })
12284
12285 (define_peephole2
12286   [(match_scratch:DI 2 "r")
12287    (parallel [(set (zero_extract:DI
12288                      (match_operand:DI 0 "register_operand" "")
12289                      (const_int 1)
12290                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12291                    (const_int 0))
12292               (clobber (reg:CC FLAGS_REG))])]
12293   "TARGET_64BIT && !TARGET_USE_BT"
12294   [(const_int 0)]
12295 {
12296   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12297   rtx op1;
12298
12299   if (HOST_BITS_PER_WIDE_INT >= 64)
12300     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12301   else if (i < HOST_BITS_PER_WIDE_INT)
12302     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12303   else
12304     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12305
12306   op1 = immed_double_const (~lo, ~hi, DImode);
12307   if (i >= 32)
12308     {
12309       emit_move_insn (operands[2], op1);
12310       op1 = operands[2];
12311     }
12312
12313   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12314   DONE;
12315 })
12316
12317 (define_peephole2
12318   [(match_scratch:DI 2 "r")
12319    (parallel [(set (zero_extract:DI
12320                      (match_operand:DI 0 "register_operand" "")
12321                      (const_int 1)
12322                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12323               (not:DI (zero_extract:DI
12324                         (match_dup 0) (const_int 1) (match_dup 1))))
12325               (clobber (reg:CC FLAGS_REG))])]
12326   "TARGET_64BIT && !TARGET_USE_BT"
12327   [(const_int 0)]
12328 {
12329   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12330   rtx op1;
12331
12332   if (HOST_BITS_PER_WIDE_INT >= 64)
12333     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12334   else if (i < HOST_BITS_PER_WIDE_INT)
12335     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12336   else
12337     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12338
12339   op1 = immed_double_const (lo, hi, DImode);
12340   if (i >= 31)
12341     {
12342       emit_move_insn (operands[2], op1);
12343       op1 = operands[2];
12344     }
12345
12346   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12347   DONE;
12348 })
12349 \f
12350 ;; Store-flag instructions.
12351
12352 ;; For all sCOND expanders, also expand the compare or test insn that
12353 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12354
12355 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12356 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12357 ;; way, which can later delete the movzx if only QImode is needed.
12358
12359 (define_expand "seq"
12360   [(set (match_operand:QI 0 "register_operand" "")
12361         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362   ""
12363   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12364
12365 (define_expand "sne"
12366   [(set (match_operand:QI 0 "register_operand" "")
12367         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12368   ""
12369   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12370
12371 (define_expand "sgt"
12372   [(set (match_operand:QI 0 "register_operand" "")
12373         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12374   ""
12375   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12376
12377 (define_expand "sgtu"
12378   [(set (match_operand:QI 0 "register_operand" "")
12379         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12380   ""
12381   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12382
12383 (define_expand "slt"
12384   [(set (match_operand:QI 0 "register_operand" "")
12385         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12386   ""
12387   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12388
12389 (define_expand "sltu"
12390   [(set (match_operand:QI 0 "register_operand" "")
12391         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12392   ""
12393   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12394
12395 (define_expand "sge"
12396   [(set (match_operand:QI 0 "register_operand" "")
12397         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12398   ""
12399   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12400
12401 (define_expand "sgeu"
12402   [(set (match_operand:QI 0 "register_operand" "")
12403         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12404   ""
12405   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12406
12407 (define_expand "sle"
12408   [(set (match_operand:QI 0 "register_operand" "")
12409         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12410   ""
12411   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12412
12413 (define_expand "sleu"
12414   [(set (match_operand:QI 0 "register_operand" "")
12415         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12416   ""
12417   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12418
12419 (define_expand "sunordered"
12420   [(set (match_operand:QI 0 "register_operand" "")
12421         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12422   "TARGET_80387 || TARGET_SSE"
12423   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12424
12425 (define_expand "sordered"
12426   [(set (match_operand:QI 0 "register_operand" "")
12427         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12428   "TARGET_80387"
12429   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12430
12431 (define_expand "suneq"
12432   [(set (match_operand:QI 0 "register_operand" "")
12433         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12434   "TARGET_80387 || TARGET_SSE"
12435   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12436
12437 (define_expand "sunge"
12438   [(set (match_operand:QI 0 "register_operand" "")
12439         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12440   "TARGET_80387 || TARGET_SSE"
12441   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12442
12443 (define_expand "sungt"
12444   [(set (match_operand:QI 0 "register_operand" "")
12445         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12446   "TARGET_80387 || TARGET_SSE"
12447   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12448
12449 (define_expand "sunle"
12450   [(set (match_operand:QI 0 "register_operand" "")
12451         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12452   "TARGET_80387 || TARGET_SSE"
12453   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12454
12455 (define_expand "sunlt"
12456   [(set (match_operand:QI 0 "register_operand" "")
12457         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12458   "TARGET_80387 || TARGET_SSE"
12459   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12460
12461 (define_expand "sltgt"
12462   [(set (match_operand:QI 0 "register_operand" "")
12463         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12464   "TARGET_80387 || TARGET_SSE"
12465   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12466
12467 (define_insn "*setcc_1"
12468   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12469         (match_operator:QI 1 "ix86_comparison_operator"
12470           [(reg FLAGS_REG) (const_int 0)]))]
12471   ""
12472   "set%C1\t%0"
12473   [(set_attr "type" "setcc")
12474    (set_attr "mode" "QI")])
12475
12476 (define_insn "*setcc_2"
12477   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12478         (match_operator:QI 1 "ix86_comparison_operator"
12479           [(reg FLAGS_REG) (const_int 0)]))]
12480   ""
12481   "set%C1\t%0"
12482   [(set_attr "type" "setcc")
12483    (set_attr "mode" "QI")])
12484
12485 ;; In general it is not safe to assume too much about CCmode registers,
12486 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12487 ;; conditions this is safe on x86, so help combine not create
12488 ;;
12489 ;;      seta    %al
12490 ;;      testb   %al, %al
12491 ;;      sete    %al
12492
12493 (define_split 
12494   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12495         (ne:QI (match_operator 1 "ix86_comparison_operator"
12496                  [(reg FLAGS_REG) (const_int 0)])
12497             (const_int 0)))]
12498   ""
12499   [(set (match_dup 0) (match_dup 1))]
12500 {
12501   PUT_MODE (operands[1], QImode);
12502 })
12503
12504 (define_split 
12505   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12506         (ne:QI (match_operator 1 "ix86_comparison_operator"
12507                  [(reg FLAGS_REG) (const_int 0)])
12508             (const_int 0)))]
12509   ""
12510   [(set (match_dup 0) (match_dup 1))]
12511 {
12512   PUT_MODE (operands[1], QImode);
12513 })
12514
12515 (define_split 
12516   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12517         (eq:QI (match_operator 1 "ix86_comparison_operator"
12518                  [(reg FLAGS_REG) (const_int 0)])
12519             (const_int 0)))]
12520   ""
12521   [(set (match_dup 0) (match_dup 1))]
12522 {
12523   rtx new_op1 = copy_rtx (operands[1]);
12524   operands[1] = new_op1;
12525   PUT_MODE (new_op1, QImode);
12526   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12527                                              GET_MODE (XEXP (new_op1, 0))));
12528
12529   /* Make sure that (a) the CCmode we have for the flags is strong
12530      enough for the reversed compare or (b) we have a valid FP compare.  */
12531   if (! ix86_comparison_operator (new_op1, VOIDmode))
12532     FAIL;
12533 })
12534
12535 (define_split 
12536   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12537         (eq:QI (match_operator 1 "ix86_comparison_operator"
12538                  [(reg FLAGS_REG) (const_int 0)])
12539             (const_int 0)))]
12540   ""
12541   [(set (match_dup 0) (match_dup 1))]
12542 {
12543   rtx new_op1 = copy_rtx (operands[1]);
12544   operands[1] = new_op1;
12545   PUT_MODE (new_op1, QImode);
12546   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12547                                              GET_MODE (XEXP (new_op1, 0))));
12548
12549   /* Make sure that (a) the CCmode we have for the flags is strong
12550      enough for the reversed compare or (b) we have a valid FP compare.  */
12551   if (! ix86_comparison_operator (new_op1, VOIDmode))
12552     FAIL;
12553 })
12554
12555 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12556 ;; subsequent logical operations are used to imitate conditional moves.
12557 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12558 ;; it directly.  Further holding this value in pseudo register might bring
12559 ;; problem in implicit normalization in spill code.
12560 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12561 ;; instructions after reload by splitting the conditional move patterns.
12562
12563 (define_insn "*sse_setccsf"
12564   [(set (match_operand:SF 0 "register_operand" "=x")
12565         (match_operator:SF 1 "sse_comparison_operator"
12566           [(match_operand:SF 2 "register_operand" "0")
12567            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12568   "TARGET_SSE && reload_completed"
12569   "cmp%D1ss\t{%3, %0|%0, %3}"
12570   [(set_attr "type" "ssecmp")
12571    (set_attr "mode" "SF")])
12572
12573 (define_insn "*sse_setccdf"
12574   [(set (match_operand:DF 0 "register_operand" "=Y")
12575         (match_operator:DF 1 "sse_comparison_operator"
12576           [(match_operand:DF 2 "register_operand" "0")
12577            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12578   "TARGET_SSE2 && reload_completed"
12579   "cmp%D1sd\t{%3, %0|%0, %3}"
12580   [(set_attr "type" "ssecmp")
12581    (set_attr "mode" "DF")])
12582 \f
12583 ;; Basic conditional jump instructions.
12584 ;; We ignore the overflow flag for signed branch instructions.
12585
12586 ;; For all bCOND expanders, also expand the compare or test insn that
12587 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12588
12589 (define_expand "beq"
12590   [(set (pc)
12591         (if_then_else (match_dup 1)
12592                       (label_ref (match_operand 0 "" ""))
12593                       (pc)))]
12594   ""
12595   "ix86_expand_branch (EQ, operands[0]); DONE;")
12596
12597 (define_expand "bne"
12598   [(set (pc)
12599         (if_then_else (match_dup 1)
12600                       (label_ref (match_operand 0 "" ""))
12601                       (pc)))]
12602   ""
12603   "ix86_expand_branch (NE, operands[0]); DONE;")
12604
12605 (define_expand "bgt"
12606   [(set (pc)
12607         (if_then_else (match_dup 1)
12608                       (label_ref (match_operand 0 "" ""))
12609                       (pc)))]
12610   ""
12611   "ix86_expand_branch (GT, operands[0]); DONE;")
12612
12613 (define_expand "bgtu"
12614   [(set (pc)
12615         (if_then_else (match_dup 1)
12616                       (label_ref (match_operand 0 "" ""))
12617                       (pc)))]
12618   ""
12619   "ix86_expand_branch (GTU, operands[0]); DONE;")
12620
12621 (define_expand "blt"
12622   [(set (pc)
12623         (if_then_else (match_dup 1)
12624                       (label_ref (match_operand 0 "" ""))
12625                       (pc)))]
12626   ""
12627   "ix86_expand_branch (LT, operands[0]); DONE;")
12628
12629 (define_expand "bltu"
12630   [(set (pc)
12631         (if_then_else (match_dup 1)
12632                       (label_ref (match_operand 0 "" ""))
12633                       (pc)))]
12634   ""
12635   "ix86_expand_branch (LTU, operands[0]); DONE;")
12636
12637 (define_expand "bge"
12638   [(set (pc)
12639         (if_then_else (match_dup 1)
12640                       (label_ref (match_operand 0 "" ""))
12641                       (pc)))]
12642   ""
12643   "ix86_expand_branch (GE, operands[0]); DONE;")
12644
12645 (define_expand "bgeu"
12646   [(set (pc)
12647         (if_then_else (match_dup 1)
12648                       (label_ref (match_operand 0 "" ""))
12649                       (pc)))]
12650   ""
12651   "ix86_expand_branch (GEU, operands[0]); DONE;")
12652
12653 (define_expand "ble"
12654   [(set (pc)
12655         (if_then_else (match_dup 1)
12656                       (label_ref (match_operand 0 "" ""))
12657                       (pc)))]
12658   ""
12659   "ix86_expand_branch (LE, operands[0]); DONE;")
12660
12661 (define_expand "bleu"
12662   [(set (pc)
12663         (if_then_else (match_dup 1)
12664                       (label_ref (match_operand 0 "" ""))
12665                       (pc)))]
12666   ""
12667   "ix86_expand_branch (LEU, operands[0]); DONE;")
12668
12669 (define_expand "bunordered"
12670   [(set (pc)
12671         (if_then_else (match_dup 1)
12672                       (label_ref (match_operand 0 "" ""))
12673                       (pc)))]
12674   "TARGET_80387 || TARGET_SSE"
12675   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12676
12677 (define_expand "bordered"
12678   [(set (pc)
12679         (if_then_else (match_dup 1)
12680                       (label_ref (match_operand 0 "" ""))
12681                       (pc)))]
12682   "TARGET_80387 || TARGET_SSE"
12683   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12684
12685 (define_expand "buneq"
12686   [(set (pc)
12687         (if_then_else (match_dup 1)
12688                       (label_ref (match_operand 0 "" ""))
12689                       (pc)))]
12690   "TARGET_80387 || TARGET_SSE"
12691   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12692
12693 (define_expand "bunge"
12694   [(set (pc)
12695         (if_then_else (match_dup 1)
12696                       (label_ref (match_operand 0 "" ""))
12697                       (pc)))]
12698   "TARGET_80387 || TARGET_SSE"
12699   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12700
12701 (define_expand "bungt"
12702   [(set (pc)
12703         (if_then_else (match_dup 1)
12704                       (label_ref (match_operand 0 "" ""))
12705                       (pc)))]
12706   "TARGET_80387 || TARGET_SSE"
12707   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12708
12709 (define_expand "bunle"
12710   [(set (pc)
12711         (if_then_else (match_dup 1)
12712                       (label_ref (match_operand 0 "" ""))
12713                       (pc)))]
12714   "TARGET_80387 || TARGET_SSE"
12715   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12716
12717 (define_expand "bunlt"
12718   [(set (pc)
12719         (if_then_else (match_dup 1)
12720                       (label_ref (match_operand 0 "" ""))
12721                       (pc)))]
12722   "TARGET_80387 || TARGET_SSE"
12723   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12724
12725 (define_expand "bltgt"
12726   [(set (pc)
12727         (if_then_else (match_dup 1)
12728                       (label_ref (match_operand 0 "" ""))
12729                       (pc)))]
12730   "TARGET_80387 || TARGET_SSE"
12731   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12732
12733 (define_insn "*jcc_1"
12734   [(set (pc)
12735         (if_then_else (match_operator 1 "ix86_comparison_operator"
12736                                       [(reg FLAGS_REG) (const_int 0)])
12737                       (label_ref (match_operand 0 "" ""))
12738                       (pc)))]
12739   ""
12740   "%+j%C1\t%l0"
12741   [(set_attr "type" "ibr")
12742    (set_attr "modrm" "0")
12743    (set (attr "length")
12744            (if_then_else (and (ge (minus (match_dup 0) (pc))
12745                                   (const_int -126))
12746                               (lt (minus (match_dup 0) (pc))
12747                                   (const_int 128)))
12748              (const_int 2)
12749              (const_int 6)))])
12750
12751 (define_insn "*jcc_2"
12752   [(set (pc)
12753         (if_then_else (match_operator 1 "ix86_comparison_operator"
12754                                       [(reg FLAGS_REG) (const_int 0)])
12755                       (pc)
12756                       (label_ref (match_operand 0 "" ""))))]
12757   ""
12758   "%+j%c1\t%l0"
12759   [(set_attr "type" "ibr")
12760    (set_attr "modrm" "0")
12761    (set (attr "length")
12762            (if_then_else (and (ge (minus (match_dup 0) (pc))
12763                                   (const_int -126))
12764                               (lt (minus (match_dup 0) (pc))
12765                                   (const_int 128)))
12766              (const_int 2)
12767              (const_int 6)))])
12768
12769 ;; In general it is not safe to assume too much about CCmode registers,
12770 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12771 ;; conditions this is safe on x86, so help combine not create
12772 ;;
12773 ;;      seta    %al
12774 ;;      testb   %al, %al
12775 ;;      je      Lfoo
12776
12777 (define_split 
12778   [(set (pc)
12779         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12780                                       [(reg FLAGS_REG) (const_int 0)])
12781                           (const_int 0))
12782                       (label_ref (match_operand 1 "" ""))
12783                       (pc)))]
12784   ""
12785   [(set (pc)
12786         (if_then_else (match_dup 0)
12787                       (label_ref (match_dup 1))
12788                       (pc)))]
12789 {
12790   PUT_MODE (operands[0], VOIDmode);
12791 })
12792   
12793 (define_split 
12794   [(set (pc)
12795         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12796                                       [(reg FLAGS_REG) (const_int 0)])
12797                           (const_int 0))
12798                       (label_ref (match_operand 1 "" ""))
12799                       (pc)))]
12800   ""
12801   [(set (pc)
12802         (if_then_else (match_dup 0)
12803                       (label_ref (match_dup 1))
12804                       (pc)))]
12805 {
12806   rtx new_op0 = copy_rtx (operands[0]);
12807   operands[0] = new_op0;
12808   PUT_MODE (new_op0, VOIDmode);
12809   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12810                                              GET_MODE (XEXP (new_op0, 0))));
12811
12812   /* Make sure that (a) the CCmode we have for the flags is strong
12813      enough for the reversed compare or (b) we have a valid FP compare.  */
12814   if (! ix86_comparison_operator (new_op0, VOIDmode))
12815     FAIL;
12816 })
12817
12818 ;; Define combination compare-and-branch fp compare instructions to use
12819 ;; during early optimization.  Splitting the operation apart early makes
12820 ;; for bad code when we want to reverse the operation.
12821
12822 (define_insn "*fp_jcc_1"
12823   [(set (pc)
12824         (if_then_else (match_operator 0 "comparison_operator"
12825                         [(match_operand 1 "register_operand" "f")
12826                          (match_operand 2 "register_operand" "f")])
12827           (label_ref (match_operand 3 "" ""))
12828           (pc)))
12829    (clobber (reg:CCFP FPSR_REG))
12830    (clobber (reg:CCFP FLAGS_REG))]
12831   "TARGET_CMOVE && TARGET_80387
12832    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12833    && FLOAT_MODE_P (GET_MODE (operands[1]))
12834    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12835    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12836   "#")
12837
12838 (define_insn "*fp_jcc_1_sse"
12839   [(set (pc)
12840         (if_then_else (match_operator 0 "comparison_operator"
12841                         [(match_operand 1 "register_operand" "f#x,x#f")
12842                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12843           (label_ref (match_operand 3 "" ""))
12844           (pc)))
12845    (clobber (reg:CCFP FPSR_REG))
12846    (clobber (reg:CCFP FLAGS_REG))]
12847   "TARGET_80387
12848    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12849    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12850    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12851   "#")
12852
12853 (define_insn "*fp_jcc_1_sse_only"
12854   [(set (pc)
12855         (if_then_else (match_operator 0 "comparison_operator"
12856                         [(match_operand 1 "register_operand" "x")
12857                          (match_operand 2 "nonimmediate_operand" "xm")])
12858           (label_ref (match_operand 3 "" ""))
12859           (pc)))
12860    (clobber (reg:CCFP FPSR_REG))
12861    (clobber (reg:CCFP FLAGS_REG))]
12862   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12863    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12864    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12865   "#")
12866
12867 (define_insn "*fp_jcc_2"
12868   [(set (pc)
12869         (if_then_else (match_operator 0 "comparison_operator"
12870                         [(match_operand 1 "register_operand" "f")
12871                          (match_operand 2 "register_operand" "f")])
12872           (pc)
12873           (label_ref (match_operand 3 "" ""))))
12874    (clobber (reg:CCFP FPSR_REG))
12875    (clobber (reg:CCFP FLAGS_REG))]
12876   "TARGET_CMOVE && TARGET_80387
12877    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12878    && FLOAT_MODE_P (GET_MODE (operands[1]))
12879    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12880    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12881   "#")
12882
12883 (define_insn "*fp_jcc_2_sse"
12884   [(set (pc)
12885         (if_then_else (match_operator 0 "comparison_operator"
12886                         [(match_operand 1 "register_operand" "f#x,x#f")
12887                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12888           (pc)
12889           (label_ref (match_operand 3 "" ""))))
12890    (clobber (reg:CCFP FPSR_REG))
12891    (clobber (reg:CCFP FLAGS_REG))]
12892   "TARGET_80387
12893    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12894    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12895    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12896   "#")
12897
12898 (define_insn "*fp_jcc_2_sse_only"
12899   [(set (pc)
12900         (if_then_else (match_operator 0 "comparison_operator"
12901                         [(match_operand 1 "register_operand" "x")
12902                          (match_operand 2 "nonimmediate_operand" "xm")])
12903           (pc)
12904           (label_ref (match_operand 3 "" ""))))
12905    (clobber (reg:CCFP FPSR_REG))
12906    (clobber (reg:CCFP FLAGS_REG))]
12907   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12908    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12909    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12910   "#")
12911
12912 (define_insn "*fp_jcc_3"
12913   [(set (pc)
12914         (if_then_else (match_operator 0 "comparison_operator"
12915                         [(match_operand 1 "register_operand" "f")
12916                          (match_operand 2 "nonimmediate_operand" "fm")])
12917           (label_ref (match_operand 3 "" ""))
12918           (pc)))
12919    (clobber (reg:CCFP FPSR_REG))
12920    (clobber (reg:CCFP FLAGS_REG))
12921    (clobber (match_scratch:HI 4 "=a"))]
12922   "TARGET_80387
12923    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12924    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12925    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12926    && SELECT_CC_MODE (GET_CODE (operands[0]),
12927                       operands[1], operands[2]) == CCFPmode
12928    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12929   "#")
12930
12931 (define_insn "*fp_jcc_4"
12932   [(set (pc)
12933         (if_then_else (match_operator 0 "comparison_operator"
12934                         [(match_operand 1 "register_operand" "f")
12935                          (match_operand 2 "nonimmediate_operand" "fm")])
12936           (pc)
12937           (label_ref (match_operand 3 "" ""))))
12938    (clobber (reg:CCFP FPSR_REG))
12939    (clobber (reg:CCFP FLAGS_REG))
12940    (clobber (match_scratch:HI 4 "=a"))]
12941   "TARGET_80387
12942    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12943    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12944    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12945    && SELECT_CC_MODE (GET_CODE (operands[0]),
12946                       operands[1], operands[2]) == CCFPmode
12947    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12948   "#")
12949
12950 (define_insn "*fp_jcc_5"
12951   [(set (pc)
12952         (if_then_else (match_operator 0 "comparison_operator"
12953                         [(match_operand 1 "register_operand" "f")
12954                          (match_operand 2 "register_operand" "f")])
12955           (label_ref (match_operand 3 "" ""))
12956           (pc)))
12957    (clobber (reg:CCFP FPSR_REG))
12958    (clobber (reg:CCFP FLAGS_REG))
12959    (clobber (match_scratch:HI 4 "=a"))]
12960   "TARGET_80387
12961    && FLOAT_MODE_P (GET_MODE (operands[1]))
12962    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12963    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12964   "#")
12965
12966 (define_insn "*fp_jcc_6"
12967   [(set (pc)
12968         (if_then_else (match_operator 0 "comparison_operator"
12969                         [(match_operand 1 "register_operand" "f")
12970                          (match_operand 2 "register_operand" "f")])
12971           (pc)
12972           (label_ref (match_operand 3 "" ""))))
12973    (clobber (reg:CCFP FPSR_REG))
12974    (clobber (reg:CCFP FLAGS_REG))
12975    (clobber (match_scratch:HI 4 "=a"))]
12976   "TARGET_80387
12977    && FLOAT_MODE_P (GET_MODE (operands[1]))
12978    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12979    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12980   "#")
12981
12982 (define_insn "*fp_jcc_7"
12983   [(set (pc)
12984         (if_then_else (match_operator 0 "comparison_operator"
12985                         [(match_operand 1 "register_operand" "f")
12986                          (match_operand 2 "const_double_operand" "C")])
12987           (label_ref (match_operand 3 "" ""))
12988           (pc)))
12989    (clobber (reg:CCFP FPSR_REG))
12990    (clobber (reg:CCFP FLAGS_REG))
12991    (clobber (match_scratch:HI 4 "=a"))]
12992   "TARGET_80387
12993    && FLOAT_MODE_P (GET_MODE (operands[1]))
12994    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12995    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12996    && SELECT_CC_MODE (GET_CODE (operands[0]),
12997                       operands[1], operands[2]) == CCFPmode
12998    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12999   "#")
13000
13001 ;; The order of operands in *fp_jcc_8 is forced by combine in
13002 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13003 ;; with a precedence over other operators and is always put in the first
13004 ;; place. Swap condition and operands to match ficom instruction.
13005
13006 (define_insn "*fp_jcc_8"
13007   [(set (pc)
13008         (if_then_else (match_operator 0 "comparison_operator"
13009                         [(match_operator 1 "float_operator"
13010                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13011                            (match_operand 3 "register_operand" "f,f")])
13012           (label_ref (match_operand 4 "" ""))
13013           (pc)))
13014    (clobber (reg:CCFP FPSR_REG))
13015    (clobber (reg:CCFP FLAGS_REG))
13016    (clobber (match_scratch:HI 5 "=a,a"))]
13017   "TARGET_80387 && TARGET_USE_FIOP
13018    && FLOAT_MODE_P (GET_MODE (operands[3]))
13019    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13020    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13021    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13022    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13023   "#")
13024
13025 (define_split
13026   [(set (pc)
13027         (if_then_else (match_operator 0 "comparison_operator"
13028                         [(match_operand 1 "register_operand" "")
13029                          (match_operand 2 "nonimmediate_operand" "")])
13030           (match_operand 3 "" "")
13031           (match_operand 4 "" "")))
13032    (clobber (reg:CCFP FPSR_REG))
13033    (clobber (reg:CCFP FLAGS_REG))]
13034   "reload_completed"
13035   [(const_int 0)]
13036 {
13037   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13038                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13039   DONE;
13040 })
13041
13042 (define_split
13043   [(set (pc)
13044         (if_then_else (match_operator 0 "comparison_operator"
13045                         [(match_operand 1 "register_operand" "")
13046                          (match_operand 2 "general_operand" "")])
13047           (match_operand 3 "" "")
13048           (match_operand 4 "" "")))
13049    (clobber (reg:CCFP FPSR_REG))
13050    (clobber (reg:CCFP FLAGS_REG))
13051    (clobber (match_scratch:HI 5 "=a"))]
13052   "reload_completed"
13053   [(const_int 0)]
13054 {
13055   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13056                         operands[3], operands[4], operands[5], NULL_RTX);
13057   DONE;
13058 })
13059
13060 (define_split
13061   [(set (pc)
13062         (if_then_else (match_operator 0 "comparison_operator"
13063                         [(match_operator 1 "float_operator"
13064                            [(match_operand:SI 2 "memory_operand" "")])
13065                            (match_operand 3 "register_operand" "")])
13066           (match_operand 4 "" "")
13067           (match_operand 5 "" "")))
13068    (clobber (reg:CCFP FPSR_REG))
13069    (clobber (reg:CCFP FLAGS_REG))
13070    (clobber (match_scratch:HI 6 "=a"))]
13071   "reload_completed"
13072   [(const_int 0)]
13073 {
13074   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13075   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13076                         operands[3], operands[7],
13077                         operands[4], operands[5], operands[6], NULL_RTX);
13078   DONE;
13079 })
13080
13081 ;; %%% Kill this when reload knows how to do it.
13082 (define_split
13083   [(set (pc)
13084         (if_then_else (match_operator 0 "comparison_operator"
13085                         [(match_operator 1 "float_operator"
13086                            [(match_operand:SI 2 "register_operand" "")])
13087                            (match_operand 3 "register_operand" "")])
13088           (match_operand 4 "" "")
13089           (match_operand 5 "" "")))
13090    (clobber (reg:CCFP FPSR_REG))
13091    (clobber (reg:CCFP FLAGS_REG))
13092    (clobber (match_scratch:HI 6 "=a"))]
13093   "reload_completed"
13094   [(const_int 0)]
13095 {
13096   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13097   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13098   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13099                         operands[3], operands[7],
13100                         operands[4], operands[5], operands[6], operands[2]);
13101   DONE;
13102 })
13103 \f
13104 ;; Unconditional and other jump instructions
13105
13106 (define_insn "jump"
13107   [(set (pc)
13108         (label_ref (match_operand 0 "" "")))]
13109   ""
13110   "jmp\t%l0"
13111   [(set_attr "type" "ibr")
13112    (set (attr "length")
13113            (if_then_else (and (ge (minus (match_dup 0) (pc))
13114                                   (const_int -126))
13115                               (lt (minus (match_dup 0) (pc))
13116                                   (const_int 128)))
13117              (const_int 2)
13118              (const_int 5)))
13119    (set_attr "modrm" "0")])
13120
13121 (define_expand "indirect_jump"
13122   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13123   ""
13124   "")
13125
13126 (define_insn "*indirect_jump"
13127   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13128   "!TARGET_64BIT"
13129   "jmp\t%A0"
13130   [(set_attr "type" "ibr")
13131    (set_attr "length_immediate" "0")])
13132
13133 (define_insn "*indirect_jump_rtx64"
13134   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13135   "TARGET_64BIT"
13136   "jmp\t%A0"
13137   [(set_attr "type" "ibr")
13138    (set_attr "length_immediate" "0")])
13139
13140 (define_expand "tablejump"
13141   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13142               (use (label_ref (match_operand 1 "" "")))])]
13143   ""
13144 {
13145   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13146      relative.  Convert the relative address to an absolute address.  */
13147   if (flag_pic)
13148     {
13149       rtx op0, op1;
13150       enum rtx_code code;
13151
13152       if (TARGET_64BIT)
13153         {
13154           code = PLUS;
13155           op0 = operands[0];
13156           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13157         }
13158       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13159         {
13160           code = PLUS;
13161           op0 = operands[0];
13162           op1 = pic_offset_table_rtx;
13163         }
13164       else
13165         {
13166           code = MINUS;
13167           op0 = pic_offset_table_rtx;
13168           op1 = operands[0];
13169         }
13170
13171       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13172                                          OPTAB_DIRECT);
13173     }
13174 })
13175
13176 (define_insn "*tablejump_1"
13177   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13178    (use (label_ref (match_operand 1 "" "")))]
13179   "!TARGET_64BIT"
13180   "jmp\t%A0"
13181   [(set_attr "type" "ibr")
13182    (set_attr "length_immediate" "0")])
13183
13184 (define_insn "*tablejump_1_rtx64"
13185   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13186    (use (label_ref (match_operand 1 "" "")))]
13187   "TARGET_64BIT"
13188   "jmp\t%A0"
13189   [(set_attr "type" "ibr")
13190    (set_attr "length_immediate" "0")])
13191 \f
13192 ;; Loop instruction
13193 ;;
13194 ;; This is all complicated by the fact that since this is a jump insn
13195 ;; we must handle our own reloads.
13196
13197 (define_expand "doloop_end"
13198   [(use (match_operand 0 "" ""))        ; loop pseudo
13199    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13200    (use (match_operand 2 "" ""))        ; max iterations
13201    (use (match_operand 3 "" ""))        ; loop level 
13202    (use (match_operand 4 "" ""))]       ; label
13203   "!TARGET_64BIT && TARGET_USE_LOOP"
13204   "                                 
13205 {
13206   /* Only use cloop on innermost loops.  */
13207   if (INTVAL (operands[3]) > 1)
13208     FAIL;
13209   if (GET_MODE (operands[0]) != SImode)
13210     FAIL;
13211   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13212                                            operands[0]));
13213   DONE;
13214 }")
13215
13216 (define_insn "doloop_end_internal"
13217   [(set (pc)
13218         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13219                           (const_int 1))
13220                       (label_ref (match_operand 0 "" ""))
13221                       (pc)))
13222    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13223         (plus:SI (match_dup 1)
13224                  (const_int -1)))
13225    (clobber (match_scratch:SI 3 "=X,X,r"))
13226    (clobber (reg:CC FLAGS_REG))]
13227   "!TARGET_64BIT && TARGET_USE_LOOP
13228    && (reload_in_progress || reload_completed
13229        || register_operand (operands[2], VOIDmode))"
13230 {
13231   if (which_alternative != 0)
13232     return "#";
13233   if (get_attr_length (insn) == 2)
13234     return "%+loop\t%l0";
13235   else
13236     return "dec{l}\t%1\;%+jne\t%l0";
13237 }
13238   [(set (attr "length")
13239         (if_then_else (and (eq_attr "alternative" "0")
13240                            (and (ge (minus (match_dup 0) (pc))
13241                                     (const_int -126))
13242                                 (lt (minus (match_dup 0) (pc))
13243                                     (const_int 128))))
13244                       (const_int 2)
13245                       (const_int 16)))
13246    ;; We don't know the type before shorten branches.  Optimistically expect
13247    ;; the loop instruction to match.
13248    (set (attr "type") (const_string "ibr"))])
13249
13250 (define_split
13251   [(set (pc)
13252         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13253                           (const_int 1))
13254                       (match_operand 0 "" "")
13255                       (pc)))
13256    (set (match_dup 1)
13257         (plus:SI (match_dup 1)
13258                  (const_int -1)))
13259    (clobber (match_scratch:SI 2 ""))
13260    (clobber (reg:CC FLAGS_REG))]
13261   "!TARGET_64BIT && TARGET_USE_LOOP
13262    && reload_completed
13263    && REGNO (operands[1]) != 2"
13264   [(parallel [(set (reg:CCZ FLAGS_REG)
13265                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13266                                  (const_int 0)))
13267               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13268    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13269                            (match_dup 0)
13270                            (pc)))]
13271   "")
13272   
13273 (define_split
13274   [(set (pc)
13275         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13276                           (const_int 1))
13277                       (match_operand 0 "" "")
13278                       (pc)))
13279    (set (match_operand:SI 2 "nonimmediate_operand" "")
13280         (plus:SI (match_dup 1)
13281                  (const_int -1)))
13282    (clobber (match_scratch:SI 3 ""))
13283    (clobber (reg:CC FLAGS_REG))]
13284   "!TARGET_64BIT && TARGET_USE_LOOP
13285    && reload_completed
13286    && (! REG_P (operands[2])
13287        || ! rtx_equal_p (operands[1], operands[2]))"
13288   [(set (match_dup 3) (match_dup 1))
13289    (parallel [(set (reg:CCZ FLAGS_REG)
13290                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13291                                 (const_int 0)))
13292               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13293    (set (match_dup 2) (match_dup 3))
13294    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13295                            (match_dup 0)
13296                            (pc)))]
13297   "")
13298
13299 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13300
13301 (define_peephole2
13302   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13303    (set (match_operand:QI 1 "register_operand" "")
13304         (match_operator:QI 2 "ix86_comparison_operator"
13305           [(reg FLAGS_REG) (const_int 0)]))
13306    (set (match_operand 3 "q_regs_operand" "")
13307         (zero_extend (match_dup 1)))]
13308   "(peep2_reg_dead_p (3, operands[1])
13309     || operands_match_p (operands[1], operands[3]))
13310    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13311   [(set (match_dup 4) (match_dup 0))
13312    (set (strict_low_part (match_dup 5))
13313         (match_dup 2))]
13314 {
13315   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13316   operands[5] = gen_lowpart (QImode, operands[3]);
13317   ix86_expand_clear (operands[3]);
13318 })
13319
13320 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13321
13322 (define_peephole2
13323   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13324    (set (match_operand:QI 1 "register_operand" "")
13325         (match_operator:QI 2 "ix86_comparison_operator"
13326           [(reg FLAGS_REG) (const_int 0)]))
13327    (parallel [(set (match_operand 3 "q_regs_operand" "")
13328                    (zero_extend (match_dup 1)))
13329               (clobber (reg:CC FLAGS_REG))])]
13330   "(peep2_reg_dead_p (3, operands[1])
13331     || operands_match_p (operands[1], operands[3]))
13332    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13333   [(set (match_dup 4) (match_dup 0))
13334    (set (strict_low_part (match_dup 5))
13335         (match_dup 2))]
13336 {
13337   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13338   operands[5] = gen_lowpart (QImode, operands[3]);
13339   ix86_expand_clear (operands[3]);
13340 })
13341 \f
13342 ;; Call instructions.
13343
13344 ;; The predicates normally associated with named expanders are not properly
13345 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13346 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13347
13348 ;; Call subroutine returning no value.
13349
13350 (define_expand "call_pop"
13351   [(parallel [(call (match_operand:QI 0 "" "")
13352                     (match_operand:SI 1 "" ""))
13353               (set (reg:SI SP_REG)
13354                    (plus:SI (reg:SI SP_REG)
13355                             (match_operand:SI 3 "" "")))])]
13356   "!TARGET_64BIT"
13357 {
13358   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13359   DONE;
13360 })
13361
13362 (define_insn "*call_pop_0"
13363   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13364          (match_operand:SI 1 "" ""))
13365    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13366                             (match_operand:SI 2 "immediate_operand" "")))]
13367   "!TARGET_64BIT"
13368 {
13369   if (SIBLING_CALL_P (insn))
13370     return "jmp\t%P0";
13371   else
13372     return "call\t%P0";
13373 }
13374   [(set_attr "type" "call")])
13375   
13376 (define_insn "*call_pop_1"
13377   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13378          (match_operand:SI 1 "" ""))
13379    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13380                             (match_operand:SI 2 "immediate_operand" "i")))]
13381   "!TARGET_64BIT"
13382 {
13383   if (constant_call_address_operand (operands[0], Pmode))
13384     {
13385       if (SIBLING_CALL_P (insn))
13386         return "jmp\t%P0";
13387       else
13388         return "call\t%P0";
13389     }
13390   if (SIBLING_CALL_P (insn))
13391     return "jmp\t%A0";
13392   else
13393     return "call\t%A0";
13394 }
13395   [(set_attr "type" "call")])
13396
13397 (define_expand "call"
13398   [(call (match_operand:QI 0 "" "")
13399          (match_operand 1 "" ""))
13400    (use (match_operand 2 "" ""))]
13401   ""
13402 {
13403   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13404   DONE;
13405 })
13406
13407 (define_expand "sibcall"
13408   [(call (match_operand:QI 0 "" "")
13409          (match_operand 1 "" ""))
13410    (use (match_operand 2 "" ""))]
13411   ""
13412 {
13413   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13414   DONE;
13415 })
13416
13417 (define_insn "*call_0"
13418   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13419          (match_operand 1 "" ""))]
13420   ""
13421 {
13422   if (SIBLING_CALL_P (insn))
13423     return "jmp\t%P0";
13424   else
13425     return "call\t%P0";
13426 }
13427   [(set_attr "type" "call")])
13428
13429 (define_insn "*call_1"
13430   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13431          (match_operand 1 "" ""))]
13432   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13433 {
13434   if (constant_call_address_operand (operands[0], Pmode))
13435     return "call\t%P0";
13436   return "call\t%A0";
13437 }
13438   [(set_attr "type" "call")])
13439
13440 (define_insn "*sibcall_1"
13441   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13442          (match_operand 1 "" ""))]
13443   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13444 {
13445   if (constant_call_address_operand (operands[0], Pmode))
13446     return "jmp\t%P0";
13447   return "jmp\t%A0";
13448 }
13449   [(set_attr "type" "call")])
13450
13451 (define_insn "*call_1_rex64"
13452   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13453          (match_operand 1 "" ""))]
13454   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13455 {
13456   if (constant_call_address_operand (operands[0], Pmode))
13457     return "call\t%P0";
13458   return "call\t%A0";
13459 }
13460   [(set_attr "type" "call")])
13461
13462 (define_insn "*sibcall_1_rex64"
13463   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13464          (match_operand 1 "" ""))]
13465   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13466   "jmp\t%P0"
13467   [(set_attr "type" "call")])
13468
13469 (define_insn "*sibcall_1_rex64_v"
13470   [(call (mem:QI (reg:DI 40))
13471          (match_operand 0 "" ""))]
13472   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13473   "jmp\t*%%r11"
13474   [(set_attr "type" "call")])
13475
13476
13477 ;; Call subroutine, returning value in operand 0
13478
13479 (define_expand "call_value_pop"
13480   [(parallel [(set (match_operand 0 "" "")
13481                    (call (match_operand:QI 1 "" "")
13482                          (match_operand:SI 2 "" "")))
13483               (set (reg:SI SP_REG)
13484                    (plus:SI (reg:SI SP_REG)
13485                             (match_operand:SI 4 "" "")))])]
13486   "!TARGET_64BIT"
13487 {
13488   ix86_expand_call (operands[0], operands[1], operands[2],
13489                     operands[3], operands[4], 0);
13490   DONE;
13491 })
13492
13493 (define_expand "call_value"
13494   [(set (match_operand 0 "" "")
13495         (call (match_operand:QI 1 "" "")
13496               (match_operand:SI 2 "" "")))
13497    (use (match_operand:SI 3 "" ""))]
13498   ;; Operand 2 not used on the i386.
13499   ""
13500 {
13501   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13502   DONE;
13503 })
13504
13505 (define_expand "sibcall_value"
13506   [(set (match_operand 0 "" "")
13507         (call (match_operand:QI 1 "" "")
13508               (match_operand:SI 2 "" "")))
13509    (use (match_operand:SI 3 "" ""))]
13510   ;; Operand 2 not used on the i386.
13511   ""
13512 {
13513   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13514   DONE;
13515 })
13516
13517 ;; Call subroutine returning any type.
13518
13519 (define_expand "untyped_call"
13520   [(parallel [(call (match_operand 0 "" "")
13521                     (const_int 0))
13522               (match_operand 1 "" "")
13523               (match_operand 2 "" "")])]
13524   ""
13525 {
13526   int i;
13527
13528   /* In order to give reg-stack an easier job in validating two
13529      coprocessor registers as containing a possible return value,
13530      simply pretend the untyped call returns a complex long double
13531      value.  */
13532
13533   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13534                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13535                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13536                     NULL, 0);
13537
13538   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13539     {
13540       rtx set = XVECEXP (operands[2], 0, i);
13541       emit_move_insn (SET_DEST (set), SET_SRC (set));
13542     }
13543
13544   /* The optimizer does not know that the call sets the function value
13545      registers we stored in the result block.  We avoid problems by
13546      claiming that all hard registers are used and clobbered at this
13547      point.  */
13548   emit_insn (gen_blockage (const0_rtx));
13549
13550   DONE;
13551 })
13552 \f
13553 ;; Prologue and epilogue instructions
13554
13555 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13556 ;; all of memory.  This blocks insns from being moved across this point.
13557
13558 (define_insn "blockage"
13559   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13560   ""
13561   ""
13562   [(set_attr "length" "0")])
13563
13564 ;; Insn emitted into the body of a function to return from a function.
13565 ;; This is only done if the function's epilogue is known to be simple.
13566 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13567
13568 (define_expand "return"
13569   [(return)]
13570   "ix86_can_use_return_insn_p ()"
13571 {
13572   if (current_function_pops_args)
13573     {
13574       rtx popc = GEN_INT (current_function_pops_args);
13575       emit_jump_insn (gen_return_pop_internal (popc));
13576       DONE;
13577     }
13578 })
13579
13580 (define_insn "return_internal"
13581   [(return)]
13582   "reload_completed"
13583   "ret"
13584   [(set_attr "length" "1")
13585    (set_attr "length_immediate" "0")
13586    (set_attr "modrm" "0")])
13587
13588 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13589 ;; instruction Athlon and K8 have.
13590
13591 (define_insn "return_internal_long"
13592   [(return)
13593    (unspec [(const_int 0)] UNSPEC_REP)]
13594   "reload_completed"
13595   "rep {;} ret"
13596   [(set_attr "length" "1")
13597    (set_attr "length_immediate" "0")
13598    (set_attr "prefix_rep" "1")
13599    (set_attr "modrm" "0")])
13600
13601 (define_insn "return_pop_internal"
13602   [(return)
13603    (use (match_operand:SI 0 "const_int_operand" ""))]
13604   "reload_completed"
13605   "ret\t%0"
13606   [(set_attr "length" "3")
13607    (set_attr "length_immediate" "2")
13608    (set_attr "modrm" "0")])
13609
13610 (define_insn "return_indirect_internal"
13611   [(return)
13612    (use (match_operand:SI 0 "register_operand" "r"))]
13613   "reload_completed"
13614   "jmp\t%A0"
13615   [(set_attr "type" "ibr")
13616    (set_attr "length_immediate" "0")])
13617
13618 (define_insn "nop"
13619   [(const_int 0)]
13620   ""
13621   "nop"
13622   [(set_attr "length" "1")
13623    (set_attr "length_immediate" "0")
13624    (set_attr "modrm" "0")])
13625
13626 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13627 ;; branch prediction penalty for the third jump in a 16-byte
13628 ;; block on K8.
13629
13630 (define_insn "align"
13631   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13632   ""
13633 {
13634 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13635   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13636 #else
13637   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13638      The align insn is used to avoid 3 jump instructions in the row to improve
13639      branch prediction and the benefits hardly outweight the cost of extra 8
13640      nops on the average inserted by full alignment pseudo operation.  */
13641 #endif
13642   return "";
13643 }
13644   [(set_attr "length" "16")])
13645
13646 (define_expand "prologue"
13647   [(const_int 1)]
13648   ""
13649   "ix86_expand_prologue (); DONE;")
13650
13651 (define_insn "set_got"
13652   [(set (match_operand:SI 0 "register_operand" "=r")
13653         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13654    (clobber (reg:CC FLAGS_REG))]
13655   "!TARGET_64BIT"
13656   { return output_set_got (operands[0]); }
13657   [(set_attr "type" "multi")
13658    (set_attr "length" "12")])
13659
13660 (define_expand "epilogue"
13661   [(const_int 1)]
13662   ""
13663   "ix86_expand_epilogue (1); DONE;")
13664
13665 (define_expand "sibcall_epilogue"
13666   [(const_int 1)]
13667   ""
13668   "ix86_expand_epilogue (0); DONE;")
13669
13670 (define_expand "eh_return"
13671   [(use (match_operand 0 "register_operand" ""))]
13672   ""
13673 {
13674   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13675
13676   /* Tricky bit: we write the address of the handler to which we will
13677      be returning into someone else's stack frame, one word below the
13678      stack address we wish to restore.  */
13679   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13680   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13681   tmp = gen_rtx_MEM (Pmode, tmp);
13682   emit_move_insn (tmp, ra);
13683
13684   if (Pmode == SImode)
13685     emit_jump_insn (gen_eh_return_si (sa));
13686   else
13687     emit_jump_insn (gen_eh_return_di (sa));
13688   emit_barrier ();
13689   DONE;
13690 })
13691
13692 (define_insn_and_split "eh_return_si"
13693   [(set (pc) 
13694         (unspec [(match_operand:SI 0 "register_operand" "c")]
13695                  UNSPEC_EH_RETURN))]
13696   "!TARGET_64BIT"
13697   "#"
13698   "reload_completed"
13699   [(const_int 1)]
13700   "ix86_expand_epilogue (2); DONE;")
13701
13702 (define_insn_and_split "eh_return_di"
13703   [(set (pc) 
13704         (unspec [(match_operand:DI 0 "register_operand" "c")]
13705                  UNSPEC_EH_RETURN))]
13706   "TARGET_64BIT"
13707   "#"
13708   "reload_completed"
13709   [(const_int 1)]
13710   "ix86_expand_epilogue (2); DONE;")
13711
13712 (define_insn "leave"
13713   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13714    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13715    (clobber (mem:BLK (scratch)))]
13716   "!TARGET_64BIT"
13717   "leave"
13718   [(set_attr "type" "leave")])
13719
13720 (define_insn "leave_rex64"
13721   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13722    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13723    (clobber (mem:BLK (scratch)))]
13724   "TARGET_64BIT"
13725   "leave"
13726   [(set_attr "type" "leave")])
13727 \f
13728 (define_expand "ffssi2"
13729   [(parallel
13730      [(set (match_operand:SI 0 "register_operand" "") 
13731            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13732       (clobber (match_scratch:SI 2 ""))
13733       (clobber (reg:CC FLAGS_REG))])]
13734   ""
13735   "")
13736
13737 (define_insn_and_split "*ffs_cmove"
13738   [(set (match_operand:SI 0 "register_operand" "=r") 
13739         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13740    (clobber (match_scratch:SI 2 "=&r"))
13741    (clobber (reg:CC FLAGS_REG))]
13742   "TARGET_CMOVE"
13743   "#"
13744   "&& reload_completed"
13745   [(set (match_dup 2) (const_int -1))
13746    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13747               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13748    (set (match_dup 0) (if_then_else:SI
13749                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13750                         (match_dup 2)
13751                         (match_dup 0)))
13752    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13753               (clobber (reg:CC FLAGS_REG))])]
13754   "")
13755
13756 (define_insn_and_split "*ffs_no_cmove"
13757   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13758         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13759    (clobber (match_scratch:SI 2 "=&q"))
13760    (clobber (reg:CC FLAGS_REG))]
13761   ""
13762   "#"
13763   "reload_completed"
13764   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13765               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13766    (set (strict_low_part (match_dup 3))
13767         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13768    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13769               (clobber (reg:CC FLAGS_REG))])
13770    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13771               (clobber (reg:CC FLAGS_REG))])
13772    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13773               (clobber (reg:CC FLAGS_REG))])]
13774 {
13775   operands[3] = gen_lowpart (QImode, operands[2]);
13776   ix86_expand_clear (operands[2]);
13777 })
13778
13779 (define_insn "*ffssi_1"
13780   [(set (reg:CCZ FLAGS_REG)
13781         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13782                      (const_int 0)))
13783    (set (match_operand:SI 0 "register_operand" "=r")
13784         (ctz:SI (match_dup 1)))]
13785   ""
13786   "bsf{l}\t{%1, %0|%0, %1}"
13787   [(set_attr "prefix_0f" "1")])
13788
13789 (define_expand "ffsdi2"
13790   [(parallel
13791      [(set (match_operand:DI 0 "register_operand" "") 
13792            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13793       (clobber (match_scratch:DI 2 ""))
13794       (clobber (reg:CC FLAGS_REG))])]
13795   "TARGET_64BIT && TARGET_CMOVE"
13796   "")
13797
13798 (define_insn_and_split "*ffs_rex64"
13799   [(set (match_operand:DI 0 "register_operand" "=r") 
13800         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13801    (clobber (match_scratch:DI 2 "=&r"))
13802    (clobber (reg:CC FLAGS_REG))]
13803   "TARGET_64BIT && TARGET_CMOVE"
13804   "#"
13805   "&& reload_completed"
13806   [(set (match_dup 2) (const_int -1))
13807    (parallel [(set (reg:CCZ FLAGS_REG)
13808                    (compare:CCZ (match_dup 1) (const_int 0)))
13809               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13810    (set (match_dup 0) (if_then_else:DI
13811                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13812                         (match_dup 2)
13813                         (match_dup 0)))
13814    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13815               (clobber (reg:CC FLAGS_REG))])]
13816   "")
13817
13818 (define_insn "*ffsdi_1"
13819   [(set (reg:CCZ FLAGS_REG)
13820         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13821                      (const_int 0)))
13822    (set (match_operand:DI 0 "register_operand" "=r")
13823         (ctz:DI (match_dup 1)))]
13824   "TARGET_64BIT"
13825   "bsf{q}\t{%1, %0|%0, %1}"
13826   [(set_attr "prefix_0f" "1")])
13827
13828 (define_insn "ctzsi2"
13829   [(set (match_operand:SI 0 "register_operand" "=r")
13830         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13831    (clobber (reg:CC FLAGS_REG))]
13832   ""
13833   "bsf{l}\t{%1, %0|%0, %1}"
13834   [(set_attr "prefix_0f" "1")])
13835
13836 (define_insn "ctzdi2"
13837   [(set (match_operand:DI 0 "register_operand" "=r")
13838         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13839    (clobber (reg:CC FLAGS_REG))]
13840   "TARGET_64BIT"
13841   "bsf{q}\t{%1, %0|%0, %1}"
13842   [(set_attr "prefix_0f" "1")])
13843
13844 (define_expand "clzsi2"
13845   [(parallel
13846      [(set (match_operand:SI 0 "register_operand" "")
13847            (minus:SI (const_int 31)
13848                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13849       (clobber (reg:CC FLAGS_REG))])
13850    (parallel
13851      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13852       (clobber (reg:CC FLAGS_REG))])]
13853   ""
13854   "")
13855
13856 (define_insn "*bsr"
13857   [(set (match_operand:SI 0 "register_operand" "=r")
13858         (minus:SI (const_int 31)
13859                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13860    (clobber (reg:CC FLAGS_REG))]
13861   ""
13862   "bsr{l}\t{%1, %0|%0, %1}"
13863   [(set_attr "prefix_0f" "1")])
13864
13865 (define_expand "clzdi2"
13866   [(parallel
13867      [(set (match_operand:DI 0 "register_operand" "")
13868            (minus:DI (const_int 63)
13869                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13870       (clobber (reg:CC FLAGS_REG))])
13871    (parallel
13872      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13873       (clobber (reg:CC FLAGS_REG))])]
13874   "TARGET_64BIT"
13875   "")
13876
13877 (define_insn "*bsr_rex64"
13878   [(set (match_operand:DI 0 "register_operand" "=r")
13879         (minus:DI (const_int 63)
13880                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13881    (clobber (reg:CC FLAGS_REG))]
13882   "TARGET_64BIT"
13883   "bsr{q}\t{%1, %0|%0, %1}"
13884   [(set_attr "prefix_0f" "1")])
13885 \f
13886 ;; Thread-local storage patterns for ELF.
13887 ;;
13888 ;; Note that these code sequences must appear exactly as shown
13889 ;; in order to allow linker relaxation.
13890
13891 (define_insn "*tls_global_dynamic_32_gnu"
13892   [(set (match_operand:SI 0 "register_operand" "=a")
13893         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13894                     (match_operand:SI 2 "tls_symbolic_operand" "")
13895                     (match_operand:SI 3 "call_insn_operand" "")]
13896                     UNSPEC_TLS_GD))
13897    (clobber (match_scratch:SI 4 "=d"))
13898    (clobber (match_scratch:SI 5 "=c"))
13899    (clobber (reg:CC FLAGS_REG))]
13900   "!TARGET_64BIT && TARGET_GNU_TLS"
13901   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13902   [(set_attr "type" "multi")
13903    (set_attr "length" "12")])
13904
13905 (define_insn "*tls_global_dynamic_32_sun"
13906   [(set (match_operand:SI 0 "register_operand" "=a")
13907         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13908                     (match_operand:SI 2 "tls_symbolic_operand" "")
13909                     (match_operand:SI 3 "call_insn_operand" "")]
13910                     UNSPEC_TLS_GD))
13911    (clobber (match_scratch:SI 4 "=d"))
13912    (clobber (match_scratch:SI 5 "=c"))
13913    (clobber (reg:CC FLAGS_REG))]
13914   "!TARGET_64BIT && TARGET_SUN_TLS"
13915   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13916         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13917   [(set_attr "type" "multi")
13918    (set_attr "length" "14")])
13919
13920 (define_expand "tls_global_dynamic_32"
13921   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13922                    (unspec:SI
13923                     [(match_dup 2)
13924                      (match_operand:SI 1 "tls_symbolic_operand" "")
13925                      (match_dup 3)]
13926                     UNSPEC_TLS_GD))
13927               (clobber (match_scratch:SI 4 ""))
13928               (clobber (match_scratch:SI 5 ""))
13929               (clobber (reg:CC FLAGS_REG))])]
13930   ""
13931 {
13932   if (flag_pic)
13933     operands[2] = pic_offset_table_rtx;
13934   else
13935     {
13936       operands[2] = gen_reg_rtx (Pmode);
13937       emit_insn (gen_set_got (operands[2]));
13938     }
13939   operands[3] = ix86_tls_get_addr ();
13940 })
13941
13942 (define_insn "*tls_global_dynamic_64"
13943   [(set (match_operand:DI 0 "register_operand" "=a")
13944         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13945                       (match_operand:DI 3 "" "")))
13946    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13947               UNSPEC_TLS_GD)]
13948   "TARGET_64BIT"
13949   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13950   [(set_attr "type" "multi")
13951    (set_attr "length" "16")])
13952
13953 (define_expand "tls_global_dynamic_64"
13954   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13955                    (call (mem:QI (match_dup 2)) (const_int 0)))
13956               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13957                          UNSPEC_TLS_GD)])]
13958   ""
13959 {
13960   operands[2] = ix86_tls_get_addr ();
13961 })
13962
13963 (define_insn "*tls_local_dynamic_base_32_gnu"
13964   [(set (match_operand:SI 0 "register_operand" "=a")
13965         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13966                     (match_operand:SI 2 "call_insn_operand" "")]
13967                    UNSPEC_TLS_LD_BASE))
13968    (clobber (match_scratch:SI 3 "=d"))
13969    (clobber (match_scratch:SI 4 "=c"))
13970    (clobber (reg:CC FLAGS_REG))]
13971   "!TARGET_64BIT && TARGET_GNU_TLS"
13972   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13973   [(set_attr "type" "multi")
13974    (set_attr "length" "11")])
13975
13976 (define_insn "*tls_local_dynamic_base_32_sun"
13977   [(set (match_operand:SI 0 "register_operand" "=a")
13978         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13979                     (match_operand:SI 2 "call_insn_operand" "")]
13980                    UNSPEC_TLS_LD_BASE))
13981    (clobber (match_scratch:SI 3 "=d"))
13982    (clobber (match_scratch:SI 4 "=c"))
13983    (clobber (reg:CC FLAGS_REG))]
13984   "!TARGET_64BIT && TARGET_SUN_TLS"
13985   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13986         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13987   [(set_attr "type" "multi")
13988    (set_attr "length" "13")])
13989
13990 (define_expand "tls_local_dynamic_base_32"
13991   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13992                    (unspec:SI [(match_dup 1) (match_dup 2)]
13993                               UNSPEC_TLS_LD_BASE))
13994               (clobber (match_scratch:SI 3 ""))
13995               (clobber (match_scratch:SI 4 ""))
13996               (clobber (reg:CC FLAGS_REG))])]
13997   ""
13998 {
13999   if (flag_pic)
14000     operands[1] = pic_offset_table_rtx;
14001   else
14002     {
14003       operands[1] = gen_reg_rtx (Pmode);
14004       emit_insn (gen_set_got (operands[1]));
14005     }
14006   operands[2] = ix86_tls_get_addr ();
14007 })
14008
14009 (define_insn "*tls_local_dynamic_base_64"
14010   [(set (match_operand:DI 0 "register_operand" "=a")
14011         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14012                       (match_operand:DI 2 "" "")))
14013    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14014   "TARGET_64BIT"
14015   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14016   [(set_attr "type" "multi")
14017    (set_attr "length" "12")])
14018
14019 (define_expand "tls_local_dynamic_base_64"
14020   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14021                    (call (mem:QI (match_dup 1)) (const_int 0)))
14022               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14023   ""
14024 {
14025   operands[1] = ix86_tls_get_addr ();
14026 })
14027
14028 ;; Local dynamic of a single variable is a lose.  Show combine how
14029 ;; to convert that back to global dynamic.
14030
14031 (define_insn_and_split "*tls_local_dynamic_32_once"
14032   [(set (match_operand:SI 0 "register_operand" "=a")
14033         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14034                              (match_operand:SI 2 "call_insn_operand" "")]
14035                             UNSPEC_TLS_LD_BASE)
14036                  (const:SI (unspec:SI
14037                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14038                             UNSPEC_DTPOFF))))
14039    (clobber (match_scratch:SI 4 "=d"))
14040    (clobber (match_scratch:SI 5 "=c"))
14041    (clobber (reg:CC FLAGS_REG))]
14042   ""
14043   "#"
14044   ""
14045   [(parallel [(set (match_dup 0)
14046                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14047                               UNSPEC_TLS_GD))
14048               (clobber (match_dup 4))
14049               (clobber (match_dup 5))
14050               (clobber (reg:CC FLAGS_REG))])]
14051   "")
14052
14053 ;; Load and add the thread base pointer from %gs:0.
14054
14055 (define_insn "*load_tp_si"
14056   [(set (match_operand:SI 0 "register_operand" "=r")
14057         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14058   "!TARGET_64BIT"
14059   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14060   [(set_attr "type" "imov")
14061    (set_attr "modrm" "0")
14062    (set_attr "length" "7")
14063    (set_attr "memory" "load")
14064    (set_attr "imm_disp" "false")])
14065
14066 (define_insn "*add_tp_si"
14067   [(set (match_operand:SI 0 "register_operand" "=r")
14068         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14069                  (match_operand:SI 1 "register_operand" "0")))
14070    (clobber (reg:CC FLAGS_REG))]
14071   "!TARGET_64BIT"
14072   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14073   [(set_attr "type" "alu")
14074    (set_attr "modrm" "0")
14075    (set_attr "length" "7")
14076    (set_attr "memory" "load")
14077    (set_attr "imm_disp" "false")])
14078
14079 (define_insn "*load_tp_di"
14080   [(set (match_operand:DI 0 "register_operand" "=r")
14081         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14082   "TARGET_64BIT"
14083   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14084   [(set_attr "type" "imov")
14085    (set_attr "modrm" "0")
14086    (set_attr "length" "7")
14087    (set_attr "memory" "load")
14088    (set_attr "imm_disp" "false")])
14089
14090 (define_insn "*add_tp_di"
14091   [(set (match_operand:DI 0 "register_operand" "=r")
14092         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14093                  (match_operand:DI 1 "register_operand" "0")))
14094    (clobber (reg:CC FLAGS_REG))]
14095   "TARGET_64BIT"
14096   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14097   [(set_attr "type" "alu")
14098    (set_attr "modrm" "0")
14099    (set_attr "length" "7")
14100    (set_attr "memory" "load")
14101    (set_attr "imm_disp" "false")])
14102 \f
14103 ;; These patterns match the binary 387 instructions for addM3, subM3,
14104 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14105 ;; SFmode.  The first is the normal insn, the second the same insn but
14106 ;; with one operand a conversion, and the third the same insn but with
14107 ;; the other operand a conversion.  The conversion may be SFmode or
14108 ;; SImode if the target mode DFmode, but only SImode if the target mode
14109 ;; is SFmode.
14110
14111 ;; Gcc is slightly more smart about handling normal two address instructions
14112 ;; so use special patterns for add and mull.
14113
14114 (define_insn "*fop_sf_comm_mixed"
14115   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14116         (match_operator:SF 3 "binary_fp_operator"
14117                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14118                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14119   "TARGET_MIX_SSE_I387
14120    && COMMUTATIVE_ARITH_P (operands[3])
14121    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14122   "* return output_387_binary_op (insn, operands);"
14123   [(set (attr "type") 
14124         (if_then_else (eq_attr "alternative" "1")
14125            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14126               (const_string "ssemul")
14127               (const_string "sseadd"))
14128            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14129               (const_string "fmul")
14130               (const_string "fop"))))
14131    (set_attr "mode" "SF")])
14132
14133 (define_insn "*fop_sf_comm_sse"
14134   [(set (match_operand:SF 0 "register_operand" "=x")
14135         (match_operator:SF 3 "binary_fp_operator"
14136                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14137                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14138   "TARGET_SSE_MATH
14139    && COMMUTATIVE_ARITH_P (operands[3])
14140    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14141   "* return output_387_binary_op (insn, operands);"
14142   [(set (attr "type") 
14143         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14144            (const_string "ssemul")
14145            (const_string "sseadd")))
14146    (set_attr "mode" "SF")])
14147
14148 (define_insn "*fop_sf_comm_i387"
14149   [(set (match_operand:SF 0 "register_operand" "=f")
14150         (match_operator:SF 3 "binary_fp_operator"
14151                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14152                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14153   "TARGET_80387
14154    && COMMUTATIVE_ARITH_P (operands[3])
14155    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14156   "* return output_387_binary_op (insn, operands);"
14157   [(set (attr "type") 
14158         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14159            (const_string "fmul")
14160            (const_string "fop")))
14161    (set_attr "mode" "SF")])
14162
14163 (define_insn "*fop_sf_1_mixed"
14164   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14165         (match_operator:SF 3 "binary_fp_operator"
14166                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14167                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14168   "TARGET_MIX_SSE_I387
14169    && !COMMUTATIVE_ARITH_P (operands[3])
14170    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14171   "* return output_387_binary_op (insn, operands);"
14172   [(set (attr "type") 
14173         (cond [(and (eq_attr "alternative" "2")
14174                     (match_operand:SF 3 "mult_operator" ""))
14175                  (const_string "ssemul")
14176                (and (eq_attr "alternative" "2")
14177                     (match_operand:SF 3 "div_operator" ""))
14178                  (const_string "ssediv")
14179                (eq_attr "alternative" "2")
14180                  (const_string "sseadd")
14181                (match_operand:SF 3 "mult_operator" "") 
14182                  (const_string "fmul")
14183                (match_operand:SF 3 "div_operator" "") 
14184                  (const_string "fdiv")
14185               ]
14186               (const_string "fop")))
14187    (set_attr "mode" "SF")])
14188
14189 (define_insn "*fop_sf_1_sse"
14190   [(set (match_operand:SF 0 "register_operand" "=x")
14191         (match_operator:SF 3 "binary_fp_operator"
14192                         [(match_operand:SF 1 "register_operand" "0")
14193                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14194   "TARGET_SSE_MATH
14195    && !COMMUTATIVE_ARITH_P (operands[3])"
14196   "* return output_387_binary_op (insn, operands);"
14197   [(set (attr "type") 
14198         (cond [(match_operand:SF 3 "mult_operator" "")
14199                  (const_string "ssemul")
14200                (match_operand:SF 3 "div_operator" "")
14201                  (const_string "ssediv")
14202               ]
14203               (const_string "sseadd")))
14204    (set_attr "mode" "SF")])
14205
14206 ;; This pattern is not fully shadowed by the pattern above.
14207 (define_insn "*fop_sf_1_i387"
14208   [(set (match_operand:SF 0 "register_operand" "=f,f")
14209         (match_operator:SF 3 "binary_fp_operator"
14210                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14211                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14212   "TARGET_80387 && !TARGET_SSE_MATH
14213    && !COMMUTATIVE_ARITH_P (operands[3])
14214    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14215   "* return output_387_binary_op (insn, operands);"
14216   [(set (attr "type") 
14217         (cond [(match_operand:SF 3 "mult_operator" "") 
14218                  (const_string "fmul")
14219                (match_operand:SF 3 "div_operator" "") 
14220                  (const_string "fdiv")
14221               ]
14222               (const_string "fop")))
14223    (set_attr "mode" "SF")])
14224
14225
14226 ;; ??? Add SSE splitters for these!
14227 (define_insn "*fop_sf_2_i387"
14228   [(set (match_operand:SF 0 "register_operand" "=f,f")
14229         (match_operator:SF 3 "binary_fp_operator"
14230           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14231            (match_operand:SF 2 "register_operand" "0,0")]))]
14232   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14233   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14234   [(set (attr "type") 
14235         (cond [(match_operand:SF 3 "mult_operator" "") 
14236                  (const_string "fmul")
14237                (match_operand:SF 3 "div_operator" "") 
14238                  (const_string "fdiv")
14239               ]
14240               (const_string "fop")))
14241    (set_attr "fp_int_src" "true")
14242    (set_attr "mode" "SI")])
14243
14244 (define_insn "*fop_sf_3_i387"
14245   [(set (match_operand:SF 0 "register_operand" "=f,f")
14246         (match_operator:SF 3 "binary_fp_operator"
14247           [(match_operand:SF 1 "register_operand" "0,0")
14248            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14249   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14250   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14251   [(set (attr "type") 
14252         (cond [(match_operand:SF 3 "mult_operator" "") 
14253                  (const_string "fmul")
14254                (match_operand:SF 3 "div_operator" "") 
14255                  (const_string "fdiv")
14256               ]
14257               (const_string "fop")))
14258    (set_attr "fp_int_src" "true")
14259    (set_attr "mode" "SI")])
14260
14261 (define_insn "*fop_df_comm_mixed"
14262   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14263         (match_operator:DF 3 "binary_fp_operator"
14264                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14265                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14266   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14267    && COMMUTATIVE_ARITH_P (operands[3])
14268    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14269   "* return output_387_binary_op (insn, operands);"
14270   [(set (attr "type") 
14271         (if_then_else (eq_attr "alternative" "1")
14272            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14273               (const_string "ssemul")
14274               (const_string "sseadd"))
14275            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14276               (const_string "fmul")
14277               (const_string "fop"))))
14278    (set_attr "mode" "DF")])
14279
14280 (define_insn "*fop_df_comm_sse"
14281   [(set (match_operand:DF 0 "register_operand" "=Y")
14282         (match_operator:DF 3 "binary_fp_operator"
14283                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14284                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14285   "TARGET_SSE2 && TARGET_SSE_MATH
14286    && COMMUTATIVE_ARITH_P (operands[3])
14287    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14288   "* return output_387_binary_op (insn, operands);"
14289   [(set (attr "type") 
14290         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14291            (const_string "ssemul")
14292            (const_string "sseadd")))
14293    (set_attr "mode" "DF")])
14294
14295 (define_insn "*fop_df_comm_i387"
14296   [(set (match_operand:DF 0 "register_operand" "=f")
14297         (match_operator:DF 3 "binary_fp_operator"
14298                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14299                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14300   "TARGET_80387
14301    && COMMUTATIVE_ARITH_P (operands[3])
14302    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14303   "* return output_387_binary_op (insn, operands);"
14304   [(set (attr "type") 
14305         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14306            (const_string "fmul")
14307            (const_string "fop")))
14308    (set_attr "mode" "DF")])
14309
14310 (define_insn "*fop_df_1_mixed"
14311   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14312         (match_operator:DF 3 "binary_fp_operator"
14313                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14314                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14315   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14316    && !COMMUTATIVE_ARITH_P (operands[3])
14317    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14318   "* return output_387_binary_op (insn, operands);"
14319   [(set (attr "type") 
14320         (cond [(and (eq_attr "alternative" "2")
14321                     (match_operand:SF 3 "mult_operator" ""))
14322                  (const_string "ssemul")
14323                (and (eq_attr "alternative" "2")
14324                     (match_operand:SF 3 "div_operator" ""))
14325                  (const_string "ssediv")
14326                (eq_attr "alternative" "2")
14327                  (const_string "sseadd")
14328                (match_operand:DF 3 "mult_operator" "") 
14329                  (const_string "fmul")
14330                (match_operand:DF 3 "div_operator" "") 
14331                  (const_string "fdiv")
14332               ]
14333               (const_string "fop")))
14334    (set_attr "mode" "DF")])
14335
14336 (define_insn "*fop_df_1_sse"
14337   [(set (match_operand:DF 0 "register_operand" "=Y")
14338         (match_operator:DF 3 "binary_fp_operator"
14339                         [(match_operand:DF 1 "register_operand" "0")
14340                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14341   "TARGET_SSE2 && TARGET_SSE_MATH
14342    && !COMMUTATIVE_ARITH_P (operands[3])"
14343   "* return output_387_binary_op (insn, operands);"
14344   [(set_attr "mode" "DF")
14345    (set (attr "type") 
14346         (cond [(match_operand:SF 3 "mult_operator" "")
14347                  (const_string "ssemul")
14348                (match_operand:SF 3 "div_operator" "")
14349                  (const_string "ssediv")
14350               ]
14351               (const_string "sseadd")))])
14352
14353 ;; This pattern is not fully shadowed by the pattern above.
14354 (define_insn "*fop_df_1_i387"
14355   [(set (match_operand:DF 0 "register_operand" "=f,f")
14356         (match_operator:DF 3 "binary_fp_operator"
14357                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14358                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14359   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14360    && !COMMUTATIVE_ARITH_P (operands[3])
14361    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14362   "* return output_387_binary_op (insn, operands);"
14363   [(set (attr "type") 
14364         (cond [(match_operand:DF 3 "mult_operator" "") 
14365                  (const_string "fmul")
14366                (match_operand:DF 3 "div_operator" "")
14367                  (const_string "fdiv")
14368               ]
14369               (const_string "fop")))
14370    (set_attr "mode" "DF")])
14371
14372 ;; ??? Add SSE splitters for these!
14373 (define_insn "*fop_df_2_i387"
14374   [(set (match_operand:DF 0 "register_operand" "=f,f")
14375         (match_operator:DF 3 "binary_fp_operator"
14376            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14377             (match_operand:DF 2 "register_operand" "0,0")]))]
14378   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14379   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14380   [(set (attr "type") 
14381         (cond [(match_operand:DF 3 "mult_operator" "") 
14382                  (const_string "fmul")
14383                (match_operand:DF 3 "div_operator" "") 
14384                  (const_string "fdiv")
14385               ]
14386               (const_string "fop")))
14387    (set_attr "fp_int_src" "true")
14388    (set_attr "mode" "SI")])
14389
14390 (define_insn "*fop_df_3_i387"
14391   [(set (match_operand:DF 0 "register_operand" "=f,f")
14392         (match_operator:DF 3 "binary_fp_operator"
14393            [(match_operand:DF 1 "register_operand" "0,0")
14394             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14395   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14396   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14397   [(set (attr "type") 
14398         (cond [(match_operand:DF 3 "mult_operator" "") 
14399                  (const_string "fmul")
14400                (match_operand:DF 3 "div_operator" "") 
14401                  (const_string "fdiv")
14402               ]
14403               (const_string "fop")))
14404    (set_attr "fp_int_src" "true")
14405    (set_attr "mode" "SI")])
14406
14407 (define_insn "*fop_df_4_i387"
14408   [(set (match_operand:DF 0 "register_operand" "=f,f")
14409         (match_operator:DF 3 "binary_fp_operator"
14410            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14411             (match_operand:DF 2 "register_operand" "0,f")]))]
14412   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14413    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14414   "* return output_387_binary_op (insn, operands);"
14415   [(set (attr "type") 
14416         (cond [(match_operand:DF 3 "mult_operator" "") 
14417                  (const_string "fmul")
14418                (match_operand:DF 3 "div_operator" "") 
14419                  (const_string "fdiv")
14420               ]
14421               (const_string "fop")))
14422    (set_attr "mode" "SF")])
14423
14424 (define_insn "*fop_df_5_i387"
14425   [(set (match_operand:DF 0 "register_operand" "=f,f")
14426         (match_operator:DF 3 "binary_fp_operator"
14427           [(match_operand:DF 1 "register_operand" "0,f")
14428            (float_extend:DF
14429             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14430   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14431   "* return output_387_binary_op (insn, operands);"
14432   [(set (attr "type") 
14433         (cond [(match_operand:DF 3 "mult_operator" "") 
14434                  (const_string "fmul")
14435                (match_operand:DF 3 "div_operator" "") 
14436                  (const_string "fdiv")
14437               ]
14438               (const_string "fop")))
14439    (set_attr "mode" "SF")])
14440
14441 (define_insn "*fop_df_6_i387"
14442   [(set (match_operand:DF 0 "register_operand" "=f,f")
14443         (match_operator:DF 3 "binary_fp_operator"
14444           [(float_extend:DF
14445             (match_operand:SF 1 "register_operand" "0,f"))
14446            (float_extend:DF
14447             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14448   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14449   "* return output_387_binary_op (insn, operands);"
14450   [(set (attr "type") 
14451         (cond [(match_operand:DF 3 "mult_operator" "") 
14452                  (const_string "fmul")
14453                (match_operand:DF 3 "div_operator" "") 
14454                  (const_string "fdiv")
14455               ]
14456               (const_string "fop")))
14457    (set_attr "mode" "SF")])
14458
14459 (define_insn "*fop_xf_comm_i387"
14460   [(set (match_operand:XF 0 "register_operand" "=f")
14461         (match_operator:XF 3 "binary_fp_operator"
14462                         [(match_operand:XF 1 "register_operand" "%0")
14463                          (match_operand:XF 2 "register_operand" "f")]))]
14464   "TARGET_80387
14465    && COMMUTATIVE_ARITH_P (operands[3])"
14466   "* return output_387_binary_op (insn, operands);"
14467   [(set (attr "type") 
14468         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14469            (const_string "fmul")
14470            (const_string "fop")))
14471    (set_attr "mode" "XF")])
14472
14473 (define_insn "*fop_xf_1_i387"
14474   [(set (match_operand:XF 0 "register_operand" "=f,f")
14475         (match_operator:XF 3 "binary_fp_operator"
14476                         [(match_operand:XF 1 "register_operand" "0,f")
14477                          (match_operand:XF 2 "register_operand" "f,0")]))]
14478   "TARGET_80387
14479    && !COMMUTATIVE_ARITH_P (operands[3])"
14480   "* return output_387_binary_op (insn, operands);"
14481   [(set (attr "type") 
14482         (cond [(match_operand:XF 3 "mult_operator" "") 
14483                  (const_string "fmul")
14484                (match_operand:XF 3 "div_operator" "") 
14485                  (const_string "fdiv")
14486               ]
14487               (const_string "fop")))
14488    (set_attr "mode" "XF")])
14489
14490 (define_insn "*fop_xf_2_i387"
14491   [(set (match_operand:XF 0 "register_operand" "=f,f")
14492         (match_operator:XF 3 "binary_fp_operator"
14493            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14494             (match_operand:XF 2 "register_operand" "0,0")]))]
14495   "TARGET_80387 && TARGET_USE_FIOP"
14496   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14497   [(set (attr "type") 
14498         (cond [(match_operand:XF 3 "mult_operator" "") 
14499                  (const_string "fmul")
14500                (match_operand:XF 3 "div_operator" "") 
14501                  (const_string "fdiv")
14502               ]
14503               (const_string "fop")))
14504    (set_attr "fp_int_src" "true")
14505    (set_attr "mode" "SI")])
14506
14507 (define_insn "*fop_xf_3_i387"
14508   [(set (match_operand:XF 0 "register_operand" "=f,f")
14509         (match_operator:XF 3 "binary_fp_operator"
14510           [(match_operand:XF 1 "register_operand" "0,0")
14511            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14512   "TARGET_80387 && TARGET_USE_FIOP"
14513   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14514   [(set (attr "type") 
14515         (cond [(match_operand:XF 3 "mult_operator" "") 
14516                  (const_string "fmul")
14517                (match_operand:XF 3 "div_operator" "") 
14518                  (const_string "fdiv")
14519               ]
14520               (const_string "fop")))
14521    (set_attr "fp_int_src" "true")
14522    (set_attr "mode" "SI")])
14523
14524 (define_insn "*fop_xf_4_i387"
14525   [(set (match_operand:XF 0 "register_operand" "=f,f")
14526         (match_operator:XF 3 "binary_fp_operator"
14527            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14528             (match_operand:XF 2 "register_operand" "0,f")]))]
14529   "TARGET_80387"
14530   "* return output_387_binary_op (insn, operands);"
14531   [(set (attr "type") 
14532         (cond [(match_operand:XF 3 "mult_operator" "") 
14533                  (const_string "fmul")
14534                (match_operand:XF 3 "div_operator" "") 
14535                  (const_string "fdiv")
14536               ]
14537               (const_string "fop")))
14538    (set_attr "mode" "SF")])
14539
14540 (define_insn "*fop_xf_5_i387"
14541   [(set (match_operand:XF 0 "register_operand" "=f,f")
14542         (match_operator:XF 3 "binary_fp_operator"
14543           [(match_operand:XF 1 "register_operand" "0,f")
14544            (float_extend:XF
14545             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14546   "TARGET_80387"
14547   "* return output_387_binary_op (insn, operands);"
14548   [(set (attr "type") 
14549         (cond [(match_operand:XF 3 "mult_operator" "") 
14550                  (const_string "fmul")
14551                (match_operand:XF 3 "div_operator" "") 
14552                  (const_string "fdiv")
14553               ]
14554               (const_string "fop")))
14555    (set_attr "mode" "SF")])
14556
14557 (define_insn "*fop_xf_6_i387"
14558   [(set (match_operand:XF 0 "register_operand" "=f,f")
14559         (match_operator:XF 3 "binary_fp_operator"
14560           [(float_extend:XF
14561             (match_operand 1 "register_operand" "0,f"))
14562            (float_extend:XF
14563             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14564   "TARGET_80387"
14565   "* return output_387_binary_op (insn, operands);"
14566   [(set (attr "type") 
14567         (cond [(match_operand:XF 3 "mult_operator" "") 
14568                  (const_string "fmul")
14569                (match_operand:XF 3 "div_operator" "") 
14570                  (const_string "fdiv")
14571               ]
14572               (const_string "fop")))
14573    (set_attr "mode" "SF")])
14574
14575 (define_split
14576   [(set (match_operand 0 "register_operand" "")
14577         (match_operator 3 "binary_fp_operator"
14578            [(float (match_operand:SI 1 "register_operand" ""))
14579             (match_operand 2 "register_operand" "")]))]
14580   "TARGET_80387 && reload_completed
14581    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14582   [(const_int 0)]
14583
14584   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14585   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14586   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14587                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14588                                           GET_MODE (operands[3]),
14589                                           operands[4],
14590                                           operands[2])));
14591   ix86_free_from_memory (GET_MODE (operands[1]));
14592   DONE;
14593 })
14594
14595 (define_split
14596   [(set (match_operand 0 "register_operand" "")
14597         (match_operator 3 "binary_fp_operator"
14598            [(match_operand 1 "register_operand" "")
14599             (float (match_operand:SI 2 "register_operand" ""))]))]
14600   "TARGET_80387 && reload_completed
14601    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14602   [(const_int 0)]
14603 {
14604   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14605   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14606   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14607                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14608                                           GET_MODE (operands[3]),
14609                                           operands[1],
14610                                           operands[4])));
14611   ix86_free_from_memory (GET_MODE (operands[2]));
14612   DONE;
14613 })
14614 \f
14615 ;; FPU special functions.
14616
14617 (define_expand "sqrtsf2"
14618   [(set (match_operand:SF 0 "register_operand" "")
14619         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14620   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14621 {
14622   if (!TARGET_SSE_MATH)
14623     operands[1] = force_reg (SFmode, operands[1]);
14624 })
14625
14626 (define_insn "*sqrtsf2_mixed"
14627   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14628         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14629   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14630   "@
14631    fsqrt
14632    sqrtss\t{%1, %0|%0, %1}"
14633   [(set_attr "type" "fpspc,sse")
14634    (set_attr "mode" "SF,SF")
14635    (set_attr "athlon_decode" "direct,*")])
14636
14637 (define_insn "*sqrtsf2_sse"
14638   [(set (match_operand:SF 0 "register_operand" "=x")
14639         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14640   "TARGET_SSE_MATH"
14641   "sqrtss\t{%1, %0|%0, %1}"
14642   [(set_attr "type" "sse")
14643    (set_attr "mode" "SF")
14644    (set_attr "athlon_decode" "*")])
14645
14646 (define_insn "*sqrtsf2_i387"
14647   [(set (match_operand:SF 0 "register_operand" "=f")
14648         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14649   "TARGET_USE_FANCY_MATH_387"
14650   "fsqrt"
14651   [(set_attr "type" "fpspc")
14652    (set_attr "mode" "SF")
14653    (set_attr "athlon_decode" "direct")])
14654
14655 (define_expand "sqrtdf2"
14656   [(set (match_operand:DF 0 "register_operand" "")
14657         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14658   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14659 {
14660   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14661     operands[1] = force_reg (DFmode, operands[1]);
14662 })
14663
14664 (define_insn "*sqrtdf2_mixed"
14665   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14666         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14667   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14668   "@
14669    fsqrt
14670    sqrtsd\t{%1, %0|%0, %1}"
14671   [(set_attr "type" "fpspc,sse")
14672    (set_attr "mode" "DF,DF")
14673    (set_attr "athlon_decode" "direct,*")])
14674
14675 (define_insn "*sqrtdf2_sse"
14676   [(set (match_operand:DF 0 "register_operand" "=Y")
14677         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14678   "TARGET_SSE2 && TARGET_SSE_MATH"
14679   "sqrtsd\t{%1, %0|%0, %1}"
14680   [(set_attr "type" "sse")
14681    (set_attr "mode" "DF")
14682    (set_attr "athlon_decode" "*")])
14683
14684 (define_insn "*sqrtdf2_i387"
14685   [(set (match_operand:DF 0 "register_operand" "=f")
14686         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14687   "TARGET_USE_FANCY_MATH_387"
14688   "fsqrt"
14689   [(set_attr "type" "fpspc")
14690    (set_attr "mode" "DF")
14691    (set_attr "athlon_decode" "direct")])
14692
14693 (define_insn "*sqrtextendsfdf2_i387"
14694   [(set (match_operand:DF 0 "register_operand" "=f")
14695         (sqrt:DF (float_extend:DF
14696                   (match_operand:SF 1 "register_operand" "0"))))]
14697   "TARGET_USE_FANCY_MATH_387
14698    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14699   "fsqrt"
14700   [(set_attr "type" "fpspc")
14701    (set_attr "mode" "DF")
14702    (set_attr "athlon_decode" "direct")])
14703
14704 (define_insn "sqrtxf2"
14705   [(set (match_operand:XF 0 "register_operand" "=f")
14706         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14707   "TARGET_USE_FANCY_MATH_387 
14708    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14709   "fsqrt"
14710   [(set_attr "type" "fpspc")
14711    (set_attr "mode" "XF")
14712    (set_attr "athlon_decode" "direct")])
14713
14714 (define_insn "*sqrtextendsfxf2_i387"
14715   [(set (match_operand:XF 0 "register_operand" "=f")
14716         (sqrt:XF (float_extend:XF
14717                   (match_operand:SF 1 "register_operand" "0"))))]
14718   "TARGET_USE_FANCY_MATH_387"
14719   "fsqrt"
14720   [(set_attr "type" "fpspc")
14721    (set_attr "mode" "XF")
14722    (set_attr "athlon_decode" "direct")])
14723
14724 (define_insn "*sqrtextenddfxf2_i387"
14725   [(set (match_operand:XF 0 "register_operand" "=f")
14726         (sqrt:XF (float_extend:XF
14727                   (match_operand:DF 1 "register_operand" "0"))))]
14728   "TARGET_USE_FANCY_MATH_387"
14729   "fsqrt"
14730   [(set_attr "type" "fpspc")
14731    (set_attr "mode" "XF")
14732    (set_attr "athlon_decode" "direct")])
14733
14734 (define_insn "fpremxf4"
14735   [(set (match_operand:XF 0 "register_operand" "=f")
14736         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14737                     (match_operand:XF 3 "register_operand" "1")]
14738                    UNSPEC_FPREM_F))
14739    (set (match_operand:XF 1 "register_operand" "=u")
14740         (unspec:XF [(match_dup 2) (match_dup 3)]
14741                    UNSPEC_FPREM_U))
14742    (set (reg:CCFP FPSR_REG)
14743         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14744   "TARGET_USE_FANCY_MATH_387
14745    && flag_unsafe_math_optimizations"
14746   "fprem"
14747   [(set_attr "type" "fpspc")
14748    (set_attr "mode" "XF")])
14749
14750 (define_expand "fmodsf3"
14751   [(use (match_operand:SF 0 "register_operand" ""))
14752    (use (match_operand:SF 1 "register_operand" ""))
14753    (use (match_operand:SF 2 "register_operand" ""))]
14754   "TARGET_USE_FANCY_MATH_387
14755    && flag_unsafe_math_optimizations"
14756 {
14757   rtx label = gen_label_rtx ();
14758
14759   rtx op1 = gen_reg_rtx (XFmode);
14760   rtx op2 = gen_reg_rtx (XFmode);
14761
14762   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14763   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14764
14765   emit_label (label);
14766
14767   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14768   ix86_emit_fp_unordered_jump (label);
14769
14770   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14771   DONE;
14772 })
14773
14774 (define_expand "fmoddf3"
14775   [(use (match_operand:DF 0 "register_operand" ""))
14776    (use (match_operand:DF 1 "register_operand" ""))
14777    (use (match_operand:DF 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_extenddfxf2 (op1, operands[1]));
14787   emit_insn (gen_extenddfxf2 (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_truncxfdf2_i387_noop (operands[0], op1));
14795   DONE;
14796 })
14797
14798 (define_expand "fmodxf3"
14799   [(use (match_operand:XF 0 "register_operand" ""))
14800    (use (match_operand:XF 1 "register_operand" ""))
14801    (use (match_operand:XF 2 "register_operand" ""))]
14802   "TARGET_USE_FANCY_MATH_387
14803    && flag_unsafe_math_optimizations"
14804 {
14805   rtx label = gen_label_rtx ();
14806
14807   emit_label (label);
14808
14809   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14810                            operands[1], operands[2]));
14811   ix86_emit_fp_unordered_jump (label);
14812
14813   emit_move_insn (operands[0], operands[1]);
14814   DONE;
14815 })
14816
14817 (define_insn "fprem1xf4"
14818   [(set (match_operand:XF 0 "register_operand" "=f")
14819         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14820                     (match_operand:XF 3 "register_operand" "1")]
14821                    UNSPEC_FPREM1_F))
14822    (set (match_operand:XF 1 "register_operand" "=u")
14823         (unspec:XF [(match_dup 2) (match_dup 3)]
14824                    UNSPEC_FPREM1_U))
14825    (set (reg:CCFP FPSR_REG)
14826         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14827   "TARGET_USE_FANCY_MATH_387
14828    && flag_unsafe_math_optimizations"
14829   "fprem1"
14830   [(set_attr "type" "fpspc")
14831    (set_attr "mode" "XF")])
14832
14833 (define_expand "dremsf3"
14834   [(use (match_operand:SF 0 "register_operand" ""))
14835    (use (match_operand:SF 1 "register_operand" ""))
14836    (use (match_operand:SF 2 "register_operand" ""))]
14837   "TARGET_USE_FANCY_MATH_387
14838    && flag_unsafe_math_optimizations"
14839 {
14840   rtx label = gen_label_rtx ();
14841
14842   rtx op1 = gen_reg_rtx (XFmode);
14843   rtx op2 = gen_reg_rtx (XFmode);
14844
14845   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14846   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14847
14848   emit_label (label);
14849
14850   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14851   ix86_emit_fp_unordered_jump (label);
14852
14853   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14854   DONE;
14855 })
14856
14857 (define_expand "dremdf3"
14858   [(use (match_operand:DF 0 "register_operand" ""))
14859    (use (match_operand:DF 1 "register_operand" ""))
14860    (use (match_operand:DF 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_extenddfxf2 (op1, operands[1]));
14870   emit_insn (gen_extenddfxf2 (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_truncxfdf2_i387_noop (operands[0], op1));
14878   DONE;
14879 })
14880
14881 (define_expand "dremxf3"
14882   [(use (match_operand:XF 0 "register_operand" ""))
14883    (use (match_operand:XF 1 "register_operand" ""))
14884    (use (match_operand:XF 2 "register_operand" ""))]
14885   "TARGET_USE_FANCY_MATH_387
14886    && flag_unsafe_math_optimizations"
14887 {
14888   rtx label = gen_label_rtx ();
14889
14890   emit_label (label);
14891
14892   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14893                             operands[1], operands[2]));
14894   ix86_emit_fp_unordered_jump (label);
14895
14896   emit_move_insn (operands[0], operands[1]);
14897   DONE;
14898 })
14899
14900 (define_insn "*sindf2"
14901   [(set (match_operand:DF 0 "register_operand" "=f")
14902         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14903   "TARGET_USE_FANCY_MATH_387
14904    && flag_unsafe_math_optimizations"
14905   "fsin"
14906   [(set_attr "type" "fpspc")
14907    (set_attr "mode" "DF")])
14908
14909 (define_insn "*sinsf2"
14910   [(set (match_operand:SF 0 "register_operand" "=f")
14911         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14912   "TARGET_USE_FANCY_MATH_387
14913    && flag_unsafe_math_optimizations"
14914   "fsin"
14915   [(set_attr "type" "fpspc")
14916    (set_attr "mode" "SF")])
14917
14918 (define_insn "*sinextendsfdf2"
14919   [(set (match_operand:DF 0 "register_operand" "=f")
14920         (unspec:DF [(float_extend:DF
14921                      (match_operand:SF 1 "register_operand" "0"))]
14922                    UNSPEC_SIN))]
14923   "TARGET_USE_FANCY_MATH_387
14924    && flag_unsafe_math_optimizations"
14925   "fsin"
14926   [(set_attr "type" "fpspc")
14927    (set_attr "mode" "DF")])
14928
14929 (define_insn "*sinxf2"
14930   [(set (match_operand:XF 0 "register_operand" "=f")
14931         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14932   "TARGET_USE_FANCY_MATH_387
14933    && flag_unsafe_math_optimizations"
14934   "fsin"
14935   [(set_attr "type" "fpspc")
14936    (set_attr "mode" "XF")])
14937
14938 (define_insn "*cosdf2"
14939   [(set (match_operand:DF 0 "register_operand" "=f")
14940         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14941   "TARGET_USE_FANCY_MATH_387
14942    && flag_unsafe_math_optimizations"
14943   "fcos"
14944   [(set_attr "type" "fpspc")
14945    (set_attr "mode" "DF")])
14946
14947 (define_insn "*cossf2"
14948   [(set (match_operand:SF 0 "register_operand" "=f")
14949         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14950   "TARGET_USE_FANCY_MATH_387
14951    && flag_unsafe_math_optimizations"
14952   "fcos"
14953   [(set_attr "type" "fpspc")
14954    (set_attr "mode" "SF")])
14955
14956 (define_insn "*cosextendsfdf2"
14957   [(set (match_operand:DF 0 "register_operand" "=f")
14958         (unspec:DF [(float_extend:DF
14959                      (match_operand:SF 1 "register_operand" "0"))]
14960                    UNSPEC_COS))]
14961   "TARGET_USE_FANCY_MATH_387
14962    && flag_unsafe_math_optimizations"
14963   "fcos"
14964   [(set_attr "type" "fpspc")
14965    (set_attr "mode" "DF")])
14966
14967 (define_insn "*cosxf2"
14968   [(set (match_operand:XF 0 "register_operand" "=f")
14969         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14970   "TARGET_USE_FANCY_MATH_387
14971    && flag_unsafe_math_optimizations"
14972   "fcos"
14973   [(set_attr "type" "fpspc")
14974    (set_attr "mode" "XF")])
14975
14976 ;; With sincos pattern defined, sin and cos builtin function will be
14977 ;; expanded to sincos pattern with one of its outputs left unused. 
14978 ;; Cse pass  will detected, if two sincos patterns can be combined,
14979 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14980 ;; depending on the unused output.
14981
14982 (define_insn "sincosdf3"
14983   [(set (match_operand:DF 0 "register_operand" "=f")
14984         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14985                    UNSPEC_SINCOS_COS))
14986    (set (match_operand:DF 1 "register_operand" "=u")
14987         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14988   "TARGET_USE_FANCY_MATH_387
14989    && flag_unsafe_math_optimizations"
14990   "fsincos"
14991   [(set_attr "type" "fpspc")
14992    (set_attr "mode" "DF")])
14993
14994 (define_split
14995   [(set (match_operand:DF 0 "register_operand" "")
14996         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14997                    UNSPEC_SINCOS_COS))
14998    (set (match_operand:DF 1 "register_operand" "")
14999         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15000   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15001    && !reload_completed && !reload_in_progress"
15002   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15003   "")
15004
15005 (define_split
15006   [(set (match_operand:DF 0 "register_operand" "")
15007         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15008                    UNSPEC_SINCOS_COS))
15009    (set (match_operand:DF 1 "register_operand" "")
15010         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15011   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15012    && !reload_completed && !reload_in_progress"
15013   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15014   "")
15015
15016 (define_insn "sincossf3"
15017   [(set (match_operand:SF 0 "register_operand" "=f")
15018         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15019                    UNSPEC_SINCOS_COS))
15020    (set (match_operand:SF 1 "register_operand" "=u")
15021         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15022   "TARGET_USE_FANCY_MATH_387
15023    && flag_unsafe_math_optimizations"
15024   "fsincos"
15025   [(set_attr "type" "fpspc")
15026    (set_attr "mode" "SF")])
15027
15028 (define_split
15029   [(set (match_operand:SF 0 "register_operand" "")
15030         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15031                    UNSPEC_SINCOS_COS))
15032    (set (match_operand:SF 1 "register_operand" "")
15033         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15034   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15035    && !reload_completed && !reload_in_progress"
15036   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15037   "")
15038
15039 (define_split
15040   [(set (match_operand:SF 0 "register_operand" "")
15041         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15042                    UNSPEC_SINCOS_COS))
15043    (set (match_operand:SF 1 "register_operand" "")
15044         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15045   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15046    && !reload_completed && !reload_in_progress"
15047   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15048   "")
15049
15050 (define_insn "*sincosextendsfdf3"
15051   [(set (match_operand:DF 0 "register_operand" "=f")
15052         (unspec:DF [(float_extend:DF
15053                      (match_operand:SF 2 "register_operand" "0"))]
15054                    UNSPEC_SINCOS_COS))
15055    (set (match_operand:DF 1 "register_operand" "=u")
15056         (unspec:DF [(float_extend:DF
15057                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15058   "TARGET_USE_FANCY_MATH_387
15059    && flag_unsafe_math_optimizations"
15060   "fsincos"
15061   [(set_attr "type" "fpspc")
15062    (set_attr "mode" "DF")])
15063
15064 (define_split
15065   [(set (match_operand:DF 0 "register_operand" "")
15066         (unspec:DF [(float_extend:DF
15067                      (match_operand:SF 2 "register_operand" ""))]
15068                    UNSPEC_SINCOS_COS))
15069    (set (match_operand:DF 1 "register_operand" "")
15070         (unspec:DF [(float_extend:DF
15071                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15072   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15073    && !reload_completed && !reload_in_progress"
15074   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15075                                    (match_dup 2))] UNSPEC_SIN))]
15076   "")
15077
15078 (define_split
15079   [(set (match_operand:DF 0 "register_operand" "")
15080         (unspec:DF [(float_extend:DF
15081                      (match_operand:SF 2 "register_operand" ""))]
15082                    UNSPEC_SINCOS_COS))
15083    (set (match_operand:DF 1 "register_operand" "")
15084         (unspec:DF [(float_extend:DF
15085                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15086   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15087    && !reload_completed && !reload_in_progress"
15088   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15089                                    (match_dup 2))] UNSPEC_COS))]
15090   "")
15091
15092 (define_insn "sincosxf3"
15093   [(set (match_operand:XF 0 "register_operand" "=f")
15094         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15095                    UNSPEC_SINCOS_COS))
15096    (set (match_operand:XF 1 "register_operand" "=u")
15097         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15098   "TARGET_USE_FANCY_MATH_387
15099    && flag_unsafe_math_optimizations"
15100   "fsincos"
15101   [(set_attr "type" "fpspc")
15102    (set_attr "mode" "XF")])
15103
15104 (define_split
15105   [(set (match_operand:XF 0 "register_operand" "")
15106         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15107                    UNSPEC_SINCOS_COS))
15108    (set (match_operand:XF 1 "register_operand" "")
15109         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15110   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15111    && !reload_completed && !reload_in_progress"
15112   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15113   "")
15114
15115 (define_split
15116   [(set (match_operand:XF 0 "register_operand" "")
15117         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15118                    UNSPEC_SINCOS_COS))
15119    (set (match_operand:XF 1 "register_operand" "")
15120         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15121   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15122    && !reload_completed && !reload_in_progress"
15123   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15124   "")
15125
15126 (define_insn "*tandf3_1"
15127   [(set (match_operand:DF 0 "register_operand" "=f")
15128         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15129                    UNSPEC_TAN_ONE))
15130    (set (match_operand:DF 1 "register_operand" "=u")
15131         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15132   "TARGET_USE_FANCY_MATH_387
15133    && flag_unsafe_math_optimizations"
15134   "fptan"
15135   [(set_attr "type" "fpspc")
15136    (set_attr "mode" "DF")])
15137
15138 ;; optimize sequence: fptan
15139 ;;                    fstp    %st(0)
15140 ;;                    fld1
15141 ;; into fptan insn.
15142
15143 (define_peephole2
15144   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15145                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15146                              UNSPEC_TAN_ONE))
15147              (set (match_operand:DF 1 "register_operand" "")
15148                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15149    (set (match_dup 0)
15150         (match_operand:DF 3 "immediate_operand" ""))]
15151   "standard_80387_constant_p (operands[3]) == 2"
15152   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15153              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15154   "")
15155
15156 (define_expand "tandf2"
15157   [(parallel [(set (match_dup 2)
15158                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15159                               UNSPEC_TAN_ONE))
15160               (set (match_operand:DF 0 "register_operand" "")
15161                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15162   "TARGET_USE_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15164 {
15165   operands[2] = gen_reg_rtx (DFmode);
15166 })
15167
15168 (define_insn "*tansf3_1"
15169   [(set (match_operand:SF 0 "register_operand" "=f")
15170         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15171                    UNSPEC_TAN_ONE))
15172    (set (match_operand:SF 1 "register_operand" "=u")
15173         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15174   "TARGET_USE_FANCY_MATH_387
15175    && flag_unsafe_math_optimizations"
15176   "fptan"
15177   [(set_attr "type" "fpspc")
15178    (set_attr "mode" "SF")])
15179
15180 ;; optimize sequence: fptan
15181 ;;                    fstp    %st(0)
15182 ;;                    fld1
15183 ;; into fptan insn.
15184
15185 (define_peephole2
15186   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15187                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15188                              UNSPEC_TAN_ONE))
15189              (set (match_operand:SF 1 "register_operand" "")
15190                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15191    (set (match_dup 0)
15192         (match_operand:SF 3 "immediate_operand" ""))]
15193   "standard_80387_constant_p (operands[3]) == 2"
15194   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15195              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15196   "")
15197
15198 (define_expand "tansf2"
15199   [(parallel [(set (match_dup 2)
15200                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15201                               UNSPEC_TAN_ONE))
15202               (set (match_operand:SF 0 "register_operand" "")
15203                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15204   "TARGET_USE_FANCY_MATH_387
15205    && flag_unsafe_math_optimizations"
15206 {
15207   operands[2] = gen_reg_rtx (SFmode);
15208 })
15209
15210 (define_insn "*tanxf3_1"
15211   [(set (match_operand:XF 0 "register_operand" "=f")
15212         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15213                    UNSPEC_TAN_ONE))
15214    (set (match_operand:XF 1 "register_operand" "=u")
15215         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15216   "TARGET_USE_FANCY_MATH_387
15217    && flag_unsafe_math_optimizations"
15218   "fptan"
15219   [(set_attr "type" "fpspc")
15220    (set_attr "mode" "XF")])
15221
15222 ;; optimize sequence: fptan
15223 ;;                    fstp    %st(0)
15224 ;;                    fld1
15225 ;; into fptan insn.
15226
15227 (define_peephole2
15228   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15229                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15230                              UNSPEC_TAN_ONE))
15231              (set (match_operand:XF 1 "register_operand" "")
15232                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15233    (set (match_dup 0)
15234         (match_operand:XF 3 "immediate_operand" ""))]
15235   "standard_80387_constant_p (operands[3]) == 2"
15236   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15237              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15238   "")
15239
15240 (define_expand "tanxf2"
15241   [(parallel [(set (match_dup 2)
15242                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15243                               UNSPEC_TAN_ONE))
15244               (set (match_operand:XF 0 "register_operand" "")
15245                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15246   "TARGET_USE_FANCY_MATH_387
15247    && flag_unsafe_math_optimizations"
15248 {
15249   operands[2] = gen_reg_rtx (XFmode);
15250 })
15251
15252 (define_insn "atan2df3_1"
15253   [(set (match_operand:DF 0 "register_operand" "=f")
15254         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15255                     (match_operand:DF 1 "register_operand" "u")]
15256                    UNSPEC_FPATAN))
15257    (clobber (match_scratch:DF 3 "=1"))]
15258   "TARGET_USE_FANCY_MATH_387
15259    && flag_unsafe_math_optimizations"
15260   "fpatan"
15261   [(set_attr "type" "fpspc")
15262    (set_attr "mode" "DF")])
15263
15264 (define_expand "atan2df3"
15265   [(use (match_operand:DF 0 "register_operand" "=f"))
15266    (use (match_operand:DF 2 "register_operand" "0"))
15267    (use (match_operand:DF 1 "register_operand" "u"))]
15268   "TARGET_USE_FANCY_MATH_387
15269    && flag_unsafe_math_optimizations"
15270 {
15271   rtx copy = gen_reg_rtx (DFmode);
15272   emit_move_insn (copy, operands[1]);
15273   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15274   DONE;
15275 })
15276
15277 (define_expand "atandf2"
15278   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15279                    (unspec:DF [(match_dup 2)
15280                                (match_operand:DF 1 "register_operand" "")]
15281                     UNSPEC_FPATAN))
15282               (clobber (match_scratch:DF 3 ""))])]
15283   "TARGET_USE_FANCY_MATH_387
15284    && flag_unsafe_math_optimizations"
15285 {
15286   operands[2] = gen_reg_rtx (DFmode);
15287   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15288 })
15289
15290 (define_insn "atan2sf3_1"
15291   [(set (match_operand:SF 0 "register_operand" "=f")
15292         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15293                     (match_operand:SF 1 "register_operand" "u")]
15294                    UNSPEC_FPATAN))
15295    (clobber (match_scratch:SF 3 "=1"))]
15296   "TARGET_USE_FANCY_MATH_387
15297    && flag_unsafe_math_optimizations"
15298   "fpatan"
15299   [(set_attr "type" "fpspc")
15300    (set_attr "mode" "SF")])
15301
15302 (define_expand "atan2sf3"
15303   [(use (match_operand:SF 0 "register_operand" "=f"))
15304    (use (match_operand:SF 2 "register_operand" "0"))
15305    (use (match_operand:SF 1 "register_operand" "u"))]
15306   "TARGET_USE_FANCY_MATH_387
15307    && flag_unsafe_math_optimizations"
15308 {
15309   rtx copy = gen_reg_rtx (SFmode);
15310   emit_move_insn (copy, operands[1]);
15311   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15312   DONE;
15313 })
15314
15315 (define_expand "atansf2"
15316   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15317                    (unspec:SF [(match_dup 2)
15318                                (match_operand:SF 1 "register_operand" "")]
15319                     UNSPEC_FPATAN))
15320               (clobber (match_scratch:SF 3 ""))])]
15321   "TARGET_USE_FANCY_MATH_387
15322    && flag_unsafe_math_optimizations"
15323 {
15324   operands[2] = gen_reg_rtx (SFmode);
15325   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15326 })
15327
15328 (define_insn "atan2xf3_1"
15329   [(set (match_operand:XF 0 "register_operand" "=f")
15330         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15331                     (match_operand:XF 1 "register_operand" "u")]
15332                    UNSPEC_FPATAN))
15333    (clobber (match_scratch:XF 3 "=1"))]
15334   "TARGET_USE_FANCY_MATH_387
15335    && flag_unsafe_math_optimizations"
15336   "fpatan"
15337   [(set_attr "type" "fpspc")
15338    (set_attr "mode" "XF")])
15339
15340 (define_expand "atan2xf3"
15341   [(use (match_operand:XF 0 "register_operand" "=f"))
15342    (use (match_operand:XF 2 "register_operand" "0"))
15343    (use (match_operand:XF 1 "register_operand" "u"))]
15344   "TARGET_USE_FANCY_MATH_387
15345    && flag_unsafe_math_optimizations"
15346 {
15347   rtx copy = gen_reg_rtx (XFmode);
15348   emit_move_insn (copy, operands[1]);
15349   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15350   DONE;
15351 })
15352
15353 (define_expand "atanxf2"
15354   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15355                    (unspec:XF [(match_dup 2)
15356                                (match_operand:XF 1 "register_operand" "")]
15357                     UNSPEC_FPATAN))
15358               (clobber (match_scratch:XF 3 ""))])]
15359   "TARGET_USE_FANCY_MATH_387
15360    && flag_unsafe_math_optimizations"
15361 {
15362   operands[2] = gen_reg_rtx (XFmode);
15363   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15364 })
15365
15366 (define_expand "asindf2"
15367   [(set (match_dup 2)
15368         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15369    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15370    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15371    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15372    (parallel [(set (match_dup 7)
15373                    (unspec:XF [(match_dup 6) (match_dup 2)]
15374                               UNSPEC_FPATAN))
15375               (clobber (match_scratch:XF 8 ""))])
15376    (set (match_operand:DF 0 "register_operand" "")
15377         (float_truncate:DF (match_dup 7)))]
15378   "TARGET_USE_FANCY_MATH_387
15379    && flag_unsafe_math_optimizations"
15380 {
15381   int i;
15382
15383   for (i=2; i<8; i++)
15384     operands[i] = gen_reg_rtx (XFmode);
15385
15386   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15387 })
15388
15389 (define_expand "asinsf2"
15390   [(set (match_dup 2)
15391         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15392    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15393    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15394    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15395    (parallel [(set (match_dup 7)
15396                    (unspec:XF [(match_dup 6) (match_dup 2)]
15397                               UNSPEC_FPATAN))
15398               (clobber (match_scratch:XF 8 ""))])
15399    (set (match_operand:SF 0 "register_operand" "")
15400         (float_truncate:SF (match_dup 7)))]
15401   "TARGET_USE_FANCY_MATH_387
15402    && flag_unsafe_math_optimizations"
15403 {
15404   int i;
15405
15406   for (i=2; i<8; i++)
15407     operands[i] = gen_reg_rtx (XFmode);
15408
15409   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15410 })
15411
15412 (define_expand "asinxf2"
15413   [(set (match_dup 2)
15414         (mult:XF (match_operand:XF 1 "register_operand" "")
15415                  (match_dup 1)))
15416    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15417    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15418    (parallel [(set (match_operand:XF 0 "register_operand" "")
15419                    (unspec:XF [(match_dup 5) (match_dup 1)]
15420                               UNSPEC_FPATAN))
15421               (clobber (match_scratch:XF 6 ""))])]
15422   "TARGET_USE_FANCY_MATH_387
15423    && flag_unsafe_math_optimizations"
15424 {
15425   int i;
15426
15427   for (i=2; i<6; i++)
15428     operands[i] = gen_reg_rtx (XFmode);
15429
15430   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15431 })
15432
15433 (define_expand "acosdf2"
15434   [(set (match_dup 2)
15435         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15436    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15437    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15438    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15439    (parallel [(set (match_dup 7)
15440                    (unspec:XF [(match_dup 2) (match_dup 6)]
15441                               UNSPEC_FPATAN))
15442               (clobber (match_scratch:XF 8 ""))])
15443    (set (match_operand:DF 0 "register_operand" "")
15444         (float_truncate:DF (match_dup 7)))]
15445   "TARGET_USE_FANCY_MATH_387
15446    && flag_unsafe_math_optimizations"
15447 {
15448   int i;
15449
15450   for (i=2; i<8; i++)
15451     operands[i] = gen_reg_rtx (XFmode);
15452
15453   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15454 })
15455
15456 (define_expand "acossf2"
15457   [(set (match_dup 2)
15458         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15459    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15460    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15461    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15462    (parallel [(set (match_dup 7)
15463                    (unspec:XF [(match_dup 2) (match_dup 6)]
15464                               UNSPEC_FPATAN))
15465               (clobber (match_scratch:XF 8 ""))])
15466    (set (match_operand:SF 0 "register_operand" "")
15467         (float_truncate:SF (match_dup 7)))]
15468   "TARGET_USE_FANCY_MATH_387
15469    && flag_unsafe_math_optimizations"
15470 {
15471   int i;
15472
15473   for (i=2; i<8; i++)
15474     operands[i] = gen_reg_rtx (XFmode);
15475
15476   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15477 })
15478
15479 (define_expand "acosxf2"
15480   [(set (match_dup 2)
15481         (mult:XF (match_operand:XF 1 "register_operand" "")
15482                  (match_dup 1)))
15483    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15484    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15485    (parallel [(set (match_operand:XF 0 "register_operand" "")
15486                    (unspec:XF [(match_dup 1) (match_dup 5)]
15487                               UNSPEC_FPATAN))
15488               (clobber (match_scratch:XF 6 ""))])]
15489   "TARGET_USE_FANCY_MATH_387
15490    && flag_unsafe_math_optimizations"
15491 {
15492   int i;
15493
15494   for (i=2; i<6; i++)
15495     operands[i] = gen_reg_rtx (XFmode);
15496
15497   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15498 })
15499
15500 (define_insn "fyl2x_xf3"
15501   [(set (match_operand:XF 0 "register_operand" "=f")
15502         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15503                     (match_operand:XF 1 "register_operand" "u")]
15504                    UNSPEC_FYL2X))
15505    (clobber (match_scratch:XF 3 "=1"))]
15506   "TARGET_USE_FANCY_MATH_387
15507    && flag_unsafe_math_optimizations"
15508   "fyl2x"
15509   [(set_attr "type" "fpspc")
15510    (set_attr "mode" "XF")])
15511
15512 (define_expand "logsf2"
15513   [(set (match_dup 2)
15514         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15515    (parallel [(set (match_dup 4)
15516                    (unspec:XF [(match_dup 2)
15517                                (match_dup 3)] UNSPEC_FYL2X))
15518               (clobber (match_scratch:XF 5 ""))])
15519    (set (match_operand:SF 0 "register_operand" "")
15520         (float_truncate:SF (match_dup 4)))]
15521   "TARGET_USE_FANCY_MATH_387
15522    && flag_unsafe_math_optimizations"
15523 {
15524   rtx temp;
15525
15526   operands[2] = gen_reg_rtx (XFmode);
15527   operands[3] = gen_reg_rtx (XFmode);
15528   operands[4] = gen_reg_rtx (XFmode);
15529
15530   temp = standard_80387_constant_rtx (4); /* fldln2 */
15531   emit_move_insn (operands[3], temp);
15532 })
15533
15534 (define_expand "logdf2"
15535   [(set (match_dup 2)
15536         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15537    (parallel [(set (match_dup 4)
15538                    (unspec:XF [(match_dup 2)
15539                                (match_dup 3)] UNSPEC_FYL2X))
15540               (clobber (match_scratch:XF 5 ""))])
15541    (set (match_operand:DF 0 "register_operand" "")
15542         (float_truncate:DF (match_dup 4)))]
15543   "TARGET_USE_FANCY_MATH_387
15544    && flag_unsafe_math_optimizations"
15545 {
15546   rtx temp;
15547
15548   operands[2] = gen_reg_rtx (XFmode);
15549   operands[3] = gen_reg_rtx (XFmode);
15550   operands[4] = gen_reg_rtx (XFmode);
15551
15552   temp = standard_80387_constant_rtx (4); /* fldln2 */
15553   emit_move_insn (operands[3], temp);
15554 })
15555
15556 (define_expand "logxf2"
15557   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15558                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15559                                (match_dup 2)] UNSPEC_FYL2X))
15560               (clobber (match_scratch:XF 3 ""))])]
15561   "TARGET_USE_FANCY_MATH_387
15562    && flag_unsafe_math_optimizations"
15563 {
15564   rtx temp;
15565
15566   operands[2] = gen_reg_rtx (XFmode);
15567   temp = standard_80387_constant_rtx (4); /* fldln2 */
15568   emit_move_insn (operands[2], temp);
15569 })
15570
15571 (define_expand "log10sf2"
15572   [(set (match_dup 2)
15573         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15574    (parallel [(set (match_dup 4)
15575                    (unspec:XF [(match_dup 2)
15576                                (match_dup 3)] UNSPEC_FYL2X))
15577               (clobber (match_scratch:XF 5 ""))])
15578    (set (match_operand:SF 0 "register_operand" "")
15579         (float_truncate:SF (match_dup 4)))]
15580   "TARGET_USE_FANCY_MATH_387
15581    && flag_unsafe_math_optimizations"
15582 {
15583   rtx temp;
15584
15585   operands[2] = gen_reg_rtx (XFmode);
15586   operands[3] = gen_reg_rtx (XFmode);
15587   operands[4] = gen_reg_rtx (XFmode);
15588
15589   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15590   emit_move_insn (operands[3], temp);
15591 })
15592
15593 (define_expand "log10df2"
15594   [(set (match_dup 2)
15595         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15596    (parallel [(set (match_dup 4)
15597                    (unspec:XF [(match_dup 2)
15598                                (match_dup 3)] UNSPEC_FYL2X))
15599               (clobber (match_scratch:XF 5 ""))])
15600    (set (match_operand:DF 0 "register_operand" "")
15601         (float_truncate:DF (match_dup 4)))]
15602   "TARGET_USE_FANCY_MATH_387
15603    && flag_unsafe_math_optimizations"
15604 {
15605   rtx temp;
15606
15607   operands[2] = gen_reg_rtx (XFmode);
15608   operands[3] = gen_reg_rtx (XFmode);
15609   operands[4] = gen_reg_rtx (XFmode);
15610
15611   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15612   emit_move_insn (operands[3], temp);
15613 })
15614
15615 (define_expand "log10xf2"
15616   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15617                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15618                                (match_dup 2)] UNSPEC_FYL2X))
15619               (clobber (match_scratch:XF 3 ""))])]
15620   "TARGET_USE_FANCY_MATH_387
15621    && flag_unsafe_math_optimizations"
15622 {
15623   rtx temp;
15624
15625   operands[2] = gen_reg_rtx (XFmode);
15626   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15627   emit_move_insn (operands[2], temp);
15628 })
15629
15630 (define_expand "log2sf2"
15631   [(set (match_dup 2)
15632         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15633    (parallel [(set (match_dup 4)
15634                    (unspec:XF [(match_dup 2)
15635                                (match_dup 3)] UNSPEC_FYL2X))
15636               (clobber (match_scratch:XF 5 ""))])
15637    (set (match_operand:SF 0 "register_operand" "")
15638         (float_truncate:SF (match_dup 4)))]
15639   "TARGET_USE_FANCY_MATH_387
15640    && flag_unsafe_math_optimizations"
15641 {
15642   operands[2] = gen_reg_rtx (XFmode);
15643   operands[3] = gen_reg_rtx (XFmode);
15644   operands[4] = gen_reg_rtx (XFmode);
15645
15646   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15647 })
15648
15649 (define_expand "log2df2"
15650   [(set (match_dup 2)
15651         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15652    (parallel [(set (match_dup 4)
15653                    (unspec:XF [(match_dup 2)
15654                                (match_dup 3)] UNSPEC_FYL2X))
15655               (clobber (match_scratch:XF 5 ""))])
15656    (set (match_operand:DF 0 "register_operand" "")
15657         (float_truncate:DF (match_dup 4)))]
15658   "TARGET_USE_FANCY_MATH_387
15659    && flag_unsafe_math_optimizations"
15660 {
15661   operands[2] = gen_reg_rtx (XFmode);
15662   operands[3] = gen_reg_rtx (XFmode);
15663   operands[4] = gen_reg_rtx (XFmode);
15664
15665   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15666 })
15667
15668 (define_expand "log2xf2"
15669   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15670                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15671                                (match_dup 2)] UNSPEC_FYL2X))
15672               (clobber (match_scratch:XF 3 ""))])]
15673   "TARGET_USE_FANCY_MATH_387
15674    && flag_unsafe_math_optimizations"
15675 {
15676   operands[2] = gen_reg_rtx (XFmode);
15677   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15678 })
15679
15680 (define_insn "fyl2xp1_xf3"
15681   [(set (match_operand:XF 0 "register_operand" "=f")
15682         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15683                     (match_operand:XF 1 "register_operand" "u")]
15684                    UNSPEC_FYL2XP1))
15685    (clobber (match_scratch:XF 3 "=1"))]
15686   "TARGET_USE_FANCY_MATH_387
15687    && flag_unsafe_math_optimizations"
15688   "fyl2xp1"
15689   [(set_attr "type" "fpspc")
15690    (set_attr "mode" "XF")])
15691
15692 (define_expand "log1psf2"
15693   [(use (match_operand:SF 0 "register_operand" ""))
15694    (use (match_operand:SF 1 "register_operand" ""))]
15695   "TARGET_USE_FANCY_MATH_387
15696    && flag_unsafe_math_optimizations"
15697 {
15698   rtx op0 = gen_reg_rtx (XFmode);
15699   rtx op1 = gen_reg_rtx (XFmode);
15700
15701   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15702   ix86_emit_i387_log1p (op0, op1);
15703   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15704   DONE;
15705 })
15706
15707 (define_expand "log1pdf2"
15708   [(use (match_operand:DF 0 "register_operand" ""))
15709    (use (match_operand:DF 1 "register_operand" ""))]
15710   "TARGET_USE_FANCY_MATH_387
15711    && flag_unsafe_math_optimizations"
15712 {
15713   rtx op0 = gen_reg_rtx (XFmode);
15714   rtx op1 = gen_reg_rtx (XFmode);
15715
15716   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15717   ix86_emit_i387_log1p (op0, op1);
15718   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15719   DONE;
15720 })
15721
15722 (define_expand "log1pxf2"
15723   [(use (match_operand:XF 0 "register_operand" ""))
15724    (use (match_operand:XF 1 "register_operand" ""))]
15725   "TARGET_USE_FANCY_MATH_387
15726    && flag_unsafe_math_optimizations"
15727 {
15728   ix86_emit_i387_log1p (operands[0], operands[1]);
15729   DONE;
15730 })
15731
15732 (define_insn "*fxtractxf3"
15733   [(set (match_operand:XF 0 "register_operand" "=f")
15734         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15735                    UNSPEC_XTRACT_FRACT))
15736    (set (match_operand:XF 1 "register_operand" "=u")
15737         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15738   "TARGET_USE_FANCY_MATH_387
15739    && flag_unsafe_math_optimizations"
15740   "fxtract"
15741   [(set_attr "type" "fpspc")
15742    (set_attr "mode" "XF")])
15743
15744 (define_expand "logbsf2"
15745   [(set (match_dup 2)
15746         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15747    (parallel [(set (match_dup 3)
15748                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15749               (set (match_dup 4)
15750                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15751    (set (match_operand:SF 0 "register_operand" "")
15752         (float_truncate:SF (match_dup 4)))]
15753   "TARGET_USE_FANCY_MATH_387
15754    && flag_unsafe_math_optimizations"
15755 {
15756   operands[2] = gen_reg_rtx (XFmode);
15757   operands[3] = gen_reg_rtx (XFmode);
15758   operands[4] = gen_reg_rtx (XFmode);
15759 })
15760
15761 (define_expand "logbdf2"
15762   [(set (match_dup 2)
15763         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15764    (parallel [(set (match_dup 3)
15765                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15766               (set (match_dup 4)
15767                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15768    (set (match_operand:DF 0 "register_operand" "")
15769         (float_truncate:DF (match_dup 4)))]
15770   "TARGET_USE_FANCY_MATH_387
15771    && flag_unsafe_math_optimizations"
15772 {
15773   operands[2] = gen_reg_rtx (XFmode);
15774   operands[3] = gen_reg_rtx (XFmode);
15775   operands[4] = gen_reg_rtx (XFmode);
15776 })
15777
15778 (define_expand "logbxf2"
15779   [(parallel [(set (match_dup 2)
15780                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15781                               UNSPEC_XTRACT_FRACT))
15782               (set (match_operand:XF 0 "register_operand" "")
15783                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15784   "TARGET_USE_FANCY_MATH_387
15785    && flag_unsafe_math_optimizations"
15786 {
15787   operands[2] = gen_reg_rtx (XFmode);
15788 })
15789
15790 (define_expand "ilogbsi2"
15791   [(parallel [(set (match_dup 2)
15792                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15793                               UNSPEC_XTRACT_FRACT))
15794               (set (match_operand:XF 3 "register_operand" "")
15795                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15796    (parallel [(set (match_operand:SI 0 "register_operand" "")
15797                    (fix:SI (match_dup 3)))
15798               (clobber (reg:CC FLAGS_REG))])]
15799   "TARGET_USE_FANCY_MATH_387
15800    && flag_unsafe_math_optimizations"
15801 {
15802   operands[2] = gen_reg_rtx (XFmode);
15803   operands[3] = gen_reg_rtx (XFmode);
15804 })
15805
15806 (define_insn "*f2xm1xf2"
15807   [(set (match_operand:XF 0 "register_operand" "=f")
15808         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15809          UNSPEC_F2XM1))]
15810   "TARGET_USE_FANCY_MATH_387
15811    && flag_unsafe_math_optimizations"
15812   "f2xm1"
15813   [(set_attr "type" "fpspc")
15814    (set_attr "mode" "XF")])
15815
15816 (define_insn "*fscalexf4"
15817   [(set (match_operand:XF 0 "register_operand" "=f")
15818         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15819                     (match_operand:XF 3 "register_operand" "1")]
15820                    UNSPEC_FSCALE_FRACT))
15821    (set (match_operand:XF 1 "register_operand" "=u")
15822         (unspec:XF [(match_dup 2) (match_dup 3)]
15823                    UNSPEC_FSCALE_EXP))]
15824   "TARGET_USE_FANCY_MATH_387
15825    && flag_unsafe_math_optimizations"
15826   "fscale"
15827   [(set_attr "type" "fpspc")
15828    (set_attr "mode" "XF")])
15829
15830 (define_expand "expsf2"
15831   [(set (match_dup 2)
15832         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15833    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15834    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15835    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15836    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15837    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15838    (parallel [(set (match_dup 10)
15839                    (unspec:XF [(match_dup 9) (match_dup 5)]
15840                               UNSPEC_FSCALE_FRACT))
15841               (set (match_dup 11)
15842                    (unspec:XF [(match_dup 9) (match_dup 5)]
15843                               UNSPEC_FSCALE_EXP))])
15844    (set (match_operand:SF 0 "register_operand" "")
15845         (float_truncate:SF (match_dup 10)))]
15846   "TARGET_USE_FANCY_MATH_387
15847    && flag_unsafe_math_optimizations"
15848 {
15849   rtx temp;
15850   int i;
15851
15852   for (i=2; i<12; i++)
15853     operands[i] = gen_reg_rtx (XFmode);
15854   temp = standard_80387_constant_rtx (5); /* fldl2e */
15855   emit_move_insn (operands[3], temp);
15856   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15857 })
15858
15859 (define_expand "expdf2"
15860   [(set (match_dup 2)
15861         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15862    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15863    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15864    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15865    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15866    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15867    (parallel [(set (match_dup 10)
15868                    (unspec:XF [(match_dup 9) (match_dup 5)]
15869                               UNSPEC_FSCALE_FRACT))
15870               (set (match_dup 11)
15871                    (unspec:XF [(match_dup 9) (match_dup 5)]
15872                               UNSPEC_FSCALE_EXP))])
15873    (set (match_operand:DF 0 "register_operand" "")
15874         (float_truncate:DF (match_dup 10)))]
15875   "TARGET_USE_FANCY_MATH_387
15876    && flag_unsafe_math_optimizations"
15877 {
15878   rtx temp;
15879   int i;
15880
15881   for (i=2; i<12; i++)
15882     operands[i] = gen_reg_rtx (XFmode);
15883   temp = standard_80387_constant_rtx (5); /* fldl2e */
15884   emit_move_insn (operands[3], temp);
15885   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15886 })
15887
15888 (define_expand "expxf2"
15889   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15890                                (match_dup 2)))
15891    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15892    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15893    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15894    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15895    (parallel [(set (match_operand:XF 0 "register_operand" "")
15896                    (unspec:XF [(match_dup 8) (match_dup 4)]
15897                               UNSPEC_FSCALE_FRACT))
15898               (set (match_dup 9)
15899                    (unspec:XF [(match_dup 8) (match_dup 4)]
15900                               UNSPEC_FSCALE_EXP))])]
15901   "TARGET_USE_FANCY_MATH_387
15902    && flag_unsafe_math_optimizations"
15903 {
15904   rtx temp;
15905   int i;
15906
15907   for (i=2; i<10; i++)
15908     operands[i] = gen_reg_rtx (XFmode);
15909   temp = standard_80387_constant_rtx (5); /* fldl2e */
15910   emit_move_insn (operands[2], temp);
15911   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15912 })
15913
15914 (define_expand "exp10sf2"
15915   [(set (match_dup 2)
15916         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15917    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15918    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15919    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15920    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15921    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15922    (parallel [(set (match_dup 10)
15923                    (unspec:XF [(match_dup 9) (match_dup 5)]
15924                               UNSPEC_FSCALE_FRACT))
15925               (set (match_dup 11)
15926                    (unspec:XF [(match_dup 9) (match_dup 5)]
15927                               UNSPEC_FSCALE_EXP))])
15928    (set (match_operand:SF 0 "register_operand" "")
15929         (float_truncate:SF (match_dup 10)))]
15930   "TARGET_USE_FANCY_MATH_387
15931    && flag_unsafe_math_optimizations"
15932 {
15933   rtx temp;
15934   int i;
15935
15936   for (i=2; i<12; i++)
15937     operands[i] = gen_reg_rtx (XFmode);
15938   temp = standard_80387_constant_rtx (6); /* fldl2t */
15939   emit_move_insn (operands[3], temp);
15940   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15941 })
15942
15943 (define_expand "exp10df2"
15944   [(set (match_dup 2)
15945         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15946    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15947    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15948    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15949    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15950    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15951    (parallel [(set (match_dup 10)
15952                    (unspec:XF [(match_dup 9) (match_dup 5)]
15953                               UNSPEC_FSCALE_FRACT))
15954               (set (match_dup 11)
15955                    (unspec:XF [(match_dup 9) (match_dup 5)]
15956                               UNSPEC_FSCALE_EXP))])
15957    (set (match_operand:DF 0 "register_operand" "")
15958         (float_truncate:DF (match_dup 10)))]
15959   "TARGET_USE_FANCY_MATH_387
15960    && flag_unsafe_math_optimizations"
15961 {
15962   rtx temp;
15963   int i;
15964
15965   for (i=2; i<12; i++)
15966     operands[i] = gen_reg_rtx (XFmode);
15967   temp = standard_80387_constant_rtx (6); /* fldl2t */
15968   emit_move_insn (operands[3], temp);
15969   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15970 })
15971
15972 (define_expand "exp10xf2"
15973   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15974                                (match_dup 2)))
15975    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15976    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15977    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15978    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15979    (parallel [(set (match_operand:XF 0 "register_operand" "")
15980                    (unspec:XF [(match_dup 8) (match_dup 4)]
15981                               UNSPEC_FSCALE_FRACT))
15982               (set (match_dup 9)
15983                    (unspec:XF [(match_dup 8) (match_dup 4)]
15984                               UNSPEC_FSCALE_EXP))])]
15985   "TARGET_USE_FANCY_MATH_387
15986    && flag_unsafe_math_optimizations"
15987 {
15988   rtx temp;
15989   int i;
15990
15991   for (i=2; i<10; i++)
15992     operands[i] = gen_reg_rtx (XFmode);
15993   temp = standard_80387_constant_rtx (6); /* fldl2t */
15994   emit_move_insn (operands[2], temp);
15995   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15996 })
15997
15998 (define_expand "exp2sf2"
15999   [(set (match_dup 2)
16000         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16001    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16002    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16003    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16004    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16005    (parallel [(set (match_dup 8)
16006                    (unspec:XF [(match_dup 7) (match_dup 3)]
16007                               UNSPEC_FSCALE_FRACT))
16008               (set (match_dup 9)
16009                    (unspec:XF [(match_dup 7) (match_dup 3)]
16010                               UNSPEC_FSCALE_EXP))])
16011    (set (match_operand:SF 0 "register_operand" "")
16012         (float_truncate:SF (match_dup 8)))]
16013   "TARGET_USE_FANCY_MATH_387
16014    && flag_unsafe_math_optimizations"
16015 {
16016   int i;
16017
16018   for (i=2; i<10; i++)
16019     operands[i] = gen_reg_rtx (XFmode);
16020   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16021 })
16022
16023 (define_expand "exp2df2"
16024   [(set (match_dup 2)
16025         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16026    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16027    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16028    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16029    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16030    (parallel [(set (match_dup 8)
16031                    (unspec:XF [(match_dup 7) (match_dup 3)]
16032                               UNSPEC_FSCALE_FRACT))
16033               (set (match_dup 9)
16034                    (unspec:XF [(match_dup 7) (match_dup 3)]
16035                               UNSPEC_FSCALE_EXP))])
16036    (set (match_operand:DF 0 "register_operand" "")
16037         (float_truncate:DF (match_dup 8)))]
16038   "TARGET_USE_FANCY_MATH_387
16039    && flag_unsafe_math_optimizations"
16040 {
16041   int i;
16042
16043   for (i=2; i<10; i++)
16044     operands[i] = gen_reg_rtx (XFmode);
16045   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16046 })
16047
16048 (define_expand "exp2xf2"
16049   [(set (match_dup 2) (match_operand:XF 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_operand:XF 0 "register_operand" "")
16055                    (unspec:XF [(match_dup 7) (match_dup 3)]
16056                               UNSPEC_FSCALE_FRACT))
16057               (set (match_dup 8)
16058                    (unspec:XF [(match_dup 7) (match_dup 3)]
16059                               UNSPEC_FSCALE_EXP))])]
16060   "TARGET_USE_FANCY_MATH_387
16061    && flag_unsafe_math_optimizations"
16062 {
16063   int i;
16064
16065   for (i=2; i<9; i++)
16066     operands[i] = gen_reg_rtx (XFmode);
16067   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16068 })
16069
16070 (define_expand "expm1df2"
16071   [(set (match_dup 2)
16072         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16073    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16074    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16075    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16076    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16077    (parallel [(set (match_dup 8)
16078                    (unspec:XF [(match_dup 7) (match_dup 5)]
16079                               UNSPEC_FSCALE_FRACT))
16080                    (set (match_dup 9)
16081                    (unspec:XF [(match_dup 7) (match_dup 5)]
16082                               UNSPEC_FSCALE_EXP))])
16083    (parallel [(set (match_dup 11)
16084                    (unspec:XF [(match_dup 10) (match_dup 9)]
16085                               UNSPEC_FSCALE_FRACT))
16086               (set (match_dup 12)
16087                    (unspec:XF [(match_dup 10) (match_dup 9)]
16088                               UNSPEC_FSCALE_EXP))])
16089    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16090    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16091    (set (match_operand:DF 0 "register_operand" "")
16092         (float_truncate:DF (match_dup 14)))]
16093   "TARGET_USE_FANCY_MATH_387
16094    && flag_unsafe_math_optimizations"
16095 {
16096   rtx temp;
16097   int i;
16098
16099   for (i=2; i<15; i++)
16100     operands[i] = gen_reg_rtx (XFmode);
16101   temp = standard_80387_constant_rtx (5); /* fldl2e */
16102   emit_move_insn (operands[3], temp);
16103   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16104 })
16105
16106 (define_expand "expm1sf2"
16107   [(set (match_dup 2)
16108         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16109    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16110    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16111    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16112    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16113    (parallel [(set (match_dup 8)
16114                    (unspec:XF [(match_dup 7) (match_dup 5)]
16115                               UNSPEC_FSCALE_FRACT))
16116                    (set (match_dup 9)
16117                    (unspec:XF [(match_dup 7) (match_dup 5)]
16118                               UNSPEC_FSCALE_EXP))])
16119    (parallel [(set (match_dup 11)
16120                    (unspec:XF [(match_dup 10) (match_dup 9)]
16121                               UNSPEC_FSCALE_FRACT))
16122               (set (match_dup 12)
16123                    (unspec:XF [(match_dup 10) (match_dup 9)]
16124                               UNSPEC_FSCALE_EXP))])
16125    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16126    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16127    (set (match_operand:SF 0 "register_operand" "")
16128         (float_truncate:SF (match_dup 14)))]
16129   "TARGET_USE_FANCY_MATH_387
16130    && flag_unsafe_math_optimizations"
16131 {
16132   rtx temp;
16133   int i;
16134
16135   for (i=2; i<15; i++)
16136     operands[i] = gen_reg_rtx (XFmode);
16137   temp = standard_80387_constant_rtx (5); /* fldl2e */
16138   emit_move_insn (operands[3], temp);
16139   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16140 })
16141
16142 (define_expand "expm1xf2"
16143   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16144                                (match_dup 2)))
16145    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16146    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16147    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16148    (parallel [(set (match_dup 7)
16149                    (unspec:XF [(match_dup 6) (match_dup 4)]
16150                               UNSPEC_FSCALE_FRACT))
16151                    (set (match_dup 8)
16152                    (unspec:XF [(match_dup 6) (match_dup 4)]
16153                               UNSPEC_FSCALE_EXP))])
16154    (parallel [(set (match_dup 10)
16155                    (unspec:XF [(match_dup 9) (match_dup 8)]
16156                               UNSPEC_FSCALE_FRACT))
16157               (set (match_dup 11)
16158                    (unspec:XF [(match_dup 9) (match_dup 8)]
16159                               UNSPEC_FSCALE_EXP))])
16160    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16161    (set (match_operand:XF 0 "register_operand" "")
16162         (plus:XF (match_dup 12) (match_dup 7)))]
16163   "TARGET_USE_FANCY_MATH_387
16164    && flag_unsafe_math_optimizations"
16165 {
16166   rtx temp;
16167   int i;
16168
16169   for (i=2; i<13; i++)
16170     operands[i] = gen_reg_rtx (XFmode);
16171   temp = standard_80387_constant_rtx (5); /* fldl2e */
16172   emit_move_insn (operands[2], temp);
16173   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16174 })
16175 \f
16176
16177 (define_insn "frndintxf2"
16178   [(set (match_operand:XF 0 "register_operand" "=f")
16179         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16180          UNSPEC_FRNDINT))]
16181   "TARGET_USE_FANCY_MATH_387
16182    && flag_unsafe_math_optimizations"
16183   "frndint"
16184   [(set_attr "type" "fpspc")
16185    (set_attr "mode" "XF")])
16186
16187 (define_expand "rintdf2"
16188   [(use (match_operand:DF 0 "register_operand" ""))
16189    (use (match_operand:DF 1 "register_operand" ""))]
16190   "TARGET_USE_FANCY_MATH_387
16191    && flag_unsafe_math_optimizations"
16192 {
16193   rtx op0 = gen_reg_rtx (XFmode);
16194   rtx op1 = gen_reg_rtx (XFmode);
16195
16196   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16197   emit_insn (gen_frndintxf2 (op0, op1));
16198
16199   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16200   DONE;
16201 })
16202
16203 (define_expand "rintsf2"
16204   [(use (match_operand:SF 0 "register_operand" ""))
16205    (use (match_operand:SF 1 "register_operand" ""))]
16206   "TARGET_USE_FANCY_MATH_387
16207    && flag_unsafe_math_optimizations"
16208 {
16209   rtx op0 = gen_reg_rtx (XFmode);
16210   rtx op1 = gen_reg_rtx (XFmode);
16211
16212   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16213   emit_insn (gen_frndintxf2 (op0, op1));
16214
16215   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16216   DONE;
16217 })
16218
16219 (define_expand "rintxf2"
16220   [(use (match_operand:XF 0 "register_operand" ""))
16221    (use (match_operand:XF 1 "register_operand" ""))]
16222   "TARGET_USE_FANCY_MATH_387
16223    && flag_unsafe_math_optimizations"
16224 {
16225   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16226   DONE;
16227 })
16228
16229 (define_insn "frndintxf2_floor"
16230   [(set (match_operand:XF 0 "register_operand" "=f")
16231         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16232          UNSPEC_FRNDINT_FLOOR))
16233    (use (match_operand:HI 2 "memory_operand" "m"))
16234    (use (match_operand:HI 3 "memory_operand" "m"))]
16235   "TARGET_USE_FANCY_MATH_387
16236    && flag_unsafe_math_optimizations"
16237   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16238   [(set_attr "type" "frndint")
16239    (set_attr "i387_cw" "floor")
16240    (set_attr "mode" "XF")])
16241
16242 (define_expand "floordf2"
16243   [(use (match_operand:DF 0 "register_operand" ""))
16244    (use (match_operand:DF 1 "register_operand" ""))]
16245   "TARGET_USE_FANCY_MATH_387
16246    && flag_unsafe_math_optimizations"
16247 {
16248   rtx op0 = gen_reg_rtx (XFmode);
16249   rtx op1 = gen_reg_rtx (XFmode);
16250   rtx op2 = assign_386_stack_local (HImode, 1);
16251   rtx op3 = assign_386_stack_local (HImode, 2);
16252         
16253   ix86_optimize_mode_switching = 1;
16254
16255   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16256   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16257
16258   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16259   DONE;
16260 })
16261
16262 (define_expand "floorsf2"
16263   [(use (match_operand:SF 0 "register_operand" ""))
16264    (use (match_operand:SF 1 "register_operand" ""))]
16265   "TARGET_USE_FANCY_MATH_387
16266    && flag_unsafe_math_optimizations"
16267 {
16268   rtx op0 = gen_reg_rtx (XFmode);
16269   rtx op1 = gen_reg_rtx (XFmode);
16270   rtx op2 = assign_386_stack_local (HImode, 1);
16271   rtx op3 = assign_386_stack_local (HImode, 2);
16272         
16273   ix86_optimize_mode_switching = 1;
16274
16275   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16276   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16277
16278   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16279   DONE;
16280 })
16281
16282 (define_expand "floorxf2"
16283   [(use (match_operand:XF 0 "register_operand" ""))
16284    (use (match_operand:XF 1 "register_operand" ""))]
16285   "TARGET_USE_FANCY_MATH_387
16286    && flag_unsafe_math_optimizations"
16287 {
16288   rtx op2 = assign_386_stack_local (HImode, 1);
16289   rtx op3 = assign_386_stack_local (HImode, 2);
16290         
16291   ix86_optimize_mode_switching = 1;
16292
16293   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16294   DONE;
16295 })
16296
16297 (define_insn "frndintxf2_ceil"
16298   [(set (match_operand:XF 0 "register_operand" "=f")
16299         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16300          UNSPEC_FRNDINT_CEIL))
16301    (use (match_operand:HI 2 "memory_operand" "m"))
16302    (use (match_operand:HI 3 "memory_operand" "m"))]
16303   "TARGET_USE_FANCY_MATH_387
16304    && flag_unsafe_math_optimizations"
16305   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16306   [(set_attr "type" "frndint")
16307    (set_attr "i387_cw" "ceil")
16308    (set_attr "mode" "XF")])
16309
16310 (define_expand "ceildf2"
16311   [(use (match_operand:DF 0 "register_operand" ""))
16312    (use (match_operand:DF 1 "register_operand" ""))]
16313   "TARGET_USE_FANCY_MATH_387
16314    && flag_unsafe_math_optimizations"
16315 {
16316   rtx op0 = gen_reg_rtx (XFmode);
16317   rtx op1 = gen_reg_rtx (XFmode);
16318   rtx op2 = assign_386_stack_local (HImode, 1);
16319   rtx op3 = assign_386_stack_local (HImode, 2);
16320         
16321   ix86_optimize_mode_switching = 1;
16322
16323   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16324   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16325
16326   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16327   DONE;
16328 })
16329
16330 (define_expand "ceilsf2"
16331   [(use (match_operand:SF 0 "register_operand" ""))
16332    (use (match_operand:SF 1 "register_operand" ""))]
16333   "TARGET_USE_FANCY_MATH_387
16334    && flag_unsafe_math_optimizations"
16335 {
16336   rtx op0 = gen_reg_rtx (XFmode);
16337   rtx op1 = gen_reg_rtx (XFmode);
16338   rtx op2 = assign_386_stack_local (HImode, 1);
16339   rtx op3 = assign_386_stack_local (HImode, 2);
16340         
16341   ix86_optimize_mode_switching = 1;
16342
16343   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16344   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16345
16346   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16347   DONE;
16348 })
16349
16350 (define_expand "ceilxf2"
16351   [(use (match_operand:XF 0 "register_operand" ""))
16352    (use (match_operand:XF 1 "register_operand" ""))]
16353   "TARGET_USE_FANCY_MATH_387
16354    && flag_unsafe_math_optimizations"
16355 {
16356   rtx op2 = assign_386_stack_local (HImode, 1);
16357   rtx op3 = assign_386_stack_local (HImode, 2);
16358         
16359   ix86_optimize_mode_switching = 1;
16360
16361   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16362   DONE;
16363 })
16364
16365 (define_insn "frndintxf2_trunc"
16366   [(set (match_operand:XF 0 "register_operand" "=f")
16367         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16368          UNSPEC_FRNDINT_TRUNC))
16369    (use (match_operand:HI 2 "memory_operand" "m"))
16370    (use (match_operand:HI 3 "memory_operand" "m"))]
16371   "TARGET_USE_FANCY_MATH_387
16372    && flag_unsafe_math_optimizations"
16373   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16374   [(set_attr "type" "frndint")
16375    (set_attr "i387_cw" "trunc")
16376    (set_attr "mode" "XF")])
16377
16378 (define_expand "btruncdf2"
16379   [(use (match_operand:DF 0 "register_operand" ""))
16380    (use (match_operand:DF 1 "register_operand" ""))]
16381   "TARGET_USE_FANCY_MATH_387
16382    && flag_unsafe_math_optimizations"
16383 {
16384   rtx op0 = gen_reg_rtx (XFmode);
16385   rtx op1 = gen_reg_rtx (XFmode);
16386   rtx op2 = assign_386_stack_local (HImode, 1);
16387   rtx op3 = assign_386_stack_local (HImode, 2);
16388         
16389   ix86_optimize_mode_switching = 1;
16390
16391   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16392   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16393
16394   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16395   DONE;
16396 })
16397
16398 (define_expand "btruncsf2"
16399   [(use (match_operand:SF 0 "register_operand" ""))
16400    (use (match_operand:SF 1 "register_operand" ""))]
16401   "TARGET_USE_FANCY_MATH_387
16402    && flag_unsafe_math_optimizations"
16403 {
16404   rtx op0 = gen_reg_rtx (XFmode);
16405   rtx op1 = gen_reg_rtx (XFmode);
16406   rtx op2 = assign_386_stack_local (HImode, 1);
16407   rtx op3 = assign_386_stack_local (HImode, 2);
16408         
16409   ix86_optimize_mode_switching = 1;
16410
16411   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16412   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16413
16414   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16415   DONE;
16416 })
16417
16418 (define_expand "btruncxf2"
16419   [(use (match_operand:XF 0 "register_operand" ""))
16420    (use (match_operand:XF 1 "register_operand" ""))]
16421   "TARGET_USE_FANCY_MATH_387
16422    && flag_unsafe_math_optimizations"
16423 {
16424   rtx op2 = assign_386_stack_local (HImode, 1);
16425   rtx op3 = assign_386_stack_local (HImode, 2);
16426         
16427   ix86_optimize_mode_switching = 1;
16428
16429   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16430   DONE;
16431 })
16432
16433 (define_insn "frndintxf2_mask_pm"
16434   [(set (match_operand:XF 0 "register_operand" "=f")
16435         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16436          UNSPEC_FRNDINT_MASK_PM))
16437    (use (match_operand:HI 2 "memory_operand" "m"))
16438    (use (match_operand:HI 3 "memory_operand" "m"))]
16439   "TARGET_USE_FANCY_MATH_387
16440    && flag_unsafe_math_optimizations"
16441   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16442   [(set_attr "type" "frndint")
16443    (set_attr "i387_cw" "mask_pm")
16444    (set_attr "mode" "XF")])
16445
16446 (define_expand "nearbyintdf2"
16447   [(use (match_operand:DF 0 "register_operand" ""))
16448    (use (match_operand:DF 1 "register_operand" ""))]
16449   "TARGET_USE_FANCY_MATH_387
16450    && flag_unsafe_math_optimizations"
16451 {
16452   rtx op0 = gen_reg_rtx (XFmode);
16453   rtx op1 = gen_reg_rtx (XFmode);
16454   rtx op2 = assign_386_stack_local (HImode, 1);
16455   rtx op3 = assign_386_stack_local (HImode, 2);
16456         
16457   ix86_optimize_mode_switching = 1;
16458
16459   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16460   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16461
16462   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16463   DONE;
16464 })
16465
16466 (define_expand "nearbyintsf2"
16467   [(use (match_operand:SF 0 "register_operand" ""))
16468    (use (match_operand:SF 1 "register_operand" ""))]
16469   "TARGET_USE_FANCY_MATH_387
16470    && flag_unsafe_math_optimizations"
16471 {
16472   rtx op0 = gen_reg_rtx (XFmode);
16473   rtx op1 = gen_reg_rtx (XFmode);
16474   rtx op2 = assign_386_stack_local (HImode, 1);
16475   rtx op3 = assign_386_stack_local (HImode, 2);
16476         
16477   ix86_optimize_mode_switching = 1;
16478
16479   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16480   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16481
16482   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16483   DONE;
16484 })
16485
16486 (define_expand "nearbyintxf2"
16487   [(use (match_operand:XF 0 "register_operand" ""))
16488    (use (match_operand:XF 1 "register_operand" ""))]
16489   "TARGET_USE_FANCY_MATH_387
16490    && flag_unsafe_math_optimizations"
16491 {
16492   rtx op2 = assign_386_stack_local (HImode, 1);
16493   rtx op3 = assign_386_stack_local (HImode, 2);
16494         
16495   ix86_optimize_mode_switching = 1;
16496
16497   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16498                                      op2, op3));
16499   DONE;
16500 })
16501
16502 \f
16503 ;; Block operation instructions
16504
16505 (define_insn "cld"
16506  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16507  ""
16508  "cld"
16509   [(set_attr "type" "cld")])
16510
16511 (define_expand "movmemsi"
16512   [(use (match_operand:BLK 0 "memory_operand" ""))
16513    (use (match_operand:BLK 1 "memory_operand" ""))
16514    (use (match_operand:SI 2 "nonmemory_operand" ""))
16515    (use (match_operand:SI 3 "const_int_operand" ""))]
16516   "! optimize_size"
16517 {
16518  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16519    DONE;
16520  else
16521    FAIL;
16522 })
16523
16524 (define_expand "movmemdi"
16525   [(use (match_operand:BLK 0 "memory_operand" ""))
16526    (use (match_operand:BLK 1 "memory_operand" ""))
16527    (use (match_operand:DI 2 "nonmemory_operand" ""))
16528    (use (match_operand:DI 3 "const_int_operand" ""))]
16529   "TARGET_64BIT"
16530 {
16531  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16532    DONE;
16533  else
16534    FAIL;
16535 })
16536
16537 ;; Most CPUs don't like single string operations
16538 ;; Handle this case here to simplify previous expander.
16539
16540 (define_expand "strmov"
16541   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16542    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16543    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16544               (clobber (reg:CC FLAGS_REG))])
16545    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16546               (clobber (reg:CC FLAGS_REG))])]
16547   ""
16548 {
16549   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16550
16551   /* If .md ever supports :P for Pmode, these can be directly
16552      in the pattern above.  */
16553   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16554   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16555
16556   if (TARGET_SINGLE_STRINGOP || optimize_size)
16557     {
16558       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16559                                       operands[2], operands[3],
16560                                       operands[5], operands[6]));
16561       DONE;
16562     }
16563
16564   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16565 })
16566
16567 (define_expand "strmov_singleop"
16568   [(parallel [(set (match_operand 1 "memory_operand" "")
16569                    (match_operand 3 "memory_operand" ""))
16570               (set (match_operand 0 "register_operand" "")
16571                    (match_operand 4 "" ""))
16572               (set (match_operand 2 "register_operand" "")
16573                    (match_operand 5 "" ""))
16574               (use (reg:SI DIRFLAG_REG))])]
16575   "TARGET_SINGLE_STRINGOP || optimize_size"
16576   "")
16577
16578 (define_insn "*strmovdi_rex_1"
16579   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16580         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16581    (set (match_operand:DI 0 "register_operand" "=D")
16582         (plus:DI (match_dup 2)
16583                  (const_int 8)))
16584    (set (match_operand:DI 1 "register_operand" "=S")
16585         (plus:DI (match_dup 3)
16586                  (const_int 8)))
16587    (use (reg:SI DIRFLAG_REG))]
16588   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16589   "movsq"
16590   [(set_attr "type" "str")
16591    (set_attr "mode" "DI")
16592    (set_attr "memory" "both")])
16593
16594 (define_insn "*strmovsi_1"
16595   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16596         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16597    (set (match_operand:SI 0 "register_operand" "=D")
16598         (plus:SI (match_dup 2)
16599                  (const_int 4)))
16600    (set (match_operand:SI 1 "register_operand" "=S")
16601         (plus:SI (match_dup 3)
16602                  (const_int 4)))
16603    (use (reg:SI DIRFLAG_REG))]
16604   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16605   "{movsl|movsd}"
16606   [(set_attr "type" "str")
16607    (set_attr "mode" "SI")
16608    (set_attr "memory" "both")])
16609
16610 (define_insn "*strmovsi_rex_1"
16611   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16612         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16613    (set (match_operand:DI 0 "register_operand" "=D")
16614         (plus:DI (match_dup 2)
16615                  (const_int 4)))
16616    (set (match_operand:DI 1 "register_operand" "=S")
16617         (plus:DI (match_dup 3)
16618                  (const_int 4)))
16619    (use (reg:SI DIRFLAG_REG))]
16620   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16621   "{movsl|movsd}"
16622   [(set_attr "type" "str")
16623    (set_attr "mode" "SI")
16624    (set_attr "memory" "both")])
16625
16626 (define_insn "*strmovhi_1"
16627   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16628         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16629    (set (match_operand:SI 0 "register_operand" "=D")
16630         (plus:SI (match_dup 2)
16631                  (const_int 2)))
16632    (set (match_operand:SI 1 "register_operand" "=S")
16633         (plus:SI (match_dup 3)
16634                  (const_int 2)))
16635    (use (reg:SI DIRFLAG_REG))]
16636   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16637   "movsw"
16638   [(set_attr "type" "str")
16639    (set_attr "memory" "both")
16640    (set_attr "mode" "HI")])
16641
16642 (define_insn "*strmovhi_rex_1"
16643   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16644         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16645    (set (match_operand:DI 0 "register_operand" "=D")
16646         (plus:DI (match_dup 2)
16647                  (const_int 2)))
16648    (set (match_operand:DI 1 "register_operand" "=S")
16649         (plus:DI (match_dup 3)
16650                  (const_int 2)))
16651    (use (reg:SI DIRFLAG_REG))]
16652   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16653   "movsw"
16654   [(set_attr "type" "str")
16655    (set_attr "memory" "both")
16656    (set_attr "mode" "HI")])
16657
16658 (define_insn "*strmovqi_1"
16659   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16660         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16661    (set (match_operand:SI 0 "register_operand" "=D")
16662         (plus:SI (match_dup 2)
16663                  (const_int 1)))
16664    (set (match_operand:SI 1 "register_operand" "=S")
16665         (plus:SI (match_dup 3)
16666                  (const_int 1)))
16667    (use (reg:SI DIRFLAG_REG))]
16668   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16669   "movsb"
16670   [(set_attr "type" "str")
16671    (set_attr "memory" "both")
16672    (set_attr "mode" "QI")])
16673
16674 (define_insn "*strmovqi_rex_1"
16675   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16676         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16677    (set (match_operand:DI 0 "register_operand" "=D")
16678         (plus:DI (match_dup 2)
16679                  (const_int 1)))
16680    (set (match_operand:DI 1 "register_operand" "=S")
16681         (plus:DI (match_dup 3)
16682                  (const_int 1)))
16683    (use (reg:SI DIRFLAG_REG))]
16684   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16685   "movsb"
16686   [(set_attr "type" "str")
16687    (set_attr "memory" "both")
16688    (set_attr "mode" "QI")])
16689
16690 (define_expand "rep_mov"
16691   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16692               (set (match_operand 0 "register_operand" "")
16693                    (match_operand 5 "" ""))
16694               (set (match_operand 2 "register_operand" "")
16695                    (match_operand 6 "" ""))
16696               (set (match_operand 1 "memory_operand" "")
16697                    (match_operand 3 "memory_operand" ""))
16698               (use (match_dup 4))
16699               (use (reg:SI DIRFLAG_REG))])]
16700   ""
16701   "")
16702
16703 (define_insn "*rep_movdi_rex64"
16704   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16705    (set (match_operand:DI 0 "register_operand" "=D") 
16706         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16707                             (const_int 3))
16708                  (match_operand:DI 3 "register_operand" "0")))
16709    (set (match_operand:DI 1 "register_operand" "=S") 
16710         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16711                  (match_operand:DI 4 "register_operand" "1")))
16712    (set (mem:BLK (match_dup 3))
16713         (mem:BLK (match_dup 4)))
16714    (use (match_dup 5))
16715    (use (reg:SI DIRFLAG_REG))]
16716   "TARGET_64BIT"
16717   "{rep\;movsq|rep movsq}"
16718   [(set_attr "type" "str")
16719    (set_attr "prefix_rep" "1")
16720    (set_attr "memory" "both")
16721    (set_attr "mode" "DI")])
16722
16723 (define_insn "*rep_movsi"
16724   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16725    (set (match_operand:SI 0 "register_operand" "=D") 
16726         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16727                             (const_int 2))
16728                  (match_operand:SI 3 "register_operand" "0")))
16729    (set (match_operand:SI 1 "register_operand" "=S") 
16730         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16731                  (match_operand:SI 4 "register_operand" "1")))
16732    (set (mem:BLK (match_dup 3))
16733         (mem:BLK (match_dup 4)))
16734    (use (match_dup 5))
16735    (use (reg:SI DIRFLAG_REG))]
16736   "!TARGET_64BIT"
16737   "{rep\;movsl|rep movsd}"
16738   [(set_attr "type" "str")
16739    (set_attr "prefix_rep" "1")
16740    (set_attr "memory" "both")
16741    (set_attr "mode" "SI")])
16742
16743 (define_insn "*rep_movsi_rex64"
16744   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16745    (set (match_operand:DI 0 "register_operand" "=D") 
16746         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16747                             (const_int 2))
16748                  (match_operand:DI 3 "register_operand" "0")))
16749    (set (match_operand:DI 1 "register_operand" "=S") 
16750         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16751                  (match_operand:DI 4 "register_operand" "1")))
16752    (set (mem:BLK (match_dup 3))
16753         (mem:BLK (match_dup 4)))
16754    (use (match_dup 5))
16755    (use (reg:SI DIRFLAG_REG))]
16756   "TARGET_64BIT"
16757   "{rep\;movsl|rep movsd}"
16758   [(set_attr "type" "str")
16759    (set_attr "prefix_rep" "1")
16760    (set_attr "memory" "both")
16761    (set_attr "mode" "SI")])
16762
16763 (define_insn "*rep_movqi"
16764   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16765    (set (match_operand:SI 0 "register_operand" "=D") 
16766         (plus:SI (match_operand:SI 3 "register_operand" "0")
16767                  (match_operand:SI 5 "register_operand" "2")))
16768    (set (match_operand:SI 1 "register_operand" "=S") 
16769         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16770    (set (mem:BLK (match_dup 3))
16771         (mem:BLK (match_dup 4)))
16772    (use (match_dup 5))
16773    (use (reg:SI DIRFLAG_REG))]
16774   "!TARGET_64BIT"
16775   "{rep\;movsb|rep movsb}"
16776   [(set_attr "type" "str")
16777    (set_attr "prefix_rep" "1")
16778    (set_attr "memory" "both")
16779    (set_attr "mode" "SI")])
16780
16781 (define_insn "*rep_movqi_rex64"
16782   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16783    (set (match_operand:DI 0 "register_operand" "=D") 
16784         (plus:DI (match_operand:DI 3 "register_operand" "0")
16785                  (match_operand:DI 5 "register_operand" "2")))
16786    (set (match_operand:DI 1 "register_operand" "=S") 
16787         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16788    (set (mem:BLK (match_dup 3))
16789         (mem:BLK (match_dup 4)))
16790    (use (match_dup 5))
16791    (use (reg:SI DIRFLAG_REG))]
16792   "TARGET_64BIT"
16793   "{rep\;movsb|rep movsb}"
16794   [(set_attr "type" "str")
16795    (set_attr "prefix_rep" "1")
16796    (set_attr "memory" "both")
16797    (set_attr "mode" "SI")])
16798
16799 (define_expand "clrmemsi"
16800    [(use (match_operand:BLK 0 "memory_operand" ""))
16801     (use (match_operand:SI 1 "nonmemory_operand" ""))
16802     (use (match_operand 2 "const_int_operand" ""))]
16803   ""
16804 {
16805  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16806    DONE;
16807  else
16808    FAIL;
16809 })
16810
16811 (define_expand "clrmemdi"
16812    [(use (match_operand:BLK 0 "memory_operand" ""))
16813     (use (match_operand:DI 1 "nonmemory_operand" ""))
16814     (use (match_operand 2 "const_int_operand" ""))]
16815   "TARGET_64BIT"
16816 {
16817  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16818    DONE;
16819  else
16820    FAIL;
16821 })
16822
16823 ;; Most CPUs don't like single string operations
16824 ;; Handle this case here to simplify previous expander.
16825
16826 (define_expand "strset"
16827   [(set (match_operand 1 "memory_operand" "")
16828         (match_operand 2 "register_operand" ""))
16829    (parallel [(set (match_operand 0 "register_operand" "")
16830                    (match_dup 3))
16831               (clobber (reg:CC FLAGS_REG))])]
16832   ""
16833 {
16834   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16835     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16836
16837   /* If .md ever supports :P for Pmode, this can be directly
16838      in the pattern above.  */
16839   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16840                               GEN_INT (GET_MODE_SIZE (GET_MODE
16841                                                       (operands[2]))));
16842   if (TARGET_SINGLE_STRINGOP || optimize_size)
16843     {
16844       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16845                                       operands[3]));
16846       DONE;
16847     }
16848 })
16849
16850 (define_expand "strset_singleop"
16851   [(parallel [(set (match_operand 1 "memory_operand" "")
16852                    (match_operand 2 "register_operand" ""))
16853               (set (match_operand 0 "register_operand" "")
16854                    (match_operand 3 "" ""))
16855               (use (reg:SI DIRFLAG_REG))])]
16856   "TARGET_SINGLE_STRINGOP || optimize_size"
16857   "")
16858
16859 (define_insn "*strsetdi_rex_1"
16860   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16861         (match_operand:DI 2 "register_operand" "a"))
16862    (set (match_operand:DI 0 "register_operand" "=D")
16863         (plus:DI (match_dup 1)
16864                  (const_int 8)))
16865    (use (reg:SI DIRFLAG_REG))]
16866   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16867   "stosq"
16868   [(set_attr "type" "str")
16869    (set_attr "memory" "store")
16870    (set_attr "mode" "DI")])
16871
16872 (define_insn "*strsetsi_1"
16873   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16874         (match_operand:SI 2 "register_operand" "a"))
16875    (set (match_operand:SI 0 "register_operand" "=D")
16876         (plus:SI (match_dup 1)
16877                  (const_int 4)))
16878    (use (reg:SI DIRFLAG_REG))]
16879   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16880   "{stosl|stosd}"
16881   [(set_attr "type" "str")
16882    (set_attr "memory" "store")
16883    (set_attr "mode" "SI")])
16884
16885 (define_insn "*strsetsi_rex_1"
16886   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16887         (match_operand:SI 2 "register_operand" "a"))
16888    (set (match_operand:DI 0 "register_operand" "=D")
16889         (plus:DI (match_dup 1)
16890                  (const_int 4)))
16891    (use (reg:SI DIRFLAG_REG))]
16892   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16893   "{stosl|stosd}"
16894   [(set_attr "type" "str")
16895    (set_attr "memory" "store")
16896    (set_attr "mode" "SI")])
16897
16898 (define_insn "*strsethi_1"
16899   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16900         (match_operand:HI 2 "register_operand" "a"))
16901    (set (match_operand:SI 0 "register_operand" "=D")
16902         (plus:SI (match_dup 1)
16903                  (const_int 2)))
16904    (use (reg:SI DIRFLAG_REG))]
16905   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16906   "stosw"
16907   [(set_attr "type" "str")
16908    (set_attr "memory" "store")
16909    (set_attr "mode" "HI")])
16910
16911 (define_insn "*strsethi_rex_1"
16912   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16913         (match_operand:HI 2 "register_operand" "a"))
16914    (set (match_operand:DI 0 "register_operand" "=D")
16915         (plus:DI (match_dup 1)
16916                  (const_int 2)))
16917    (use (reg:SI DIRFLAG_REG))]
16918   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16919   "stosw"
16920   [(set_attr "type" "str")
16921    (set_attr "memory" "store")
16922    (set_attr "mode" "HI")])
16923
16924 (define_insn "*strsetqi_1"
16925   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16926         (match_operand:QI 2 "register_operand" "a"))
16927    (set (match_operand:SI 0 "register_operand" "=D")
16928         (plus:SI (match_dup 1)
16929                  (const_int 1)))
16930    (use (reg:SI DIRFLAG_REG))]
16931   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16932   "stosb"
16933   [(set_attr "type" "str")
16934    (set_attr "memory" "store")
16935    (set_attr "mode" "QI")])
16936
16937 (define_insn "*strsetqi_rex_1"
16938   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16939         (match_operand:QI 2 "register_operand" "a"))
16940    (set (match_operand:DI 0 "register_operand" "=D")
16941         (plus:DI (match_dup 1)
16942                  (const_int 1)))
16943    (use (reg:SI DIRFLAG_REG))]
16944   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16945   "stosb"
16946   [(set_attr "type" "str")
16947    (set_attr "memory" "store")
16948    (set_attr "mode" "QI")])
16949
16950 (define_expand "rep_stos"
16951   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16952               (set (match_operand 0 "register_operand" "")
16953                    (match_operand 4 "" ""))
16954               (set (match_operand 2 "memory_operand" "") (const_int 0))
16955               (use (match_operand 3 "register_operand" ""))
16956               (use (match_dup 1))
16957               (use (reg:SI DIRFLAG_REG))])]
16958   ""
16959   "")
16960
16961 (define_insn "*rep_stosdi_rex64"
16962   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16963    (set (match_operand:DI 0 "register_operand" "=D") 
16964         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16965                             (const_int 3))
16966                  (match_operand:DI 3 "register_operand" "0")))
16967    (set (mem:BLK (match_dup 3))
16968         (const_int 0))
16969    (use (match_operand:DI 2 "register_operand" "a"))
16970    (use (match_dup 4))
16971    (use (reg:SI DIRFLAG_REG))]
16972   "TARGET_64BIT"
16973   "{rep\;stosq|rep stosq}"
16974   [(set_attr "type" "str")
16975    (set_attr "prefix_rep" "1")
16976    (set_attr "memory" "store")
16977    (set_attr "mode" "DI")])
16978
16979 (define_insn "*rep_stossi"
16980   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16981    (set (match_operand:SI 0 "register_operand" "=D") 
16982         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16983                             (const_int 2))
16984                  (match_operand:SI 3 "register_operand" "0")))
16985    (set (mem:BLK (match_dup 3))
16986         (const_int 0))
16987    (use (match_operand:SI 2 "register_operand" "a"))
16988    (use (match_dup 4))
16989    (use (reg:SI DIRFLAG_REG))]
16990   "!TARGET_64BIT"
16991   "{rep\;stosl|rep stosd}"
16992   [(set_attr "type" "str")
16993    (set_attr "prefix_rep" "1")
16994    (set_attr "memory" "store")
16995    (set_attr "mode" "SI")])
16996
16997 (define_insn "*rep_stossi_rex64"
16998   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16999    (set (match_operand:DI 0 "register_operand" "=D") 
17000         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17001                             (const_int 2))
17002                  (match_operand:DI 3 "register_operand" "0")))
17003    (set (mem:BLK (match_dup 3))
17004         (const_int 0))
17005    (use (match_operand:SI 2 "register_operand" "a"))
17006    (use (match_dup 4))
17007    (use (reg:SI DIRFLAG_REG))]
17008   "TARGET_64BIT"
17009   "{rep\;stosl|rep stosd}"
17010   [(set_attr "type" "str")
17011    (set_attr "prefix_rep" "1")
17012    (set_attr "memory" "store")
17013    (set_attr "mode" "SI")])
17014
17015 (define_insn "*rep_stosqi"
17016   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17017    (set (match_operand:SI 0 "register_operand" "=D") 
17018         (plus:SI (match_operand:SI 3 "register_operand" "0")
17019                  (match_operand:SI 4 "register_operand" "1")))
17020    (set (mem:BLK (match_dup 3))
17021         (const_int 0))
17022    (use (match_operand:QI 2 "register_operand" "a"))
17023    (use (match_dup 4))
17024    (use (reg:SI DIRFLAG_REG))]
17025   "!TARGET_64BIT"
17026   "{rep\;stosb|rep stosb}"
17027   [(set_attr "type" "str")
17028    (set_attr "prefix_rep" "1")
17029    (set_attr "memory" "store")
17030    (set_attr "mode" "QI")])
17031
17032 (define_insn "*rep_stosqi_rex64"
17033   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17034    (set (match_operand:DI 0 "register_operand" "=D") 
17035         (plus:DI (match_operand:DI 3 "register_operand" "0")
17036                  (match_operand:DI 4 "register_operand" "1")))
17037    (set (mem:BLK (match_dup 3))
17038         (const_int 0))
17039    (use (match_operand:QI 2 "register_operand" "a"))
17040    (use (match_dup 4))
17041    (use (reg:SI DIRFLAG_REG))]
17042   "TARGET_64BIT"
17043   "{rep\;stosb|rep stosb}"
17044   [(set_attr "type" "str")
17045    (set_attr "prefix_rep" "1")
17046    (set_attr "memory" "store")
17047    (set_attr "mode" "QI")])
17048
17049 (define_expand "cmpstrsi"
17050   [(set (match_operand:SI 0 "register_operand" "")
17051         (compare:SI (match_operand:BLK 1 "general_operand" "")
17052                     (match_operand:BLK 2 "general_operand" "")))
17053    (use (match_operand 3 "general_operand" ""))
17054    (use (match_operand 4 "immediate_operand" ""))]
17055   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17056 {
17057   rtx addr1, addr2, out, outlow, count, countreg, align;
17058
17059   /* Can't use this if the user has appropriated esi or edi.  */
17060   if (global_regs[4] || global_regs[5])
17061     FAIL;
17062
17063   out = operands[0];
17064   if (GET_CODE (out) != REG)
17065     out = gen_reg_rtx (SImode);
17066
17067   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17068   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17069   if (addr1 != XEXP (operands[1], 0))
17070     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17071   if (addr2 != XEXP (operands[2], 0))
17072     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17073
17074   count = operands[3];
17075   countreg = ix86_zero_extend_to_Pmode (count);
17076
17077   /* %%% Iff we are testing strict equality, we can use known alignment
17078      to good advantage.  This may be possible with combine, particularly
17079      once cc0 is dead.  */
17080   align = operands[4];
17081
17082   emit_insn (gen_cld ());
17083   if (GET_CODE (count) == CONST_INT)
17084     {
17085       if (INTVAL (count) == 0)
17086         {
17087           emit_move_insn (operands[0], const0_rtx);
17088           DONE;
17089         }
17090       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17091                                     operands[1], operands[2]));
17092     }
17093   else
17094     {
17095       if (TARGET_64BIT)
17096         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17097       else
17098         emit_insn (gen_cmpsi_1 (countreg, countreg));
17099       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17100                                  operands[1], operands[2]));
17101     }
17102
17103   outlow = gen_lowpart (QImode, out);
17104   emit_insn (gen_cmpintqi (outlow));
17105   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17106
17107   if (operands[0] != out)
17108     emit_move_insn (operands[0], out);
17109
17110   DONE;
17111 })
17112
17113 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17114
17115 (define_expand "cmpintqi"
17116   [(set (match_dup 1)
17117         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17118    (set (match_dup 2)
17119         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17120    (parallel [(set (match_operand:QI 0 "register_operand" "")
17121                    (minus:QI (match_dup 1)
17122                              (match_dup 2)))
17123               (clobber (reg:CC FLAGS_REG))])]
17124   ""
17125   "operands[1] = gen_reg_rtx (QImode);
17126    operands[2] = gen_reg_rtx (QImode);")
17127
17128 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17129 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17130
17131 (define_expand "cmpstrqi_nz_1"
17132   [(parallel [(set (reg:CC FLAGS_REG)
17133                    (compare:CC (match_operand 4 "memory_operand" "")
17134                                (match_operand 5 "memory_operand" "")))
17135               (use (match_operand 2 "register_operand" ""))
17136               (use (match_operand:SI 3 "immediate_operand" ""))
17137               (use (reg:SI DIRFLAG_REG))
17138               (clobber (match_operand 0 "register_operand" ""))
17139               (clobber (match_operand 1 "register_operand" ""))
17140               (clobber (match_dup 2))])]
17141   ""
17142   "")
17143
17144 (define_insn "*cmpstrqi_nz_1"
17145   [(set (reg:CC FLAGS_REG)
17146         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17147                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17148    (use (match_operand:SI 6 "register_operand" "2"))
17149    (use (match_operand:SI 3 "immediate_operand" "i"))
17150    (use (reg:SI DIRFLAG_REG))
17151    (clobber (match_operand:SI 0 "register_operand" "=S"))
17152    (clobber (match_operand:SI 1 "register_operand" "=D"))
17153    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17154   "!TARGET_64BIT"
17155   "repz{\;| }cmpsb"
17156   [(set_attr "type" "str")
17157    (set_attr "mode" "QI")
17158    (set_attr "prefix_rep" "1")])
17159
17160 (define_insn "*cmpstrqi_nz_rex_1"
17161   [(set (reg:CC FLAGS_REG)
17162         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17163                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17164    (use (match_operand:DI 6 "register_operand" "2"))
17165    (use (match_operand:SI 3 "immediate_operand" "i"))
17166    (use (reg:SI DIRFLAG_REG))
17167    (clobber (match_operand:DI 0 "register_operand" "=S"))
17168    (clobber (match_operand:DI 1 "register_operand" "=D"))
17169    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17170   "TARGET_64BIT"
17171   "repz{\;| }cmpsb"
17172   [(set_attr "type" "str")
17173    (set_attr "mode" "QI")
17174    (set_attr "prefix_rep" "1")])
17175
17176 ;; The same, but the count is not known to not be zero.
17177
17178 (define_expand "cmpstrqi_1"
17179   [(parallel [(set (reg:CC FLAGS_REG)
17180                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17181                                      (const_int 0))
17182                   (compare:CC (match_operand 4 "memory_operand" "")
17183                               (match_operand 5 "memory_operand" ""))
17184                   (const_int 0)))
17185               (use (match_operand:SI 3 "immediate_operand" ""))
17186               (use (reg:CC FLAGS_REG))
17187               (use (reg:SI DIRFLAG_REG))
17188               (clobber (match_operand 0 "register_operand" ""))
17189               (clobber (match_operand 1 "register_operand" ""))
17190               (clobber (match_dup 2))])]
17191   ""
17192   "")
17193
17194 (define_insn "*cmpstrqi_1"
17195   [(set (reg:CC FLAGS_REG)
17196         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17197                              (const_int 0))
17198           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17199                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17200           (const_int 0)))
17201    (use (match_operand:SI 3 "immediate_operand" "i"))
17202    (use (reg:CC FLAGS_REG))
17203    (use (reg:SI DIRFLAG_REG))
17204    (clobber (match_operand:SI 0 "register_operand" "=S"))
17205    (clobber (match_operand:SI 1 "register_operand" "=D"))
17206    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17207   "!TARGET_64BIT"
17208   "repz{\;| }cmpsb"
17209   [(set_attr "type" "str")
17210    (set_attr "mode" "QI")
17211    (set_attr "prefix_rep" "1")])
17212
17213 (define_insn "*cmpstrqi_rex_1"
17214   [(set (reg:CC FLAGS_REG)
17215         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17216                              (const_int 0))
17217           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17218                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17219           (const_int 0)))
17220    (use (match_operand:SI 3 "immediate_operand" "i"))
17221    (use (reg:CC FLAGS_REG))
17222    (use (reg:SI DIRFLAG_REG))
17223    (clobber (match_operand:DI 0 "register_operand" "=S"))
17224    (clobber (match_operand:DI 1 "register_operand" "=D"))
17225    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17226   "TARGET_64BIT"
17227   "repz{\;| }cmpsb"
17228   [(set_attr "type" "str")
17229    (set_attr "mode" "QI")
17230    (set_attr "prefix_rep" "1")])
17231
17232 (define_expand "strlensi"
17233   [(set (match_operand:SI 0 "register_operand" "")
17234         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17235                     (match_operand:QI 2 "immediate_operand" "")
17236                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17237   ""
17238 {
17239  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17240    DONE;
17241  else
17242    FAIL;
17243 })
17244
17245 (define_expand "strlendi"
17246   [(set (match_operand:DI 0 "register_operand" "")
17247         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17248                     (match_operand:QI 2 "immediate_operand" "")
17249                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17250   ""
17251 {
17252  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17253    DONE;
17254  else
17255    FAIL;
17256 })
17257
17258 (define_expand "strlenqi_1"
17259   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17260               (use (reg:SI DIRFLAG_REG))
17261               (clobber (match_operand 1 "register_operand" ""))
17262               (clobber (reg:CC FLAGS_REG))])]
17263   ""
17264   "")
17265
17266 (define_insn "*strlenqi_1"
17267   [(set (match_operand:SI 0 "register_operand" "=&c")
17268         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17269                     (match_operand:QI 2 "register_operand" "a")
17270                     (match_operand:SI 3 "immediate_operand" "i")
17271                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17272    (use (reg:SI DIRFLAG_REG))
17273    (clobber (match_operand:SI 1 "register_operand" "=D"))
17274    (clobber (reg:CC FLAGS_REG))]
17275   "!TARGET_64BIT"
17276   "repnz{\;| }scasb"
17277   [(set_attr "type" "str")
17278    (set_attr "mode" "QI")
17279    (set_attr "prefix_rep" "1")])
17280
17281 (define_insn "*strlenqi_rex_1"
17282   [(set (match_operand:DI 0 "register_operand" "=&c")
17283         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17284                     (match_operand:QI 2 "register_operand" "a")
17285                     (match_operand:DI 3 "immediate_operand" "i")
17286                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17287    (use (reg:SI DIRFLAG_REG))
17288    (clobber (match_operand:DI 1 "register_operand" "=D"))
17289    (clobber (reg:CC FLAGS_REG))]
17290   "TARGET_64BIT"
17291   "repnz{\;| }scasb"
17292   [(set_attr "type" "str")
17293    (set_attr "mode" "QI")
17294    (set_attr "prefix_rep" "1")])
17295
17296 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17297 ;; handled in combine, but it is not currently up to the task.
17298 ;; When used for their truth value, the cmpstr* expanders generate
17299 ;; code like this:
17300 ;;
17301 ;;   repz cmpsb
17302 ;;   seta       %al
17303 ;;   setb       %dl
17304 ;;   cmpb       %al, %dl
17305 ;;   jcc        label
17306 ;;
17307 ;; The intermediate three instructions are unnecessary.
17308
17309 ;; This one handles cmpstr*_nz_1...
17310 (define_peephole2
17311   [(parallel[
17312      (set (reg:CC FLAGS_REG)
17313           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17314                       (mem:BLK (match_operand 5 "register_operand" ""))))
17315      (use (match_operand 6 "register_operand" ""))
17316      (use (match_operand:SI 3 "immediate_operand" ""))
17317      (use (reg:SI DIRFLAG_REG))
17318      (clobber (match_operand 0 "register_operand" ""))
17319      (clobber (match_operand 1 "register_operand" ""))
17320      (clobber (match_operand 2 "register_operand" ""))])
17321    (set (match_operand:QI 7 "register_operand" "")
17322         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17323    (set (match_operand:QI 8 "register_operand" "")
17324         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17325    (set (reg FLAGS_REG)
17326         (compare (match_dup 7) (match_dup 8)))
17327   ]
17328   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17329   [(parallel[
17330      (set (reg:CC FLAGS_REG)
17331           (compare:CC (mem:BLK (match_dup 4))
17332                       (mem:BLK (match_dup 5))))
17333      (use (match_dup 6))
17334      (use (match_dup 3))
17335      (use (reg:SI DIRFLAG_REG))
17336      (clobber (match_dup 0))
17337      (clobber (match_dup 1))
17338      (clobber (match_dup 2))])]
17339   "")
17340
17341 ;; ...and this one handles cmpstr*_1.
17342 (define_peephole2
17343   [(parallel[
17344      (set (reg:CC FLAGS_REG)
17345           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17346                                (const_int 0))
17347             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17348                         (mem:BLK (match_operand 5 "register_operand" "")))
17349             (const_int 0)))
17350      (use (match_operand:SI 3 "immediate_operand" ""))
17351      (use (reg:CC FLAGS_REG))
17352      (use (reg:SI DIRFLAG_REG))
17353      (clobber (match_operand 0 "register_operand" ""))
17354      (clobber (match_operand 1 "register_operand" ""))
17355      (clobber (match_operand 2 "register_operand" ""))])
17356    (set (match_operand:QI 7 "register_operand" "")
17357         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17358    (set (match_operand:QI 8 "register_operand" "")
17359         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17360    (set (reg FLAGS_REG)
17361         (compare (match_dup 7) (match_dup 8)))
17362   ]
17363   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17364   [(parallel[
17365      (set (reg:CC FLAGS_REG)
17366           (if_then_else:CC (ne (match_dup 6)
17367                                (const_int 0))
17368             (compare:CC (mem:BLK (match_dup 4))
17369                         (mem:BLK (match_dup 5)))
17370             (const_int 0)))
17371      (use (match_dup 3))
17372      (use (reg:CC FLAGS_REG))
17373      (use (reg:SI DIRFLAG_REG))
17374      (clobber (match_dup 0))
17375      (clobber (match_dup 1))
17376      (clobber (match_dup 2))])]
17377   "")
17378
17379
17380 \f
17381 ;; Conditional move instructions.
17382
17383 (define_expand "movdicc"
17384   [(set (match_operand:DI 0 "register_operand" "")
17385         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17386                          (match_operand:DI 2 "general_operand" "")
17387                          (match_operand:DI 3 "general_operand" "")))]
17388   "TARGET_64BIT"
17389   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17390
17391 (define_insn "x86_movdicc_0_m1_rex64"
17392   [(set (match_operand:DI 0 "register_operand" "=r")
17393         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17394           (const_int -1)
17395           (const_int 0)))
17396    (clobber (reg:CC FLAGS_REG))]
17397   "TARGET_64BIT"
17398   "sbb{q}\t%0, %0"
17399   ; Since we don't have the proper number of operands for an alu insn,
17400   ; fill in all the blanks.
17401   [(set_attr "type" "alu")
17402    (set_attr "pent_pair" "pu")
17403    (set_attr "memory" "none")
17404    (set_attr "imm_disp" "false")
17405    (set_attr "mode" "DI")
17406    (set_attr "length_immediate" "0")])
17407
17408 (define_insn "movdicc_c_rex64"
17409   [(set (match_operand:DI 0 "register_operand" "=r,r")
17410         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17411                                 [(reg FLAGS_REG) (const_int 0)])
17412                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17413                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17414   "TARGET_64BIT && TARGET_CMOVE
17415    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17416   "@
17417    cmov%O2%C1\t{%2, %0|%0, %2}
17418    cmov%O2%c1\t{%3, %0|%0, %3}"
17419   [(set_attr "type" "icmov")
17420    (set_attr "mode" "DI")])
17421
17422 (define_expand "movsicc"
17423   [(set (match_operand:SI 0 "register_operand" "")
17424         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17425                          (match_operand:SI 2 "general_operand" "")
17426                          (match_operand:SI 3 "general_operand" "")))]
17427   ""
17428   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17429
17430 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17431 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17432 ;; So just document what we're doing explicitly.
17433
17434 (define_insn "x86_movsicc_0_m1"
17435   [(set (match_operand:SI 0 "register_operand" "=r")
17436         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17437           (const_int -1)
17438           (const_int 0)))
17439    (clobber (reg:CC FLAGS_REG))]
17440   ""
17441   "sbb{l}\t%0, %0"
17442   ; Since we don't have the proper number of operands for an alu insn,
17443   ; fill in all the blanks.
17444   [(set_attr "type" "alu")
17445    (set_attr "pent_pair" "pu")
17446    (set_attr "memory" "none")
17447    (set_attr "imm_disp" "false")
17448    (set_attr "mode" "SI")
17449    (set_attr "length_immediate" "0")])
17450
17451 (define_insn "*movsicc_noc"
17452   [(set (match_operand:SI 0 "register_operand" "=r,r")
17453         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17454                                 [(reg FLAGS_REG) (const_int 0)])
17455                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17456                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17457   "TARGET_CMOVE
17458    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17459   "@
17460    cmov%O2%C1\t{%2, %0|%0, %2}
17461    cmov%O2%c1\t{%3, %0|%0, %3}"
17462   [(set_attr "type" "icmov")
17463    (set_attr "mode" "SI")])
17464
17465 (define_expand "movhicc"
17466   [(set (match_operand:HI 0 "register_operand" "")
17467         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17468                          (match_operand:HI 2 "general_operand" "")
17469                          (match_operand:HI 3 "general_operand" "")))]
17470   "TARGET_HIMODE_MATH"
17471   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17472
17473 (define_insn "*movhicc_noc"
17474   [(set (match_operand:HI 0 "register_operand" "=r,r")
17475         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17476                                 [(reg FLAGS_REG) (const_int 0)])
17477                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17478                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17479   "TARGET_CMOVE
17480    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17481   "@
17482    cmov%O2%C1\t{%2, %0|%0, %2}
17483    cmov%O2%c1\t{%3, %0|%0, %3}"
17484   [(set_attr "type" "icmov")
17485    (set_attr "mode" "HI")])
17486
17487 (define_expand "movqicc"
17488   [(set (match_operand:QI 0 "register_operand" "")
17489         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17490                          (match_operand:QI 2 "general_operand" "")
17491                          (match_operand:QI 3 "general_operand" "")))]
17492   "TARGET_QIMODE_MATH"
17493   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17494
17495 (define_insn_and_split "*movqicc_noc"
17496   [(set (match_operand:QI 0 "register_operand" "=r,r")
17497         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17498                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17499                       (match_operand:QI 2 "register_operand" "r,0")
17500                       (match_operand:QI 3 "register_operand" "0,r")))]
17501   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17502   "#"
17503   "&& reload_completed"
17504   [(set (match_dup 0)
17505         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17506                       (match_dup 2)
17507                       (match_dup 3)))]
17508   "operands[0] = gen_lowpart (SImode, operands[0]);
17509    operands[2] = gen_lowpart (SImode, operands[2]);
17510    operands[3] = gen_lowpart (SImode, operands[3]);"
17511   [(set_attr "type" "icmov")
17512    (set_attr "mode" "SI")])
17513
17514 (define_expand "movsfcc"
17515   [(set (match_operand:SF 0 "register_operand" "")
17516         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17517                          (match_operand:SF 2 "register_operand" "")
17518                          (match_operand:SF 3 "register_operand" "")))]
17519   "TARGET_CMOVE"
17520   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17521
17522 (define_insn "*movsfcc_1"
17523   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17524         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17525                                 [(reg FLAGS_REG) (const_int 0)])
17526                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17527                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17528   "TARGET_CMOVE
17529    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17530   "@
17531    fcmov%F1\t{%2, %0|%0, %2}
17532    fcmov%f1\t{%3, %0|%0, %3}
17533    cmov%O2%C1\t{%2, %0|%0, %2}
17534    cmov%O2%c1\t{%3, %0|%0, %3}"
17535   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17536    (set_attr "mode" "SF,SF,SI,SI")])
17537
17538 (define_expand "movdfcc"
17539   [(set (match_operand:DF 0 "register_operand" "")
17540         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17541                          (match_operand:DF 2 "register_operand" "")
17542                          (match_operand:DF 3 "register_operand" "")))]
17543   "TARGET_CMOVE"
17544   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17545
17546 (define_insn "*movdfcc_1"
17547   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17548         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17549                                 [(reg FLAGS_REG) (const_int 0)])
17550                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17551                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17552   "!TARGET_64BIT && 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    #
17558    #"
17559   [(set_attr "type" "fcmov,fcmov,multi,multi")
17560    (set_attr "mode" "DF")])
17561
17562 (define_insn "*movdfcc_1_rex64"
17563   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17564         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17565                                 [(reg FLAGS_REG) (const_int 0)])
17566                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17567                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17568   "TARGET_64BIT && TARGET_CMOVE
17569    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17570   "@
17571    fcmov%F1\t{%2, %0|%0, %2}
17572    fcmov%f1\t{%3, %0|%0, %3}
17573    cmov%O2%C1\t{%2, %0|%0, %2}
17574    cmov%O2%c1\t{%3, %0|%0, %3}"
17575   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17576    (set_attr "mode" "DF")])
17577
17578 (define_split
17579   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17580         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17581                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17582                       (match_operand:DF 2 "nonimmediate_operand" "")
17583                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17584   "!TARGET_64BIT && reload_completed"
17585   [(set (match_dup 2)
17586         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17587                       (match_dup 5)
17588                       (match_dup 7)))
17589    (set (match_dup 3)
17590         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17591                       (match_dup 6)
17592                       (match_dup 8)))]
17593   "split_di (operands+2, 1, operands+5, operands+6);
17594    split_di (operands+3, 1, operands+7, operands+8);
17595    split_di (operands, 1, operands+2, operands+3);")
17596
17597 (define_expand "movxfcc"
17598   [(set (match_operand:XF 0 "register_operand" "")
17599         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17600                          (match_operand:XF 2 "register_operand" "")
17601                          (match_operand:XF 3 "register_operand" "")))]
17602   "TARGET_CMOVE"
17603   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17604
17605 (define_insn "*movxfcc_1"
17606   [(set (match_operand:XF 0 "register_operand" "=f,f")
17607         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17608                                 [(reg FLAGS_REG) (const_int 0)])
17609                       (match_operand:XF 2 "register_operand" "f,0")
17610                       (match_operand:XF 3 "register_operand" "0,f")))]
17611   "TARGET_CMOVE"
17612   "@
17613    fcmov%F1\t{%2, %0|%0, %2}
17614    fcmov%f1\t{%3, %0|%0, %3}"
17615   [(set_attr "type" "fcmov")
17616    (set_attr "mode" "XF")])
17617
17618 (define_expand "minsf3"
17619   [(parallel [
17620      (set (match_operand:SF 0 "register_operand" "")
17621           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17622                                (match_operand:SF 2 "nonimmediate_operand" ""))
17623                            (match_dup 1)
17624                            (match_dup 2)))
17625      (clobber (reg:CC FLAGS_REG))])]
17626   "TARGET_SSE"
17627   "")
17628
17629 (define_insn "*minsf"
17630   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17631         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17632                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17633                          (match_dup 1)
17634                          (match_dup 2)))
17635    (clobber (reg:CC FLAGS_REG))]
17636   "TARGET_SSE && TARGET_IEEE_FP"
17637   "#")
17638
17639 (define_insn "*minsf_nonieee"
17640   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17641         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17642                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17643                          (match_dup 1)
17644                          (match_dup 2)))
17645    (clobber (reg:CC FLAGS_REG))]
17646   "TARGET_SSE && !TARGET_IEEE_FP
17647    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17648   "#")
17649
17650 (define_split
17651   [(set (match_operand:SF 0 "register_operand" "")
17652         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17653                              (match_operand:SF 2 "nonimmediate_operand" ""))
17654                          (match_operand:SF 3 "register_operand" "")
17655                          (match_operand:SF 4 "nonimmediate_operand" "")))
17656    (clobber (reg:CC FLAGS_REG))]
17657   "SSE_REG_P (operands[0]) && reload_completed
17658    && ((operands_match_p (operands[1], operands[3])
17659         && operands_match_p (operands[2], operands[4]))
17660        || (operands_match_p (operands[1], operands[4])
17661            && operands_match_p (operands[2], operands[3])))"
17662   [(set (match_dup 0)
17663         (if_then_else:SF (lt (match_dup 1)
17664                              (match_dup 2))
17665                          (match_dup 1)
17666                          (match_dup 2)))])
17667
17668 ;; Conditional addition patterns
17669 (define_expand "addqicc"
17670   [(match_operand:QI 0 "register_operand" "")
17671    (match_operand 1 "comparison_operator" "")
17672    (match_operand:QI 2 "register_operand" "")
17673    (match_operand:QI 3 "const_int_operand" "")]
17674   ""
17675   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17676
17677 (define_expand "addhicc"
17678   [(match_operand:HI 0 "register_operand" "")
17679    (match_operand 1 "comparison_operator" "")
17680    (match_operand:HI 2 "register_operand" "")
17681    (match_operand:HI 3 "const_int_operand" "")]
17682   ""
17683   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17684
17685 (define_expand "addsicc"
17686   [(match_operand:SI 0 "register_operand" "")
17687    (match_operand 1 "comparison_operator" "")
17688    (match_operand:SI 2 "register_operand" "")
17689    (match_operand:SI 3 "const_int_operand" "")]
17690   ""
17691   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17692
17693 (define_expand "adddicc"
17694   [(match_operand:DI 0 "register_operand" "")
17695    (match_operand 1 "comparison_operator" "")
17696    (match_operand:DI 2 "register_operand" "")
17697    (match_operand:DI 3 "const_int_operand" "")]
17698   "TARGET_64BIT"
17699   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17700
17701 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17702
17703 (define_split
17704   [(set (match_operand:SF 0 "fp_register_operand" "")
17705         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17706                              (match_operand:SF 2 "register_operand" ""))
17707                          (match_operand:SF 3 "register_operand" "")
17708                          (match_operand:SF 4 "register_operand" "")))
17709    (clobber (reg:CC FLAGS_REG))]
17710   "reload_completed
17711    && ((operands_match_p (operands[1], operands[3])
17712         && operands_match_p (operands[2], operands[4]))
17713        || (operands_match_p (operands[1], operands[4])
17714            && operands_match_p (operands[2], operands[3])))"
17715   [(set (reg:CCFP FLAGS_REG)
17716         (compare:CCFP (match_dup 2)
17717                       (match_dup 1)))
17718    (set (match_dup 0)
17719         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17720                          (match_dup 1)
17721                          (match_dup 2)))])
17722
17723 (define_insn "*minsf_sse"
17724   [(set (match_operand:SF 0 "register_operand" "=x")
17725         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17726                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17727                          (match_dup 1)
17728                          (match_dup 2)))]
17729   "TARGET_SSE && reload_completed"
17730   "minss\t{%2, %0|%0, %2}"
17731   [(set_attr "type" "sse")
17732    (set_attr "mode" "SF")])
17733
17734 (define_expand "mindf3"
17735   [(parallel [
17736      (set (match_operand:DF 0 "register_operand" "")
17737           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17738                                (match_operand:DF 2 "nonimmediate_operand" ""))
17739                            (match_dup 1)
17740                            (match_dup 2)))
17741      (clobber (reg:CC FLAGS_REG))])]
17742   "TARGET_SSE2 && TARGET_SSE_MATH"
17743   "#")
17744
17745 (define_insn "*mindf"
17746   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17747         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17748                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17749                          (match_dup 1)
17750                          (match_dup 2)))
17751    (clobber (reg:CC FLAGS_REG))]
17752   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17753   "#")
17754
17755 (define_insn "*mindf_nonieee"
17756   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17757         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17758                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17759                          (match_dup 1)
17760                          (match_dup 2)))
17761    (clobber (reg:CC FLAGS_REG))]
17762   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17763    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17764   "#")
17765
17766 (define_split
17767   [(set (match_operand:DF 0 "register_operand" "")
17768         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17769                              (match_operand:DF 2 "nonimmediate_operand" ""))
17770                          (match_operand:DF 3 "register_operand" "")
17771                          (match_operand:DF 4 "nonimmediate_operand" "")))
17772    (clobber (reg:CC FLAGS_REG))]
17773   "SSE_REG_P (operands[0]) && reload_completed
17774    && ((operands_match_p (operands[1], operands[3])
17775         && operands_match_p (operands[2], operands[4]))
17776        || (operands_match_p (operands[1], operands[4])
17777            && operands_match_p (operands[2], operands[3])))"
17778   [(set (match_dup 0)
17779         (if_then_else:DF (lt (match_dup 1)
17780                              (match_dup 2))
17781                          (match_dup 1)
17782                          (match_dup 2)))])
17783
17784 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17785 (define_split
17786   [(set (match_operand:DF 0 "fp_register_operand" "")
17787         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17788                              (match_operand:DF 2 "register_operand" ""))
17789                          (match_operand:DF 3 "register_operand" "")
17790                          (match_operand:DF 4 "register_operand" "")))
17791    (clobber (reg:CC FLAGS_REG))]
17792   "reload_completed
17793    && ((operands_match_p (operands[1], operands[3])
17794         && operands_match_p (operands[2], operands[4]))
17795        || (operands_match_p (operands[1], operands[4])
17796            && operands_match_p (operands[2], operands[3])))"
17797   [(set (reg:CCFP FLAGS_REG)
17798         (compare:CCFP (match_dup 2)
17799                       (match_dup 1)))
17800    (set (match_dup 0)
17801         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17802                          (match_dup 1)
17803                          (match_dup 2)))])
17804
17805 (define_insn "*mindf_sse"
17806   [(set (match_operand:DF 0 "register_operand" "=Y")
17807         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17808                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17809                          (match_dup 1)
17810                          (match_dup 2)))]
17811   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17812   "minsd\t{%2, %0|%0, %2}"
17813   [(set_attr "type" "sse")
17814    (set_attr "mode" "DF")])
17815
17816 (define_expand "maxsf3"
17817   [(parallel [
17818      (set (match_operand:SF 0 "register_operand" "")
17819           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17820                                (match_operand:SF 2 "nonimmediate_operand" ""))
17821                            (match_dup 1)
17822                            (match_dup 2)))
17823      (clobber (reg:CC FLAGS_REG))])]
17824   "TARGET_SSE"
17825   "#")
17826
17827 (define_insn "*maxsf"
17828   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17829         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17830                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17831                          (match_dup 1)
17832                          (match_dup 2)))
17833    (clobber (reg:CC FLAGS_REG))]
17834   "TARGET_SSE && TARGET_IEEE_FP"
17835   "#")
17836
17837 (define_insn "*maxsf_nonieee"
17838   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17839         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17840                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17841                          (match_dup 1)
17842                          (match_dup 2)))
17843    (clobber (reg:CC FLAGS_REG))]
17844   "TARGET_SSE && !TARGET_IEEE_FP
17845    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17846   "#")
17847
17848 (define_split
17849   [(set (match_operand:SF 0 "register_operand" "")
17850         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17851                              (match_operand:SF 2 "nonimmediate_operand" ""))
17852                          (match_operand:SF 3 "register_operand" "")
17853                          (match_operand:SF 4 "nonimmediate_operand" "")))
17854    (clobber (reg:CC FLAGS_REG))]
17855   "SSE_REG_P (operands[0]) && reload_completed
17856    && ((operands_match_p (operands[1], operands[3])
17857         && operands_match_p (operands[2], operands[4]))
17858        || (operands_match_p (operands[1], operands[4])
17859            && operands_match_p (operands[2], operands[3])))"
17860   [(set (match_dup 0)
17861         (if_then_else:SF (gt (match_dup 1)
17862                              (match_dup 2))
17863                          (match_dup 1)
17864                          (match_dup 2)))])
17865
17866 (define_split
17867   [(set (match_operand:SF 0 "fp_register_operand" "")
17868         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17869                              (match_operand:SF 2 "register_operand" ""))
17870                          (match_operand:SF 3 "register_operand" "")
17871                          (match_operand:SF 4 "register_operand" "")))
17872    (clobber (reg:CC FLAGS_REG))]
17873   "reload_completed
17874    && ((operands_match_p (operands[1], operands[3])
17875         && operands_match_p (operands[2], operands[4]))
17876        || (operands_match_p (operands[1], operands[4])
17877            && operands_match_p (operands[2], operands[3])))"
17878   [(set (reg:CCFP FLAGS_REG)
17879         (compare:CCFP (match_dup 1)
17880                       (match_dup 2)))
17881    (set (match_dup 0)
17882         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17883                          (match_dup 1)
17884                          (match_dup 2)))])
17885
17886 (define_insn "*maxsf_sse"
17887   [(set (match_operand:SF 0 "register_operand" "=x")
17888         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17889                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17890                          (match_dup 1)
17891                          (match_dup 2)))]
17892   "TARGET_SSE && reload_completed"
17893   "maxss\t{%2, %0|%0, %2}"
17894   [(set_attr "type" "sse")
17895    (set_attr "mode" "SF")])
17896
17897 (define_expand "maxdf3"
17898   [(parallel [
17899      (set (match_operand:DF 0 "register_operand" "")
17900           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17901                                (match_operand:DF 2 "nonimmediate_operand" ""))
17902                            (match_dup 1)
17903                            (match_dup 2)))
17904      (clobber (reg:CC FLAGS_REG))])]
17905   "TARGET_SSE2 && TARGET_SSE_MATH"
17906   "#")
17907
17908 (define_insn "*maxdf"
17909   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17910         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17911                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17912                          (match_dup 1)
17913                          (match_dup 2)))
17914    (clobber (reg:CC FLAGS_REG))]
17915   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17916   "#")
17917
17918 (define_insn "*maxdf_nonieee"
17919   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17920         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17921                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17922                          (match_dup 1)
17923                          (match_dup 2)))
17924    (clobber (reg:CC FLAGS_REG))]
17925   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17926    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17927   "#")
17928
17929 (define_split
17930   [(set (match_operand:DF 0 "register_operand" "")
17931         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17932                              (match_operand:DF 2 "nonimmediate_operand" ""))
17933                          (match_operand:DF 3 "register_operand" "")
17934                          (match_operand:DF 4 "nonimmediate_operand" "")))
17935    (clobber (reg:CC FLAGS_REG))]
17936   "SSE_REG_P (operands[0]) && reload_completed
17937    && ((operands_match_p (operands[1], operands[3])
17938         && operands_match_p (operands[2], operands[4]))
17939        || (operands_match_p (operands[1], operands[4])
17940            && operands_match_p (operands[2], operands[3])))"
17941   [(set (match_dup 0)
17942         (if_then_else:DF (gt (match_dup 1)
17943                              (match_dup 2))
17944                          (match_dup 1)
17945                          (match_dup 2)))])
17946
17947 (define_split
17948   [(set (match_operand:DF 0 "fp_register_operand" "")
17949         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17950                              (match_operand:DF 2 "register_operand" ""))
17951                          (match_operand:DF 3 "register_operand" "")
17952                          (match_operand:DF 4 "register_operand" "")))
17953    (clobber (reg:CC FLAGS_REG))]
17954   "reload_completed
17955    && ((operands_match_p (operands[1], operands[3])
17956         && operands_match_p (operands[2], operands[4]))
17957        || (operands_match_p (operands[1], operands[4])
17958            && operands_match_p (operands[2], operands[3])))"
17959   [(set (reg:CCFP FLAGS_REG)
17960         (compare:CCFP (match_dup 1)
17961                       (match_dup 2)))
17962    (set (match_dup 0)
17963         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17964                          (match_dup 1)
17965                          (match_dup 2)))])
17966
17967 (define_insn "*maxdf_sse"
17968   [(set (match_operand:DF 0 "register_operand" "=Y")
17969         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17970                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17971                          (match_dup 1)
17972                          (match_dup 2)))]
17973   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17974   "maxsd\t{%2, %0|%0, %2}"
17975   [(set_attr "type" "sse")
17976    (set_attr "mode" "DF")])
17977 \f
17978 ;; Misc patterns (?)
17979
17980 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17981 ;; Otherwise there will be nothing to keep
17982 ;; 
17983 ;; [(set (reg ebp) (reg esp))]
17984 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17985 ;;  (clobber (eflags)]
17986 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17987 ;;
17988 ;; in proper program order.
17989 (define_insn "pro_epilogue_adjust_stack_1"
17990   [(set (match_operand:SI 0 "register_operand" "=r,r")
17991         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17992                  (match_operand:SI 2 "immediate_operand" "i,i")))
17993    (clobber (reg:CC FLAGS_REG))
17994    (clobber (mem:BLK (scratch)))]
17995   "!TARGET_64BIT"
17996 {
17997   switch (get_attr_type (insn))
17998     {
17999     case TYPE_IMOV:
18000       return "mov{l}\t{%1, %0|%0, %1}";
18001
18002     case TYPE_ALU:
18003       if (GET_CODE (operands[2]) == CONST_INT
18004           && (INTVAL (operands[2]) == 128
18005               || (INTVAL (operands[2]) < 0
18006                   && INTVAL (operands[2]) != -128)))
18007         {
18008           operands[2] = GEN_INT (-INTVAL (operands[2]));
18009           return "sub{l}\t{%2, %0|%0, %2}";
18010         }
18011       return "add{l}\t{%2, %0|%0, %2}";
18012
18013     case TYPE_LEA:
18014       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18015       return "lea{l}\t{%a2, %0|%0, %a2}";
18016
18017     default:
18018       abort ();
18019     }
18020 }
18021   [(set (attr "type")
18022         (cond [(eq_attr "alternative" "0")
18023                  (const_string "alu")
18024                (match_operand:SI 2 "const0_operand" "")
18025                  (const_string "imov")
18026               ]
18027               (const_string "lea")))
18028    (set_attr "mode" "SI")])
18029
18030 (define_insn "pro_epilogue_adjust_stack_rex64"
18031   [(set (match_operand:DI 0 "register_operand" "=r,r")
18032         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18033                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18034    (clobber (reg:CC FLAGS_REG))
18035    (clobber (mem:BLK (scratch)))]
18036   "TARGET_64BIT"
18037 {
18038   switch (get_attr_type (insn))
18039     {
18040     case TYPE_IMOV:
18041       return "mov{q}\t{%1, %0|%0, %1}";
18042
18043     case TYPE_ALU:
18044       if (GET_CODE (operands[2]) == CONST_INT
18045           /* Avoid overflows.  */
18046           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18047           && (INTVAL (operands[2]) == 128
18048               || (INTVAL (operands[2]) < 0
18049                   && INTVAL (operands[2]) != -128)))
18050         {
18051           operands[2] = GEN_INT (-INTVAL (operands[2]));
18052           return "sub{q}\t{%2, %0|%0, %2}";
18053         }
18054       return "add{q}\t{%2, %0|%0, %2}";
18055
18056     case TYPE_LEA:
18057       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18058       return "lea{q}\t{%a2, %0|%0, %a2}";
18059
18060     default:
18061       abort ();
18062     }
18063 }
18064   [(set (attr "type")
18065         (cond [(eq_attr "alternative" "0")
18066                  (const_string "alu")
18067                (match_operand:DI 2 "const0_operand" "")
18068                  (const_string "imov")
18069               ]
18070               (const_string "lea")))
18071    (set_attr "mode" "DI")])
18072
18073 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18074   [(set (match_operand:DI 0 "register_operand" "=r,r")
18075         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18076                  (match_operand:DI 3 "immediate_operand" "i,i")))
18077    (use (match_operand:DI 2 "register_operand" "r,r"))
18078    (clobber (reg:CC FLAGS_REG))
18079    (clobber (mem:BLK (scratch)))]
18080   "TARGET_64BIT"
18081 {
18082   switch (get_attr_type (insn))
18083     {
18084     case TYPE_ALU:
18085       return "add{q}\t{%2, %0|%0, %2}";
18086
18087     case TYPE_LEA:
18088       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18089       return "lea{q}\t{%a2, %0|%0, %a2}";
18090
18091     default:
18092       abort ();
18093     }
18094 }
18095   [(set_attr "type" "alu,lea")
18096    (set_attr "mode" "DI")])
18097
18098 ;; Placeholder for the conditional moves.  This one is split either to SSE
18099 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18100 ;; fact is that compares supported by the cmp??ss instructions are exactly
18101 ;; swapped of those supported by cmove sequence.
18102 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18103 ;; supported by i387 comparisons and we do need to emit two conditional moves
18104 ;; in tandem.
18105
18106 (define_insn "sse_movsfcc"
18107   [(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")
18108         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18109                         [(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")
18110                          (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")])
18111                       (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")
18112                       (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")))
18113    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18114    (clobber (reg:CC FLAGS_REG))]
18115   "TARGET_SSE
18116    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18117    /* Avoid combine from being smart and converting min/max
18118       instruction patterns into conditional moves.  */
18119    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18120         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18121        || !rtx_equal_p (operands[4], operands[2])
18122        || !rtx_equal_p (operands[5], operands[3]))
18123    && (!TARGET_IEEE_FP
18124        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18125   "#")
18126
18127 (define_insn "sse_movsfcc_eq"
18128   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18129         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18130                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18131                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18132                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18133    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18134    (clobber (reg:CC FLAGS_REG))]
18135   "TARGET_SSE
18136    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18137   "#")
18138
18139 (define_insn "sse_movdfcc"
18140   [(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")
18141         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18142                         [(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")
18143                          (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")])
18144                       (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")
18145                       (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")))
18146    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18147    (clobber (reg:CC FLAGS_REG))]
18148   "TARGET_SSE2
18149    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18150    /* Avoid combine from being smart and converting min/max
18151       instruction patterns into conditional moves.  */
18152    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18153         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18154        || !rtx_equal_p (operands[4], operands[2])
18155        || !rtx_equal_p (operands[5], operands[3]))
18156    && (!TARGET_IEEE_FP
18157        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18158   "#")
18159
18160 (define_insn "sse_movdfcc_eq"
18161   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18162         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18163                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18164                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18165                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18166    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18167    (clobber (reg:CC FLAGS_REG))]
18168   "TARGET_SSE
18169    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18170   "#")
18171
18172 ;; For non-sse moves just expand the usual cmove sequence.
18173 (define_split
18174   [(set (match_operand 0 "register_operand" "")
18175         (if_then_else (match_operator 1 "comparison_operator"
18176                         [(match_operand 4 "nonimmediate_operand" "")
18177                          (match_operand 5 "register_operand" "")])
18178                       (match_operand 2 "nonimmediate_operand" "")
18179                       (match_operand 3 "nonimmediate_operand" "")))
18180    (clobber (match_operand 6 "" ""))
18181    (clobber (reg:CC FLAGS_REG))]
18182   "!SSE_REG_P (operands[0]) && reload_completed
18183    && (GET_MODE (operands[0]) == SFmode
18184        || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
18185   [(const_int 0)]
18186 {
18187    ix86_compare_op0 = operands[5];
18188    ix86_compare_op1 = operands[4];
18189    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18190                                  VOIDmode, operands[5], operands[4]);
18191    ix86_expand_fp_movcc (operands);
18192    DONE;
18193 })
18194
18195 ;; Split SSE based conditional move into sequence:
18196 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18197 ;; and   op2, op0   -  zero op2 if comparison was false
18198 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18199 ;; or    op2, op0   -  get the nonzero one into the result.
18200 (define_split
18201   [(set (match_operand:SF 0 "register_operand" "")
18202         (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18203                            [(match_operand:SF 4 "register_operand" "")
18204                             (match_operand:SF 5 "nonimmediate_operand" "")])
18205                          (match_operand:SF 2 "register_operand" "")
18206                          (match_operand:SF 3 "register_operand" "")))
18207    (clobber (match_operand 6 "" ""))
18208    (clobber (reg:CC FLAGS_REG))]
18209   "SSE_REG_P (operands[0]) && reload_completed"
18210   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18211    (set (match_dup 2) (and:V4SF (match_dup 2)
18212                                 (match_dup 8)))
18213    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18214                                           (match_dup 3)))
18215    (set (match_dup 0) (ior:V4SF (match_dup 6)
18216                                 (match_dup 7)))]
18217 {
18218   /* If op2 == op3, op3 would be clobbered before it is used.  */
18219   if (operands_match_p (operands[2], operands[3]))
18220     {
18221       emit_move_insn (operands[0], operands[2]);
18222       DONE;
18223     }
18224
18225   PUT_MODE (operands[1], GET_MODE (operands[0]));
18226   if (operands_match_p (operands[0], operands[4]))
18227     operands[6] = operands[4], operands[7] = operands[2];
18228   else
18229     operands[6] = operands[2], operands[7] = operands[4];
18230   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18231   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18232   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18233   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18234   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18235   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18236 })
18237
18238 (define_split
18239   [(set (match_operand:DF 0 "register_operand" "")
18240         (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18241                            [(match_operand:DF 4 "register_operand" "")
18242                             (match_operand:DF 5 "nonimmediate_operand" "")])
18243                          (match_operand:DF 2 "register_operand" "")
18244                          (match_operand:DF 3 "register_operand" "")))
18245    (clobber (match_operand 6 "" ""))
18246    (clobber (reg:CC FLAGS_REG))]
18247   "SSE_REG_P (operands[0]) && reload_completed"
18248   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18249    (set (match_dup 2) (and:V2DF (match_dup 2)
18250                                 (match_dup 8)))
18251    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18252                                           (match_dup 3)))
18253    (set (match_dup 0) (ior:V2DF (match_dup 6)
18254                                 (match_dup 7)))]
18255 {
18256   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18257     {
18258       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18259       emit_insn (gen_sse2_unpcklpd (op, op, op));
18260       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18261       emit_insn (gen_sse2_unpcklpd (op, op, op));
18262     }
18263
18264   /* If op2 == op3, op3 would be clobbered before it is used.  */
18265   if (operands_match_p (operands[2], operands[3]))
18266     {
18267       emit_move_insn (operands[0], operands[2]);
18268       DONE;
18269     }
18270
18271   PUT_MODE (operands[1], GET_MODE (operands[0]));
18272   if (operands_match_p (operands[0], operands[4]))
18273     operands[6] = operands[4], operands[7] = operands[2];
18274   else
18275     operands[6] = operands[2], operands[7] = operands[4];
18276   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18277   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18278   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18279   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18280   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18281   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18282 })
18283
18284 ;; Special case of conditional move we can handle effectively.
18285 ;; Do not brother with the integer/floating point case, since these are
18286 ;; bot considerably slower, unlike in the generic case.
18287 (define_insn "*sse_movsfcc_const0_1"
18288   [(set (match_operand:SF 0 "register_operand" "=&x")
18289         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18290                         [(match_operand:SF 4 "register_operand" "0")
18291                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18292                       (match_operand:SF 2 "register_operand" "x")
18293                       (match_operand:SF 3 "const0_operand" "X")))]
18294   "TARGET_SSE"
18295   "#")
18296
18297 (define_insn "*sse_movsfcc_const0_2"
18298   [(set (match_operand:SF 0 "register_operand" "=&x")
18299         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18300                         [(match_operand:SF 4 "register_operand" "0")
18301                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18302                       (match_operand:SF 2 "const0_operand" "X")
18303                       (match_operand:SF 3 "register_operand" "x")))]
18304   "TARGET_SSE"
18305   "#")
18306
18307 (define_insn "*sse_movsfcc_const0_3"
18308   [(set (match_operand:SF 0 "register_operand" "=&x")
18309         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18310                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18311                          (match_operand:SF 5 "register_operand" "0")])
18312                       (match_operand:SF 2 "register_operand" "x")
18313                       (match_operand:SF 3 "const0_operand" "X")))]
18314   "TARGET_SSE"
18315   "#")
18316
18317 (define_insn "*sse_movsfcc_const0_4"
18318   [(set (match_operand:SF 0 "register_operand" "=&x")
18319         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18320                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18321                          (match_operand:SF 5 "register_operand" "0")])
18322                       (match_operand:SF 2 "const0_operand" "X")
18323                       (match_operand:SF 3 "register_operand" "x")))]
18324   "TARGET_SSE"
18325   "#")
18326
18327 (define_insn "*sse_movdfcc_const0_1"
18328   [(set (match_operand:DF 0 "register_operand" "=&Y")
18329         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18330                         [(match_operand:DF 4 "register_operand" "0")
18331                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18332                       (match_operand:DF 2 "register_operand" "Y")
18333                       (match_operand:DF 3 "const0_operand" "X")))]
18334   "TARGET_SSE2"
18335   "#")
18336
18337 (define_insn "*sse_movdfcc_const0_2"
18338   [(set (match_operand:DF 0 "register_operand" "=&Y")
18339         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18340                         [(match_operand:DF 4 "register_operand" "0")
18341                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18342                       (match_operand:DF 2 "const0_operand" "X")
18343                       (match_operand:DF 3 "register_operand" "Y")))]
18344   "TARGET_SSE2"
18345   "#")
18346
18347 (define_insn "*sse_movdfcc_const0_3"
18348   [(set (match_operand:DF 0 "register_operand" "=&Y")
18349         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18350                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18351                          (match_operand:DF 5 "register_operand" "0")])
18352                       (match_operand:DF 2 "register_operand" "Y")
18353                       (match_operand:DF 3 "const0_operand" "X")))]
18354   "TARGET_SSE2"
18355   "#")
18356
18357 (define_insn "*sse_movdfcc_const0_4"
18358   [(set (match_operand:DF 0 "register_operand" "=&Y")
18359         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18360                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18361                          (match_operand:DF 5 "register_operand" "0")])
18362                       (match_operand:DF 2 "const0_operand" "X")
18363                       (match_operand:DF 3 "register_operand" "Y")))]
18364   "TARGET_SSE2"
18365   "#")
18366
18367 (define_split
18368   [(set (match_operand:SF 0 "register_operand" "")
18369         (if_then_else:SF (match_operator 1 "comparison_operator"
18370                            [(match_operand:SF 4 "nonimmediate_operand" "")
18371                             (match_operand:SF 5 "nonimmediate_operand" "")])
18372                          (match_operand:SF 2 "nonmemory_operand" "")
18373                          (match_operand:SF 3 "nonmemory_operand" "")))]
18374   "SSE_REG_P (operands[0]) && reload_completed
18375    && (const0_operand (operands[2], GET_MODE (operands[0]))
18376        || const0_operand (operands[3], GET_MODE (operands[0])))"
18377   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18378    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18379 {
18380   PUT_MODE (operands[1], GET_MODE (operands[0]));
18381   if (!sse_comparison_operator (operands[1], VOIDmode)
18382       || !rtx_equal_p (operands[0], operands[4]))
18383     {
18384       rtx tmp = operands[5];
18385       operands[5] = operands[4];
18386       operands[4] = tmp;
18387       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18388     }
18389   if (!rtx_equal_p (operands[0], operands[4]))
18390     abort ();
18391   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18392   if (const0_operand (operands[2], GET_MODE (operands[2])))
18393     {
18394       operands[7] = operands[3];
18395       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18396     }
18397   else
18398     {
18399       operands[7] = operands[2];
18400       operands[6] = operands[8];
18401     }
18402   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18403 })
18404
18405 (define_split
18406   [(set (match_operand:DF 0 "register_operand" "")
18407         (if_then_else:DF (match_operator 1 "comparison_operator"
18408                            [(match_operand:DF 4 "nonimmediate_operand" "")
18409                             (match_operand:DF 5 "nonimmediate_operand" "")])
18410                          (match_operand:DF 2 "nonmemory_operand" "")
18411                          (match_operand:DF 3 "nonmemory_operand" "")))]
18412   "SSE_REG_P (operands[0]) && reload_completed
18413    && (const0_operand (operands[2], GET_MODE (operands[0]))
18414        || const0_operand (operands[3], GET_MODE (operands[0])))"
18415   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18416    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18417 {
18418   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18419     {
18420       if (REG_P (operands[2]))
18421         {
18422           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18423           emit_insn (gen_sse2_unpcklpd (op, op, op));
18424         }
18425       if (REG_P (operands[3]))
18426         {
18427           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18428           emit_insn (gen_sse2_unpcklpd (op, op, op));
18429         }
18430     }
18431   PUT_MODE (operands[1], GET_MODE (operands[0]));
18432   if (!sse_comparison_operator (operands[1], VOIDmode)
18433       || !rtx_equal_p (operands[0], operands[4]))
18434     {
18435       rtx tmp = operands[5];
18436       operands[5] = operands[4];
18437       operands[4] = tmp;
18438       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18439     }
18440   if (!rtx_equal_p (operands[0], operands[4]))
18441     abort ();
18442   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18443   if (const0_operand (operands[2], GET_MODE (operands[2])))
18444     {
18445       operands[7] = operands[3];
18446       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18447     }
18448   else
18449     {
18450       operands[7] = operands[2];
18451       operands[6] = operands[8];
18452     }
18453   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18454 })
18455
18456 (define_expand "allocate_stack_worker"
18457   [(match_operand:SI 0 "register_operand" "")]
18458   "TARGET_STACK_PROBE"
18459 {
18460   if (reload_completed)
18461     {
18462       if (TARGET_64BIT)
18463         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18464       else
18465         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18466     }
18467   else
18468     {
18469       if (TARGET_64BIT)
18470         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18471       else
18472         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18473     }
18474   DONE;
18475 })
18476
18477 (define_insn "allocate_stack_worker_1"
18478   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18479     UNSPECV_STACK_PROBE)
18480    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18481    (clobber (match_scratch:SI 1 "=0"))
18482    (clobber (reg:CC FLAGS_REG))]
18483   "!TARGET_64BIT && TARGET_STACK_PROBE"
18484   "call\t__alloca"
18485   [(set_attr "type" "multi")
18486    (set_attr "length" "5")])
18487
18488 (define_expand "allocate_stack_worker_postreload"
18489   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18490                                     UNSPECV_STACK_PROBE)
18491               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18492               (clobber (match_dup 0))
18493               (clobber (reg:CC FLAGS_REG))])]
18494   ""
18495   "")
18496
18497 (define_insn "allocate_stack_worker_rex64"
18498   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18499     UNSPECV_STACK_PROBE)
18500    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18501    (clobber (match_scratch:DI 1 "=0"))
18502    (clobber (reg:CC FLAGS_REG))]
18503   "TARGET_64BIT && TARGET_STACK_PROBE"
18504   "call\t__alloca"
18505   [(set_attr "type" "multi")
18506    (set_attr "length" "5")])
18507
18508 (define_expand "allocate_stack_worker_rex64_postreload"
18509   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18510                                     UNSPECV_STACK_PROBE)
18511               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18512               (clobber (match_dup 0))
18513               (clobber (reg:CC FLAGS_REG))])]
18514   ""
18515   "")
18516
18517 (define_expand "allocate_stack"
18518   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18519                    (minus:SI (reg:SI SP_REG)
18520                              (match_operand:SI 1 "general_operand" "")))
18521               (clobber (reg:CC FLAGS_REG))])
18522    (parallel [(set (reg:SI SP_REG)
18523                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18524               (clobber (reg:CC FLAGS_REG))])]
18525   "TARGET_STACK_PROBE"
18526 {
18527 #ifdef CHECK_STACK_LIMIT
18528   if (GET_CODE (operands[1]) == CONST_INT
18529       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18530     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18531                            operands[1]));
18532   else 
18533 #endif
18534     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18535                                                             operands[1])));
18536
18537   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18538   DONE;
18539 })
18540
18541 (define_expand "builtin_setjmp_receiver"
18542   [(label_ref (match_operand 0 "" ""))]
18543   "!TARGET_64BIT && flag_pic"
18544 {
18545   emit_insn (gen_set_got (pic_offset_table_rtx));
18546   DONE;
18547 })
18548 \f
18549 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18550
18551 (define_split
18552   [(set (match_operand 0 "register_operand" "")
18553         (match_operator 3 "promotable_binary_operator"
18554            [(match_operand 1 "register_operand" "")
18555             (match_operand 2 "aligned_operand" "")]))
18556    (clobber (reg:CC FLAGS_REG))]
18557   "! TARGET_PARTIAL_REG_STALL && reload_completed
18558    && ((GET_MODE (operands[0]) == HImode 
18559         && ((!optimize_size && !TARGET_FAST_PREFIX)
18560             || GET_CODE (operands[2]) != CONST_INT
18561             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18562        || (GET_MODE (operands[0]) == QImode 
18563            && (TARGET_PROMOTE_QImode || optimize_size)))"
18564   [(parallel [(set (match_dup 0)
18565                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18566               (clobber (reg:CC FLAGS_REG))])]
18567   "operands[0] = gen_lowpart (SImode, operands[0]);
18568    operands[1] = gen_lowpart (SImode, operands[1]);
18569    if (GET_CODE (operands[3]) != ASHIFT)
18570      operands[2] = gen_lowpart (SImode, operands[2]);
18571    PUT_MODE (operands[3], SImode);")
18572
18573 ; Promote the QImode tests, as i386 has encoding of the AND
18574 ; instruction with 32-bit sign-extended immediate and thus the
18575 ; instruction size is unchanged, except in the %eax case for
18576 ; which it is increased by one byte, hence the ! optimize_size.
18577 (define_split
18578   [(set (match_operand 0 "flags_reg_operand" "")
18579         (match_operator 2 "compare_operator"
18580           [(and (match_operand 3 "aligned_operand" "")
18581                 (match_operand 4 "const_int_operand" ""))
18582            (const_int 0)]))
18583    (set (match_operand 1 "register_operand" "")
18584         (and (match_dup 3) (match_dup 4)))]
18585   "! TARGET_PARTIAL_REG_STALL && reload_completed
18586    /* Ensure that the operand will remain sign-extended immediate.  */
18587    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18588    && ! optimize_size
18589    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18590        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18591   [(parallel [(set (match_dup 0)
18592                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18593                                     (const_int 0)]))
18594               (set (match_dup 1)
18595                    (and:SI (match_dup 3) (match_dup 4)))])]
18596 {
18597   operands[4]
18598     = gen_int_mode (INTVAL (operands[4])
18599                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18600   operands[1] = gen_lowpart (SImode, operands[1]);
18601   operands[3] = gen_lowpart (SImode, operands[3]);
18602 })
18603
18604 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18605 ; the TEST instruction with 32-bit sign-extended immediate and thus
18606 ; the instruction size would at least double, which is not what we
18607 ; want even with ! optimize_size.
18608 (define_split
18609   [(set (match_operand 0 "flags_reg_operand" "")
18610         (match_operator 1 "compare_operator"
18611           [(and (match_operand:HI 2 "aligned_operand" "")
18612                 (match_operand:HI 3 "const_int_operand" ""))
18613            (const_int 0)]))]
18614   "! TARGET_PARTIAL_REG_STALL && reload_completed
18615    /* Ensure that the operand will remain sign-extended immediate.  */
18616    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18617    && ! TARGET_FAST_PREFIX
18618    && ! optimize_size"
18619   [(set (match_dup 0)
18620         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18621                          (const_int 0)]))]
18622 {
18623   operands[3]
18624     = gen_int_mode (INTVAL (operands[3])
18625                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18626   operands[2] = gen_lowpart (SImode, operands[2]);
18627 })
18628
18629 (define_split
18630   [(set (match_operand 0 "register_operand" "")
18631         (neg (match_operand 1 "register_operand" "")))
18632    (clobber (reg:CC FLAGS_REG))]
18633   "! TARGET_PARTIAL_REG_STALL && reload_completed
18634    && (GET_MODE (operands[0]) == HImode
18635        || (GET_MODE (operands[0]) == QImode 
18636            && (TARGET_PROMOTE_QImode || optimize_size)))"
18637   [(parallel [(set (match_dup 0)
18638                    (neg:SI (match_dup 1)))
18639               (clobber (reg:CC FLAGS_REG))])]
18640   "operands[0] = gen_lowpart (SImode, operands[0]);
18641    operands[1] = gen_lowpart (SImode, operands[1]);")
18642
18643 (define_split
18644   [(set (match_operand 0 "register_operand" "")
18645         (not (match_operand 1 "register_operand" "")))]
18646   "! TARGET_PARTIAL_REG_STALL && reload_completed
18647    && (GET_MODE (operands[0]) == HImode
18648        || (GET_MODE (operands[0]) == QImode 
18649            && (TARGET_PROMOTE_QImode || optimize_size)))"
18650   [(set (match_dup 0)
18651         (not:SI (match_dup 1)))]
18652   "operands[0] = gen_lowpart (SImode, operands[0]);
18653    operands[1] = gen_lowpart (SImode, operands[1]);")
18654
18655 (define_split 
18656   [(set (match_operand 0 "register_operand" "")
18657         (if_then_else (match_operator 1 "comparison_operator" 
18658                                 [(reg FLAGS_REG) (const_int 0)])
18659                       (match_operand 2 "register_operand" "")
18660                       (match_operand 3 "register_operand" "")))]
18661   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18662    && (GET_MODE (operands[0]) == HImode
18663        || (GET_MODE (operands[0]) == QImode 
18664            && (TARGET_PROMOTE_QImode || optimize_size)))"
18665   [(set (match_dup 0)
18666         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18667   "operands[0] = gen_lowpart (SImode, operands[0]);
18668    operands[2] = gen_lowpart (SImode, operands[2]);
18669    operands[3] = gen_lowpart (SImode, operands[3]);")
18670                         
18671 \f
18672 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18673 ;; transform a complex memory operation into two memory to register operations.
18674
18675 ;; Don't push memory operands
18676 (define_peephole2
18677   [(set (match_operand:SI 0 "push_operand" "")
18678         (match_operand:SI 1 "memory_operand" ""))
18679    (match_scratch:SI 2 "r")]
18680   "! optimize_size && ! TARGET_PUSH_MEMORY"
18681   [(set (match_dup 2) (match_dup 1))
18682    (set (match_dup 0) (match_dup 2))]
18683   "")
18684
18685 (define_peephole2
18686   [(set (match_operand:DI 0 "push_operand" "")
18687         (match_operand:DI 1 "memory_operand" ""))
18688    (match_scratch:DI 2 "r")]
18689   "! optimize_size && ! TARGET_PUSH_MEMORY"
18690   [(set (match_dup 2) (match_dup 1))
18691    (set (match_dup 0) (match_dup 2))]
18692   "")
18693
18694 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18695 ;; SImode pushes.
18696 (define_peephole2
18697   [(set (match_operand:SF 0 "push_operand" "")
18698         (match_operand:SF 1 "memory_operand" ""))
18699    (match_scratch:SF 2 "r")]
18700   "! optimize_size && ! TARGET_PUSH_MEMORY"
18701   [(set (match_dup 2) (match_dup 1))
18702    (set (match_dup 0) (match_dup 2))]
18703   "")
18704
18705 (define_peephole2
18706   [(set (match_operand:HI 0 "push_operand" "")
18707         (match_operand:HI 1 "memory_operand" ""))
18708    (match_scratch:HI 2 "r")]
18709   "! optimize_size && ! TARGET_PUSH_MEMORY"
18710   [(set (match_dup 2) (match_dup 1))
18711    (set (match_dup 0) (match_dup 2))]
18712   "")
18713
18714 (define_peephole2
18715   [(set (match_operand:QI 0 "push_operand" "")
18716         (match_operand:QI 1 "memory_operand" ""))
18717    (match_scratch:QI 2 "q")]
18718   "! optimize_size && ! TARGET_PUSH_MEMORY"
18719   [(set (match_dup 2) (match_dup 1))
18720    (set (match_dup 0) (match_dup 2))]
18721   "")
18722
18723 ;; Don't move an immediate directly to memory when the instruction
18724 ;; gets too big.
18725 (define_peephole2
18726   [(match_scratch:SI 1 "r")
18727    (set (match_operand:SI 0 "memory_operand" "")
18728         (const_int 0))]
18729   "! optimize_size
18730    && ! TARGET_USE_MOV0
18731    && TARGET_SPLIT_LONG_MOVES
18732    && get_attr_length (insn) >= ix86_cost->large_insn
18733    && peep2_regno_dead_p (0, FLAGS_REG)"
18734   [(parallel [(set (match_dup 1) (const_int 0))
18735               (clobber (reg:CC FLAGS_REG))])
18736    (set (match_dup 0) (match_dup 1))]
18737   "")
18738
18739 (define_peephole2
18740   [(match_scratch:HI 1 "r")
18741    (set (match_operand:HI 0 "memory_operand" "")
18742         (const_int 0))]
18743   "! optimize_size
18744    && ! TARGET_USE_MOV0
18745    && TARGET_SPLIT_LONG_MOVES
18746    && get_attr_length (insn) >= ix86_cost->large_insn
18747    && peep2_regno_dead_p (0, FLAGS_REG)"
18748   [(parallel [(set (match_dup 2) (const_int 0))
18749               (clobber (reg:CC FLAGS_REG))])
18750    (set (match_dup 0) (match_dup 1))]
18751   "operands[2] = gen_lowpart (SImode, operands[1]);")
18752
18753 (define_peephole2
18754   [(match_scratch:QI 1 "q")
18755    (set (match_operand:QI 0 "memory_operand" "")
18756         (const_int 0))]
18757   "! optimize_size
18758    && ! TARGET_USE_MOV0
18759    && TARGET_SPLIT_LONG_MOVES
18760    && get_attr_length (insn) >= ix86_cost->large_insn
18761    && peep2_regno_dead_p (0, FLAGS_REG)"
18762   [(parallel [(set (match_dup 2) (const_int 0))
18763               (clobber (reg:CC FLAGS_REG))])
18764    (set (match_dup 0) (match_dup 1))]
18765   "operands[2] = gen_lowpart (SImode, operands[1]);")
18766
18767 (define_peephole2
18768   [(match_scratch:SI 2 "r")
18769    (set (match_operand:SI 0 "memory_operand" "")
18770         (match_operand:SI 1 "immediate_operand" ""))]
18771   "! optimize_size
18772    && get_attr_length (insn) >= ix86_cost->large_insn
18773    && TARGET_SPLIT_LONG_MOVES"
18774   [(set (match_dup 2) (match_dup 1))
18775    (set (match_dup 0) (match_dup 2))]
18776   "")
18777
18778 (define_peephole2
18779   [(match_scratch:HI 2 "r")
18780    (set (match_operand:HI 0 "memory_operand" "")
18781         (match_operand:HI 1 "immediate_operand" ""))]
18782   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18783   && TARGET_SPLIT_LONG_MOVES"
18784   [(set (match_dup 2) (match_dup 1))
18785    (set (match_dup 0) (match_dup 2))]
18786   "")
18787
18788 (define_peephole2
18789   [(match_scratch:QI 2 "q")
18790    (set (match_operand:QI 0 "memory_operand" "")
18791         (match_operand:QI 1 "immediate_operand" ""))]
18792   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18793   && TARGET_SPLIT_LONG_MOVES"
18794   [(set (match_dup 2) (match_dup 1))
18795    (set (match_dup 0) (match_dup 2))]
18796   "")
18797
18798 ;; Don't compare memory with zero, load and use a test instead.
18799 (define_peephole2
18800   [(set (match_operand 0 "flags_reg_operand" "")
18801         (match_operator 1 "compare_operator"
18802           [(match_operand:SI 2 "memory_operand" "")
18803            (const_int 0)]))
18804    (match_scratch:SI 3 "r")]
18805   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18806   [(set (match_dup 3) (match_dup 2))
18807    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18808   "")
18809
18810 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18811 ;; Don't split NOTs with a displacement operand, because resulting XOR
18812 ;; will not be pairable anyway.
18813 ;;
18814 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18815 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18816 ;; so this split helps here as well.
18817 ;;
18818 ;; Note: Can't do this as a regular split because we can't get proper
18819 ;; lifetime information then.
18820
18821 (define_peephole2
18822   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18823         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18824   "!optimize_size
18825    && peep2_regno_dead_p (0, FLAGS_REG)
18826    && ((TARGET_PENTIUM 
18827         && (GET_CODE (operands[0]) != MEM
18828             || !memory_displacement_operand (operands[0], SImode)))
18829        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18830   [(parallel [(set (match_dup 0)
18831                    (xor:SI (match_dup 1) (const_int -1)))
18832               (clobber (reg:CC FLAGS_REG))])]
18833   "")
18834
18835 (define_peephole2
18836   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18837         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18838   "!optimize_size
18839    && peep2_regno_dead_p (0, FLAGS_REG)
18840    && ((TARGET_PENTIUM 
18841         && (GET_CODE (operands[0]) != MEM
18842             || !memory_displacement_operand (operands[0], HImode)))
18843        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18844   [(parallel [(set (match_dup 0)
18845                    (xor:HI (match_dup 1) (const_int -1)))
18846               (clobber (reg:CC FLAGS_REG))])]
18847   "")
18848
18849 (define_peephole2
18850   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18851         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18852   "!optimize_size
18853    && peep2_regno_dead_p (0, FLAGS_REG)
18854    && ((TARGET_PENTIUM 
18855         && (GET_CODE (operands[0]) != MEM
18856             || !memory_displacement_operand (operands[0], QImode)))
18857        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18858   [(parallel [(set (match_dup 0)
18859                    (xor:QI (match_dup 1) (const_int -1)))
18860               (clobber (reg:CC FLAGS_REG))])]
18861   "")
18862
18863 ;; Non pairable "test imm, reg" instructions can be translated to
18864 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18865 ;; byte opcode instead of two, have a short form for byte operands),
18866 ;; so do it for other CPUs as well.  Given that the value was dead,
18867 ;; this should not create any new dependencies.  Pass on the sub-word
18868 ;; versions if we're concerned about partial register stalls.
18869
18870 (define_peephole2
18871   [(set (match_operand 0 "flags_reg_operand" "")
18872         (match_operator 1 "compare_operator"
18873           [(and:SI (match_operand:SI 2 "register_operand" "")
18874                    (match_operand:SI 3 "immediate_operand" ""))
18875            (const_int 0)]))]
18876   "ix86_match_ccmode (insn, CCNOmode)
18877    && (true_regnum (operands[2]) != 0
18878        || (GET_CODE (operands[3]) == CONST_INT
18879            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18880    && peep2_reg_dead_p (1, operands[2])"
18881   [(parallel
18882      [(set (match_dup 0)
18883            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18884                             (const_int 0)]))
18885       (set (match_dup 2)
18886            (and:SI (match_dup 2) (match_dup 3)))])]
18887   "")
18888
18889 ;; We don't need to handle HImode case, because it will be promoted to SImode
18890 ;; on ! TARGET_PARTIAL_REG_STALL
18891
18892 (define_peephole2
18893   [(set (match_operand 0 "flags_reg_operand" "")
18894         (match_operator 1 "compare_operator"
18895           [(and:QI (match_operand:QI 2 "register_operand" "")
18896                    (match_operand:QI 3 "immediate_operand" ""))
18897            (const_int 0)]))]
18898   "! TARGET_PARTIAL_REG_STALL
18899    && ix86_match_ccmode (insn, CCNOmode)
18900    && true_regnum (operands[2]) != 0
18901    && peep2_reg_dead_p (1, operands[2])"
18902   [(parallel
18903      [(set (match_dup 0)
18904            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18905                             (const_int 0)]))
18906       (set (match_dup 2)
18907            (and:QI (match_dup 2) (match_dup 3)))])]
18908   "")
18909
18910 (define_peephole2
18911   [(set (match_operand 0 "flags_reg_operand" "")
18912         (match_operator 1 "compare_operator"
18913           [(and:SI
18914              (zero_extract:SI
18915                (match_operand 2 "ext_register_operand" "")
18916                (const_int 8)
18917                (const_int 8))
18918              (match_operand 3 "const_int_operand" ""))
18919            (const_int 0)]))]
18920   "! TARGET_PARTIAL_REG_STALL
18921    && ix86_match_ccmode (insn, CCNOmode)
18922    && true_regnum (operands[2]) != 0
18923    && peep2_reg_dead_p (1, operands[2])"
18924   [(parallel [(set (match_dup 0)
18925                    (match_op_dup 1
18926                      [(and:SI
18927                         (zero_extract:SI
18928                           (match_dup 2)
18929                           (const_int 8)
18930                           (const_int 8))
18931                         (match_dup 3))
18932                       (const_int 0)]))
18933               (set (zero_extract:SI (match_dup 2)
18934                                     (const_int 8)
18935                                     (const_int 8))
18936                    (and:SI 
18937                      (zero_extract:SI
18938                        (match_dup 2)
18939                        (const_int 8)
18940                        (const_int 8))
18941                      (match_dup 3)))])]
18942   "")
18943
18944 ;; Don't do logical operations with memory inputs.
18945 (define_peephole2
18946   [(match_scratch:SI 2 "r")
18947    (parallel [(set (match_operand:SI 0 "register_operand" "")
18948                    (match_operator:SI 3 "arith_or_logical_operator"
18949                      [(match_dup 0)
18950                       (match_operand:SI 1 "memory_operand" "")]))
18951               (clobber (reg:CC FLAGS_REG))])]
18952   "! optimize_size && ! TARGET_READ_MODIFY"
18953   [(set (match_dup 2) (match_dup 1))
18954    (parallel [(set (match_dup 0)
18955                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18956               (clobber (reg:CC FLAGS_REG))])]
18957   "")
18958
18959 (define_peephole2
18960   [(match_scratch:SI 2 "r")
18961    (parallel [(set (match_operand:SI 0 "register_operand" "")
18962                    (match_operator:SI 3 "arith_or_logical_operator"
18963                      [(match_operand:SI 1 "memory_operand" "")
18964                       (match_dup 0)]))
18965               (clobber (reg:CC FLAGS_REG))])]
18966   "! optimize_size && ! TARGET_READ_MODIFY"
18967   [(set (match_dup 2) (match_dup 1))
18968    (parallel [(set (match_dup 0)
18969                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18970               (clobber (reg:CC FLAGS_REG))])]
18971   "")
18972
18973 ; Don't do logical operations with memory outputs
18974 ;
18975 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18976 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18977 ; the same decoder scheduling characteristics as the original.
18978
18979 (define_peephole2
18980   [(match_scratch:SI 2 "r")
18981    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18982                    (match_operator:SI 3 "arith_or_logical_operator"
18983                      [(match_dup 0)
18984                       (match_operand:SI 1 "nonmemory_operand" "")]))
18985               (clobber (reg:CC FLAGS_REG))])]
18986   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18987   [(set (match_dup 2) (match_dup 0))
18988    (parallel [(set (match_dup 2)
18989                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18990               (clobber (reg:CC FLAGS_REG))])
18991    (set (match_dup 0) (match_dup 2))]
18992   "")
18993
18994 (define_peephole2
18995   [(match_scratch:SI 2 "r")
18996    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18997                    (match_operator:SI 3 "arith_or_logical_operator"
18998                      [(match_operand:SI 1 "nonmemory_operand" "")
18999                       (match_dup 0)]))
19000               (clobber (reg:CC FLAGS_REG))])]
19001   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19002   [(set (match_dup 2) (match_dup 0))
19003    (parallel [(set (match_dup 2)
19004                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19005               (clobber (reg:CC FLAGS_REG))])
19006    (set (match_dup 0) (match_dup 2))]
19007   "")
19008
19009 ;; Attempt to always use XOR for zeroing registers.
19010 (define_peephole2
19011   [(set (match_operand 0 "register_operand" "")
19012         (const_int 0))]
19013   "(GET_MODE (operands[0]) == QImode
19014     || GET_MODE (operands[0]) == HImode
19015     || GET_MODE (operands[0]) == SImode
19016     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19017    && (! TARGET_USE_MOV0 || optimize_size)
19018    && peep2_regno_dead_p (0, FLAGS_REG)"
19019   [(parallel [(set (match_dup 0) (const_int 0))
19020               (clobber (reg:CC FLAGS_REG))])]
19021   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19022                               operands[0]);")
19023
19024 (define_peephole2
19025   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19026         (const_int 0))]
19027   "(GET_MODE (operands[0]) == QImode
19028     || GET_MODE (operands[0]) == HImode)
19029    && (! TARGET_USE_MOV0 || optimize_size)
19030    && peep2_regno_dead_p (0, FLAGS_REG)"
19031   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19032               (clobber (reg:CC FLAGS_REG))])])
19033
19034 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19035 (define_peephole2
19036   [(set (match_operand 0 "register_operand" "")
19037         (const_int -1))]
19038   "(GET_MODE (operands[0]) == HImode
19039     || GET_MODE (operands[0]) == SImode 
19040     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19041    && (optimize_size || TARGET_PENTIUM)
19042    && peep2_regno_dead_p (0, FLAGS_REG)"
19043   [(parallel [(set (match_dup 0) (const_int -1))
19044               (clobber (reg:CC FLAGS_REG))])]
19045   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19046                               operands[0]);")
19047
19048 ;; Attempt to convert simple leas to adds. These can be created by
19049 ;; move expanders.
19050 (define_peephole2
19051   [(set (match_operand:SI 0 "register_operand" "")
19052         (plus:SI (match_dup 0)
19053                  (match_operand:SI 1 "nonmemory_operand" "")))]
19054   "peep2_regno_dead_p (0, FLAGS_REG)"
19055   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19056               (clobber (reg:CC FLAGS_REG))])]
19057   "")
19058
19059 (define_peephole2
19060   [(set (match_operand:SI 0 "register_operand" "")
19061         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19062                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19063   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19064   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19065               (clobber (reg:CC FLAGS_REG))])]
19066   "operands[2] = gen_lowpart (SImode, operands[2]);")
19067
19068 (define_peephole2
19069   [(set (match_operand:DI 0 "register_operand" "")
19070         (plus:DI (match_dup 0)
19071                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19072   "peep2_regno_dead_p (0, FLAGS_REG)"
19073   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19074               (clobber (reg:CC FLAGS_REG))])]
19075   "")
19076
19077 (define_peephole2
19078   [(set (match_operand:SI 0 "register_operand" "")
19079         (mult:SI (match_dup 0)
19080                  (match_operand:SI 1 "const_int_operand" "")))]
19081   "exact_log2 (INTVAL (operands[1])) >= 0
19082    && peep2_regno_dead_p (0, FLAGS_REG)"
19083   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19084               (clobber (reg:CC FLAGS_REG))])]
19085   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19086
19087 (define_peephole2
19088   [(set (match_operand:DI 0 "register_operand" "")
19089         (mult:DI (match_dup 0)
19090                  (match_operand:DI 1 "const_int_operand" "")))]
19091   "exact_log2 (INTVAL (operands[1])) >= 0
19092    && peep2_regno_dead_p (0, FLAGS_REG)"
19093   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19094               (clobber (reg:CC FLAGS_REG))])]
19095   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19096
19097 (define_peephole2
19098   [(set (match_operand:SI 0 "register_operand" "")
19099         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19100                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19101   "exact_log2 (INTVAL (operands[2])) >= 0
19102    && REGNO (operands[0]) == REGNO (operands[1])
19103    && peep2_regno_dead_p (0, FLAGS_REG)"
19104   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19105               (clobber (reg:CC FLAGS_REG))])]
19106   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19107
19108 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19109 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19110 ;; many CPUs it is also faster, since special hardware to avoid esp
19111 ;; dependencies is present.
19112
19113 ;; While some of these conversions may be done using splitters, we use peepholes
19114 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19115
19116 ;; Convert prologue esp subtractions to push.
19117 ;; We need register to push.  In order to keep verify_flow_info happy we have
19118 ;; two choices
19119 ;; - use scratch and clobber it in order to avoid dependencies
19120 ;; - use already live register
19121 ;; We can't use the second way right now, since there is no reliable way how to
19122 ;; verify that given register is live.  First choice will also most likely in
19123 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19124 ;; call clobbered registers are dead.  We may want to use base pointer as an
19125 ;; alternative when no register is available later.
19126
19127 (define_peephole2
19128   [(match_scratch:SI 0 "r")
19129    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19130               (clobber (reg:CC FLAGS_REG))
19131               (clobber (mem:BLK (scratch)))])]
19132   "optimize_size || !TARGET_SUB_ESP_4"
19133   [(clobber (match_dup 0))
19134    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19135               (clobber (mem:BLK (scratch)))])])
19136
19137 (define_peephole2
19138   [(match_scratch:SI 0 "r")
19139    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19140               (clobber (reg:CC FLAGS_REG))
19141               (clobber (mem:BLK (scratch)))])]
19142   "optimize_size || !TARGET_SUB_ESP_8"
19143   [(clobber (match_dup 0))
19144    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19145    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19146               (clobber (mem:BLK (scratch)))])])
19147
19148 ;; Convert esp subtractions to push.
19149 (define_peephole2
19150   [(match_scratch:SI 0 "r")
19151    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19152               (clobber (reg:CC FLAGS_REG))])]
19153   "optimize_size || !TARGET_SUB_ESP_4"
19154   [(clobber (match_dup 0))
19155    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19156
19157 (define_peephole2
19158   [(match_scratch:SI 0 "r")
19159    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19160               (clobber (reg:CC FLAGS_REG))])]
19161   "optimize_size || !TARGET_SUB_ESP_8"
19162   [(clobber (match_dup 0))
19163    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19164    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19165
19166 ;; Convert epilogue deallocator to pop.
19167 (define_peephole2
19168   [(match_scratch:SI 0 "r")
19169    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19170               (clobber (reg:CC FLAGS_REG))
19171               (clobber (mem:BLK (scratch)))])]
19172   "optimize_size || !TARGET_ADD_ESP_4"
19173   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19174               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19175               (clobber (mem:BLK (scratch)))])]
19176   "")
19177
19178 ;; Two pops case is tricky, since pop causes dependency on destination register.
19179 ;; We use two registers if available.
19180 (define_peephole2
19181   [(match_scratch:SI 0 "r")
19182    (match_scratch:SI 1 "r")
19183    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19184               (clobber (reg:CC FLAGS_REG))
19185               (clobber (mem:BLK (scratch)))])]
19186   "optimize_size || !TARGET_ADD_ESP_8"
19187   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19188               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19189               (clobber (mem:BLK (scratch)))])
19190    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19191               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19192   "")
19193
19194 (define_peephole2
19195   [(match_scratch:SI 0 "r")
19196    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19197               (clobber (reg:CC FLAGS_REG))
19198               (clobber (mem:BLK (scratch)))])]
19199   "optimize_size"
19200   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19201               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19202               (clobber (mem:BLK (scratch)))])
19203    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19204               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19205   "")
19206
19207 ;; Convert esp additions to pop.
19208 (define_peephole2
19209   [(match_scratch:SI 0 "r")
19210    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19211               (clobber (reg:CC FLAGS_REG))])]
19212   ""
19213   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19214               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19215   "")
19216
19217 ;; Two pops case is tricky, since pop causes dependency on destination register.
19218 ;; We use two registers if available.
19219 (define_peephole2
19220   [(match_scratch:SI 0 "r")
19221    (match_scratch:SI 1 "r")
19222    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19223               (clobber (reg:CC FLAGS_REG))])]
19224   ""
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    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19228               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19229   "")
19230
19231 (define_peephole2
19232   [(match_scratch:SI 0 "r")
19233    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19234               (clobber (reg:CC FLAGS_REG))])]
19235   "optimize_size"
19236   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19237               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
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 \f
19242 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19243 ;; required and register dies.  Similarly for 128 to plus -128.
19244 (define_peephole2
19245   [(set (match_operand 0 "flags_reg_operand" "")
19246         (match_operator 1 "compare_operator"
19247           [(match_operand 2 "register_operand" "")
19248            (match_operand 3 "const_int_operand" "")]))]
19249   "(INTVAL (operands[3]) == -1
19250     || INTVAL (operands[3]) == 1
19251     || INTVAL (operands[3]) == 128)
19252    && ix86_match_ccmode (insn, CCGCmode)
19253    && peep2_reg_dead_p (1, operands[2])"
19254   [(parallel [(set (match_dup 0)
19255                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19256               (clobber (match_dup 2))])]
19257   "")
19258 \f
19259 (define_peephole2
19260   [(match_scratch:DI 0 "r")
19261    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19262               (clobber (reg:CC FLAGS_REG))
19263               (clobber (mem:BLK (scratch)))])]
19264   "optimize_size || !TARGET_SUB_ESP_4"
19265   [(clobber (match_dup 0))
19266    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19267               (clobber (mem:BLK (scratch)))])])
19268
19269 (define_peephole2
19270   [(match_scratch:DI 0 "r")
19271    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19272               (clobber (reg:CC FLAGS_REG))
19273               (clobber (mem:BLK (scratch)))])]
19274   "optimize_size || !TARGET_SUB_ESP_8"
19275   [(clobber (match_dup 0))
19276    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19277    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19278               (clobber (mem:BLK (scratch)))])])
19279
19280 ;; Convert esp subtractions to push.
19281 (define_peephole2
19282   [(match_scratch:DI 0 "r")
19283    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19284               (clobber (reg:CC FLAGS_REG))])]
19285   "optimize_size || !TARGET_SUB_ESP_4"
19286   [(clobber (match_dup 0))
19287    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19288
19289 (define_peephole2
19290   [(match_scratch:DI 0 "r")
19291    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19292               (clobber (reg:CC FLAGS_REG))])]
19293   "optimize_size || !TARGET_SUB_ESP_8"
19294   [(clobber (match_dup 0))
19295    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19296    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19297
19298 ;; Convert epilogue deallocator to pop.
19299 (define_peephole2
19300   [(match_scratch:DI 0 "r")
19301    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19302               (clobber (reg:CC FLAGS_REG))
19303               (clobber (mem:BLK (scratch)))])]
19304   "optimize_size || !TARGET_ADD_ESP_4"
19305   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19306               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19307               (clobber (mem:BLK (scratch)))])]
19308   "")
19309
19310 ;; Two pops case is tricky, since pop causes dependency on destination register.
19311 ;; We use two registers if available.
19312 (define_peephole2
19313   [(match_scratch:DI 0 "r")
19314    (match_scratch:DI 1 "r")
19315    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19316               (clobber (reg:CC FLAGS_REG))
19317               (clobber (mem:BLK (scratch)))])]
19318   "optimize_size || !TARGET_ADD_ESP_8"
19319   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19320               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19321               (clobber (mem:BLK (scratch)))])
19322    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19323               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19324   "")
19325
19326 (define_peephole2
19327   [(match_scratch:DI 0 "r")
19328    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19329               (clobber (reg:CC FLAGS_REG))
19330               (clobber (mem:BLK (scratch)))])]
19331   "optimize_size"
19332   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19333               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19334               (clobber (mem:BLK (scratch)))])
19335    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19336               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19337   "")
19338
19339 ;; Convert esp additions to pop.
19340 (define_peephole2
19341   [(match_scratch:DI 0 "r")
19342    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19343               (clobber (reg:CC FLAGS_REG))])]
19344   ""
19345   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19346               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19347   "")
19348
19349 ;; Two pops case is tricky, since pop causes dependency on destination register.
19350 ;; We use two registers if available.
19351 (define_peephole2
19352   [(match_scratch:DI 0 "r")
19353    (match_scratch:DI 1 "r")
19354    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19355               (clobber (reg:CC FLAGS_REG))])]
19356   ""
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    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19360               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19361   "")
19362
19363 (define_peephole2
19364   [(match_scratch:DI 0 "r")
19365    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19366               (clobber (reg:CC FLAGS_REG))])]
19367   "optimize_size"
19368   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19369               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
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 \f
19374 ;; Convert imul by three, five and nine into lea
19375 (define_peephole2
19376   [(parallel
19377     [(set (match_operand:SI 0 "register_operand" "")
19378           (mult:SI (match_operand:SI 1 "register_operand" "")
19379                    (match_operand:SI 2 "const_int_operand" "")))
19380      (clobber (reg:CC FLAGS_REG))])]
19381   "INTVAL (operands[2]) == 3
19382    || INTVAL (operands[2]) == 5
19383    || INTVAL (operands[2]) == 9"
19384   [(set (match_dup 0)
19385         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19386                  (match_dup 1)))]
19387   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19388
19389 (define_peephole2
19390   [(parallel
19391     [(set (match_operand:SI 0 "register_operand" "")
19392           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19393                    (match_operand:SI 2 "const_int_operand" "")))
19394      (clobber (reg:CC FLAGS_REG))])]
19395   "!optimize_size 
19396    && (INTVAL (operands[2]) == 3
19397        || INTVAL (operands[2]) == 5
19398        || INTVAL (operands[2]) == 9)"
19399   [(set (match_dup 0) (match_dup 1))
19400    (set (match_dup 0)
19401         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19402                  (match_dup 0)))]
19403   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19404
19405 (define_peephole2
19406   [(parallel
19407     [(set (match_operand:DI 0 "register_operand" "")
19408           (mult:DI (match_operand:DI 1 "register_operand" "")
19409                    (match_operand:DI 2 "const_int_operand" "")))
19410      (clobber (reg:CC FLAGS_REG))])]
19411   "TARGET_64BIT
19412    && (INTVAL (operands[2]) == 3
19413        || INTVAL (operands[2]) == 5
19414        || INTVAL (operands[2]) == 9)"
19415   [(set (match_dup 0)
19416         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19417                  (match_dup 1)))]
19418   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19419
19420 (define_peephole2
19421   [(parallel
19422     [(set (match_operand:DI 0 "register_operand" "")
19423           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19424                    (match_operand:DI 2 "const_int_operand" "")))
19425      (clobber (reg:CC FLAGS_REG))])]
19426   "TARGET_64BIT
19427    && !optimize_size 
19428    && (INTVAL (operands[2]) == 3
19429        || INTVAL (operands[2]) == 5
19430        || INTVAL (operands[2]) == 9)"
19431   [(set (match_dup 0) (match_dup 1))
19432    (set (match_dup 0)
19433         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19434                  (match_dup 0)))]
19435   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19436
19437 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19438 ;; imul $32bit_imm, reg, reg is direct decoded.
19439 (define_peephole2
19440   [(match_scratch:DI 3 "r")
19441    (parallel [(set (match_operand:DI 0 "register_operand" "")
19442                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19443                             (match_operand:DI 2 "immediate_operand" "")))
19444               (clobber (reg:CC FLAGS_REG))])]
19445   "TARGET_K8 && !optimize_size
19446    && (GET_CODE (operands[2]) != CONST_INT
19447        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19448   [(set (match_dup 3) (match_dup 1))
19449    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19450               (clobber (reg:CC FLAGS_REG))])]
19451 "")
19452
19453 (define_peephole2
19454   [(match_scratch:SI 3 "r")
19455    (parallel [(set (match_operand:SI 0 "register_operand" "")
19456                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19457                             (match_operand:SI 2 "immediate_operand" "")))
19458               (clobber (reg:CC FLAGS_REG))])]
19459   "TARGET_K8 && !optimize_size
19460    && (GET_CODE (operands[2]) != CONST_INT
19461        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19462   [(set (match_dup 3) (match_dup 1))
19463    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19464               (clobber (reg:CC FLAGS_REG))])]
19465 "")
19466
19467 (define_peephole2
19468   [(match_scratch:SI 3 "r")
19469    (parallel [(set (match_operand:DI 0 "register_operand" "")
19470                    (zero_extend:DI
19471                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19472                               (match_operand:SI 2 "immediate_operand" ""))))
19473               (clobber (reg:CC FLAGS_REG))])]
19474   "TARGET_K8 && !optimize_size
19475    && (GET_CODE (operands[2]) != CONST_INT
19476        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19477   [(set (match_dup 3) (match_dup 1))
19478    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19479               (clobber (reg:CC FLAGS_REG))])]
19480 "")
19481
19482 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19483 ;; Convert it into imul reg, reg
19484 ;; It would be better to force assembler to encode instruction using long
19485 ;; immediate, but there is apparently no way to do so.
19486 (define_peephole2
19487   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19488                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19489                             (match_operand:DI 2 "const_int_operand" "")))
19490               (clobber (reg:CC FLAGS_REG))])
19491    (match_scratch:DI 3 "r")]
19492   "TARGET_K8 && !optimize_size
19493    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19494   [(set (match_dup 3) (match_dup 2))
19495    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19496               (clobber (reg:CC FLAGS_REG))])]
19497 {
19498   if (!rtx_equal_p (operands[0], operands[1]))
19499     emit_move_insn (operands[0], operands[1]);
19500 })
19501
19502 (define_peephole2
19503   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19504                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19505                             (match_operand:SI 2 "const_int_operand" "")))
19506               (clobber (reg:CC FLAGS_REG))])
19507    (match_scratch:SI 3 "r")]
19508   "TARGET_K8 && !optimize_size
19509    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19510   [(set (match_dup 3) (match_dup 2))
19511    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19512               (clobber (reg:CC FLAGS_REG))])]
19513 {
19514   if (!rtx_equal_p (operands[0], operands[1]))
19515     emit_move_insn (operands[0], operands[1]);
19516 })
19517
19518 (define_peephole2
19519   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19520                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19521                             (match_operand:HI 2 "immediate_operand" "")))
19522               (clobber (reg:CC FLAGS_REG))])
19523    (match_scratch:HI 3 "r")]
19524   "TARGET_K8 && !optimize_size"
19525   [(set (match_dup 3) (match_dup 2))
19526    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19527               (clobber (reg:CC FLAGS_REG))])]
19528 {
19529   if (!rtx_equal_p (operands[0], operands[1]))
19530     emit_move_insn (operands[0], operands[1]);
19531 })
19532 \f
19533 ;; Call-value patterns last so that the wildcard operand does not
19534 ;; disrupt insn-recog's switch tables.
19535
19536 (define_insn "*call_value_pop_0"
19537   [(set (match_operand 0 "" "")
19538         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19539               (match_operand:SI 2 "" "")))
19540    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19541                             (match_operand:SI 3 "immediate_operand" "")))]
19542   "!TARGET_64BIT"
19543 {
19544   if (SIBLING_CALL_P (insn))
19545     return "jmp\t%P1";
19546   else
19547     return "call\t%P1";
19548 }
19549   [(set_attr "type" "callv")])
19550
19551 (define_insn "*call_value_pop_1"
19552   [(set (match_operand 0 "" "")
19553         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19554               (match_operand:SI 2 "" "")))
19555    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19556                             (match_operand:SI 3 "immediate_operand" "i")))]
19557   "!TARGET_64BIT"
19558 {
19559   if (constant_call_address_operand (operands[1], Pmode))
19560     {
19561       if (SIBLING_CALL_P (insn))
19562         return "jmp\t%P1";
19563       else
19564         return "call\t%P1";
19565     }
19566   if (SIBLING_CALL_P (insn))
19567     return "jmp\t%A1";
19568   else
19569     return "call\t%A1";
19570 }
19571   [(set_attr "type" "callv")])
19572
19573 (define_insn "*call_value_0"
19574   [(set (match_operand 0 "" "")
19575         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19576               (match_operand:SI 2 "" "")))]
19577   "!TARGET_64BIT"
19578 {
19579   if (SIBLING_CALL_P (insn))
19580     return "jmp\t%P1";
19581   else
19582     return "call\t%P1";
19583 }
19584   [(set_attr "type" "callv")])
19585
19586 (define_insn "*call_value_0_rex64"
19587   [(set (match_operand 0 "" "")
19588         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19589               (match_operand:DI 2 "const_int_operand" "")))]
19590   "TARGET_64BIT"
19591 {
19592   if (SIBLING_CALL_P (insn))
19593     return "jmp\t%P1";
19594   else
19595     return "call\t%P1";
19596 }
19597   [(set_attr "type" "callv")])
19598
19599 (define_insn "*call_value_1"
19600   [(set (match_operand 0 "" "")
19601         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19602               (match_operand:SI 2 "" "")))]
19603   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19604 {
19605   if (constant_call_address_operand (operands[1], Pmode))
19606     return "call\t%P1";
19607   return "call\t%A1";
19608 }
19609   [(set_attr "type" "callv")])
19610
19611 (define_insn "*sibcall_value_1"
19612   [(set (match_operand 0 "" "")
19613         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19614               (match_operand:SI 2 "" "")))]
19615   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19616 {
19617   if (constant_call_address_operand (operands[1], Pmode))
19618     return "jmp\t%P1";
19619   return "jmp\t%A1";
19620 }
19621   [(set_attr "type" "callv")])
19622
19623 (define_insn "*call_value_1_rex64"
19624   [(set (match_operand 0 "" "")
19625         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19626               (match_operand:DI 2 "" "")))]
19627   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19628 {
19629   if (constant_call_address_operand (operands[1], Pmode))
19630     return "call\t%P1";
19631   return "call\t%A1";
19632 }
19633   [(set_attr "type" "callv")])
19634
19635 (define_insn "*sibcall_value_1_rex64"
19636   [(set (match_operand 0 "" "")
19637         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19638               (match_operand:DI 2 "" "")))]
19639   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19640   "jmp\t%P1"
19641   [(set_attr "type" "callv")])
19642
19643 (define_insn "*sibcall_value_1_rex64_v"
19644   [(set (match_operand 0 "" "")
19645         (call (mem:QI (reg:DI 40))
19646               (match_operand:DI 1 "" "")))]
19647   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19648   "jmp\t*%%r11"
19649   [(set_attr "type" "callv")])
19650 \f
19651 (define_insn "trap"
19652   [(trap_if (const_int 1) (const_int 5))]
19653   ""
19654   "int\t$5")
19655
19656 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19657 ;;; for the sake of bounds checking.  By emitting bounds checks as
19658 ;;; conditional traps rather than as conditional jumps around
19659 ;;; unconditional traps we avoid introducing spurious basic-block
19660 ;;; boundaries and facilitate elimination of redundant checks.  In
19661 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19662 ;;; interrupt 5.
19663 ;;; 
19664 ;;; FIXME: Static branch prediction rules for ix86 are such that
19665 ;;; forward conditional branches predict as untaken.  As implemented
19666 ;;; below, pseudo conditional traps violate that rule.  We should use
19667 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19668 ;;; section loaded at the end of the text segment and branch forward
19669 ;;; there on bounds-failure, and then jump back immediately (in case
19670 ;;; the system chooses to ignore bounds violations, or to report
19671 ;;; violations and continue execution).
19672
19673 (define_expand "conditional_trap"
19674   [(trap_if (match_operator 0 "comparison_operator"
19675              [(match_dup 2) (const_int 0)])
19676             (match_operand 1 "const_int_operand" ""))]
19677   ""
19678 {
19679   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19680                               ix86_expand_compare (GET_CODE (operands[0]),
19681                                                    NULL, NULL),
19682                               operands[1]));
19683   DONE;
19684 })
19685
19686 (define_insn "*conditional_trap_1"
19687   [(trap_if (match_operator 0 "comparison_operator"
19688              [(reg FLAGS_REG) (const_int 0)])
19689             (match_operand 1 "const_int_operand" ""))]
19690   ""
19691 {
19692   operands[2] = gen_label_rtx ();
19693   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19694   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19695                              CODE_LABEL_NUMBER (operands[2]));
19696   RET;
19697 })
19698
19699         ;; Pentium III SIMD instructions.
19700
19701 ;; Moves for SSE/MMX regs.
19702
19703 (define_expand "movv4sf"
19704   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19705         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19706   "TARGET_SSE"
19707 {
19708   ix86_expand_vector_move (V4SFmode, operands);
19709   DONE;
19710 })
19711
19712 (define_insn "*movv4sf_internal"
19713   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19714         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19715   "TARGET_SSE"
19716   "@
19717     xorps\t%0, %0
19718     movaps\t{%1, %0|%0, %1}
19719     movaps\t{%1, %0|%0, %1}"
19720   [(set_attr "type" "ssemov")
19721    (set_attr "mode" "V4SF")])
19722
19723 (define_split
19724   [(set (match_operand:V4SF 0 "register_operand" "")
19725         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19726   "TARGET_SSE && reload_completed"
19727   [(set (match_dup 0)
19728         (vec_merge:V4SF
19729          (vec_duplicate:V4SF (match_dup 1))
19730          (match_dup 2)
19731          (const_int 1)))]
19732 {
19733   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19734   operands[2] = CONST0_RTX (V4SFmode);
19735 })
19736
19737 (define_expand "movv2df"
19738   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19739         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19740   "TARGET_SSE"
19741 {
19742   ix86_expand_vector_move (V2DFmode, operands);
19743   DONE;
19744 })
19745
19746 (define_insn "*movv2df_internal"
19747   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19748         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19749   "TARGET_SSE
19750    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19751 {
19752   switch (which_alternative)
19753     {
19754     case 0:
19755       if (get_attr_mode (insn) == MODE_V4SF)
19756         return "xorps\t%0, %0";
19757       else
19758         return "xorpd\t%0, %0";
19759     case 1:
19760     case 2:
19761       if (get_attr_mode (insn) == MODE_V4SF)
19762         return "movaps\t{%1, %0|%0, %1}";
19763       else
19764         return "movapd\t{%1, %0|%0, %1}";
19765     default:
19766       abort ();
19767     }
19768 }
19769   [(set_attr "type" "ssemov")
19770    (set (attr "mode")
19771         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
19772                  (const_string "V4SF")
19773                (eq_attr "alternative" "0,1")
19774                  (if_then_else
19775                    (ne (symbol_ref "optimize_size")
19776                        (const_int 0))
19777                    (const_string "V4SF")
19778                    (const_string "V2DF"))
19779                (eq_attr "alternative" "2")
19780                  (if_then_else
19781                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19782                             (const_int 0))
19783                         (ne (symbol_ref "optimize_size")
19784                             (const_int 0)))
19785                    (const_string "V4SF")
19786                    (const_string "V2DF"))]
19787                (const_string "V2DF")))])
19788
19789 (define_split
19790   [(set (match_operand:V2DF 0 "register_operand" "")
19791         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19792   "TARGET_SSE2 && reload_completed"
19793   [(set (match_dup 0)
19794         (vec_merge:V2DF
19795          (vec_duplicate:V2DF (match_dup 1))
19796          (match_dup 2)
19797          (const_int 1)))]
19798 {
19799   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19800   operands[2] = CONST0_RTX (V2DFmode);
19801 })
19802
19803 ;; 16 byte integral modes handled by SSE, minus TImode, which gets
19804 ;; special-cased for TARGET_64BIT.
19805 (define_mode_macro SSEMODEI [V16QI V8HI V4SI V2DI])
19806
19807 (define_expand "mov<mode>"
19808   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "")
19809         (match_operand:SSEMODEI 1 "nonimmediate_operand" ""))]
19810   "TARGET_SSE"
19811 {
19812   ix86_expand_vector_move (<MODE>mode, operands);
19813   DONE;
19814 })
19815
19816 (define_insn "*mov<mode>_internal"
19817   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "=x,x ,m")
19818         (match_operand:SSEMODEI 1 "vector_move_operand"  "C ,xm,x"))]
19819   "TARGET_SSE
19820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19821 {
19822   switch (which_alternative)
19823     {
19824     case 0:
19825       if (get_attr_mode (insn) == MODE_V4SF)
19826         return "xorps\t%0, %0";
19827       else
19828         return "pxor\t%0, %0";
19829     case 1:
19830     case 2:
19831       if (get_attr_mode (insn) == MODE_V4SF)
19832         return "movaps\t{%1, %0|%0, %1}";
19833       else
19834         return "movdqa\t{%1, %0|%0, %1}";
19835     default:
19836       abort ();
19837     }
19838 }
19839   [(set_attr "type" "ssemov")
19840    (set (attr "mode")
19841         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
19842                  (const_string "V4SF")
19843
19844                (eq_attr "alternative" "0,1")
19845                  (if_then_else
19846                    (ne (symbol_ref "optimize_size")
19847                        (const_int 0))
19848                    (const_string "V4SF")
19849                    (const_string "TI"))
19850                (eq_attr "alternative" "2")
19851                  (if_then_else
19852                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19853                             (const_int 0))
19854                         (ne (symbol_ref "optimize_size")
19855                             (const_int 0)))
19856                    (const_string "V4SF")
19857                    (const_string "TI"))]
19858                (const_string "TI")))])
19859
19860 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
19861 (define_mode_macro MMXMODEI [V8QI V4HI V2SI])
19862
19863 (define_expand "mov<mode>"
19864   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "")
19865         (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))]
19866   "TARGET_MMX"
19867 {
19868   ix86_expand_vector_move (<MODE>mode, operands);
19869   DONE;
19870 })
19871
19872 (define_insn "*mov<mode>_internal_rex64"
19873   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
19874                                 "=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x")
19875         (match_operand:MMXMODEI 1 "vector_move_operand"
19876                                 "Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
19877   "TARGET_64BIT && TARGET_MMX
19878    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19879   "@
19880     movq\t{%1, %0|%0, %1}
19881     movq\t{%1, %0|%0, %1}
19882     pxor\t%0, %0
19883     movq\t{%1, %0|%0, %1}
19884     movq\t{%1, %0|%0, %1}
19885     movdq2q\t{%1, %0|%0, %1}
19886     movq2dq\t{%1, %0|%0, %1}
19887     pxor\t%0, %0
19888     movq\t{%1, %0|%0, %1}
19889     movq\t{%1, %0|%0, %1}
19890     movd\t{%1, %0|%0, %1}
19891     movd\t{%1, %0|%0, %1}"
19892   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
19893    (set_attr "mode" "DI")])
19894
19895 (define_insn "*mov<mode>_internal"
19896   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
19897                                 "=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m")
19898         (match_operand:MMXMODEI 1 "vector_move_operand"
19899                                 "C  ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x"))]
19900   "TARGET_MMX
19901    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19902   "@
19903     pxor\t%0, %0
19904     movq\t{%1, %0|%0, %1}
19905     movq\t{%1, %0|%0, %1}
19906     movdq2q\t{%1, %0|%0, %1}
19907     movq2dq\t{%1, %0|%0, %1}
19908     pxor\t%0, %0
19909     movq\t{%1, %0|%0, %1}
19910     movq\t{%1, %0|%0, %1}
19911     xorps\t%0, %0
19912     movaps\t{%1, %0|%0, %1}
19913     movlps\t{%1, %0|%0, %1}
19914     movlps\t{%1, %0|%0, %1}"
19915   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
19916    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF")])
19917
19918 (define_expand "movv2sf"
19919   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19920         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19921   "TARGET_MMX"
19922 {
19923   ix86_expand_vector_move (V2SFmode, operands);
19924   DONE;
19925 })
19926
19927 (define_insn "*movv2sf_internal_rex64"
19928   [(set (match_operand:V2SF 0 "nonimmediate_operand"
19929                                 "=rm,r,*y ,*y ,m ,*y,Y ,x,x ,m,r,x")
19930         (match_operand:V2SF 1 "vector_move_operand"
19931                                 "Cr ,m ,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
19932   "TARGET_64BIT && TARGET_MMX
19933    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19934   "@
19935     movq\t{%1, %0|%0, %1}
19936     movq\t{%1, %0|%0, %1}
19937     pxor\t%0, %0
19938     movq\t{%1, %0|%0, %1}
19939     movq\t{%1, %0|%0, %1}
19940     movdq2q\t{%1, %0|%0, %1}
19941     movq2dq\t{%1, %0|%0, %1}
19942     xorps\t%0, %0
19943     movlps\t{%1, %0|%0, %1}
19944     movlps\t{%1, %0|%0, %1}
19945     movd\t{%1, %0|%0, %1}
19946     movd\t{%1, %0|%0, %1}"
19947   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
19948    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V2SF,V2SF,DI,DI")])
19949
19950 (define_insn "*movv2sf_internal"
19951   [(set (match_operand:V2SF 0 "nonimmediate_operand"
19952                                         "=*y,*y ,m,*y,*Y,*x,*x ,m")
19953         (match_operand:V2SF 1 "vector_move_operand"
19954                                         "C ,*ym,*y,*Y,*y,C ,*xm,*x"))]
19955   "TARGET_MMX
19956    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19957   "@
19958     pxor\t%0, %0
19959     movq\t{%1, %0|%0, %1}
19960     movq\t{%1, %0|%0, %1}
19961     movdq2q\t{%1, %0|%0, %1}
19962     movq2dq\t{%1, %0|%0, %1}
19963     xorps\t%0, %0
19964     movlps\t{%1, %0|%0, %1}
19965     movlps\t{%1, %0|%0, %1}"
19966   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19967    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
19968
19969 (define_expand "movti"
19970   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19971         (match_operand:TI 1 "nonimmediate_operand" ""))]
19972   "TARGET_SSE || TARGET_64BIT"
19973 {
19974   if (TARGET_64BIT)
19975     ix86_expand_move (TImode, operands);
19976   else
19977     ix86_expand_vector_move (TImode, operands);
19978   DONE;
19979 })
19980
19981 (define_insn "*movti_internal"
19982   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19983         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19984   "TARGET_SSE && !TARGET_64BIT
19985    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19986 {
19987   switch (which_alternative)
19988     {
19989     case 0:
19990       if (get_attr_mode (insn) == MODE_V4SF)
19991         return "xorps\t%0, %0";
19992       else
19993         return "pxor\t%0, %0";
19994     case 1:
19995     case 2:
19996       if (get_attr_mode (insn) == MODE_V4SF)
19997         return "movaps\t{%1, %0|%0, %1}";
19998       else
19999         return "movdqa\t{%1, %0|%0, %1}";
20000     default:
20001       abort ();
20002     }
20003 }
20004   [(set_attr "type" "ssemov,ssemov,ssemov")
20005    (set (attr "mode")
20006         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
20007                  (const_string "V4SF")
20008
20009                (eq_attr "alternative" "0,1")
20010                  (if_then_else
20011                    (ne (symbol_ref "optimize_size")
20012                        (const_int 0))
20013                    (const_string "V4SF")
20014                    (const_string "TI"))
20015                (eq_attr "alternative" "2")
20016                  (if_then_else
20017                    (ne (symbol_ref "optimize_size")
20018                        (const_int 0))
20019                    (const_string "V4SF")
20020                    (const_string "TI"))]
20021                (const_string "TI")))])
20022
20023 (define_insn "*movti_rex64"
20024   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20025         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20026   "TARGET_64BIT
20027    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20028 {
20029   switch (which_alternative)
20030     {
20031     case 0:
20032     case 1:
20033       return "#";
20034     case 2:
20035       if (get_attr_mode (insn) == MODE_V4SF)
20036         return "xorps\t%0, %0";
20037       else
20038         return "pxor\t%0, %0";
20039     case 3:
20040     case 4:
20041       if (get_attr_mode (insn) == MODE_V4SF)
20042         return "movaps\t{%1, %0|%0, %1}";
20043       else
20044         return "movdqa\t{%1, %0|%0, %1}";
20045     default:
20046       abort ();
20047     }
20048 }
20049   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20050    (set (attr "mode")
20051         (cond [(eq_attr "alternative" "2,3")
20052                  (if_then_else
20053                    (ne (symbol_ref "optimize_size")
20054                        (const_int 0))
20055                    (const_string "V4SF")
20056                    (const_string "TI"))
20057                (eq_attr "alternative" "4")
20058                  (if_then_else
20059                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20060                             (const_int 0))
20061                         (ne (symbol_ref "optimize_size")
20062                             (const_int 0)))
20063                    (const_string "V4SF")
20064                    (const_string "TI"))]
20065                (const_string "DI")))])
20066
20067 (define_expand "movtf"
20068   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20069         (match_operand:TF 1 "nonimmediate_operand" ""))]
20070   "TARGET_64BIT"
20071 {
20072   ix86_expand_move (TFmode, operands);
20073   DONE;
20074 })
20075
20076 (define_insn "*movtf_internal"
20077   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20078         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20079   "TARGET_64BIT
20080    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20081 {
20082   switch (which_alternative)
20083     {
20084     case 0:
20085     case 1:
20086       return "#";
20087     case 2:
20088       if (get_attr_mode (insn) == MODE_V4SF)
20089         return "xorps\t%0, %0";
20090       else
20091         return "pxor\t%0, %0";
20092     case 3:
20093     case 4:
20094       if (get_attr_mode (insn) == MODE_V4SF)
20095         return "movaps\t{%1, %0|%0, %1}";
20096       else
20097         return "movdqa\t{%1, %0|%0, %1}";
20098     default:
20099       abort ();
20100     }
20101 }
20102   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20103    (set (attr "mode")
20104         (cond [(eq_attr "alternative" "2,3")
20105                  (if_then_else
20106                    (ne (symbol_ref "optimize_size")
20107                        (const_int 0))
20108                    (const_string "V4SF")
20109                    (const_string "TI"))
20110                (eq_attr "alternative" "4")
20111                  (if_then_else
20112                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20113                             (const_int 0))
20114                         (ne (symbol_ref "optimize_size")
20115                             (const_int 0)))
20116                    (const_string "V4SF")
20117                    (const_string "TI"))]
20118                (const_string "DI")))])
20119
20120 (define_mode_macro SSEPUSH [V16QI V8HI V4SI V2DI TI V4SF V2DF])
20121
20122 (define_insn "*push<mode>"
20123   [(set (match_operand:SSEPUSH 0 "push_operand" "=<")
20124         (match_operand:SSEPUSH 1 "register_operand" "x"))]
20125   "TARGET_SSE"
20126   "#")
20127
20128 (define_mode_macro MMXPUSH [V8QI V4HI V2SI V2SF])
20129
20130 (define_insn "*push<mode>"
20131   [(set (match_operand:MMXPUSH 0 "push_operand" "=<")
20132         (match_operand:MMXPUSH 1 "register_operand" "xy"))]
20133   "TARGET_MMX"
20134   "#")
20135
20136 (define_split
20137   [(set (match_operand 0 "push_operand" "")
20138         (match_operand 1 "register_operand" ""))]
20139   "!TARGET_64BIT && reload_completed
20140    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20141   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20142    (set (match_dup 2) (match_dup 1))]
20143   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20144                                  stack_pointer_rtx);
20145    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20146
20147 (define_split
20148   [(set (match_operand 0 "push_operand" "")
20149         (match_operand 1 "register_operand" ""))]
20150   "TARGET_64BIT && reload_completed
20151    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20152   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20153    (set (match_dup 2) (match_dup 1))]
20154   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20155                                  stack_pointer_rtx);
20156    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20157
20158
20159 (define_split
20160   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20161         (match_operand:TI 1 "general_operand" ""))]
20162   "reload_completed && !SSE_REG_P (operands[0])
20163    && !SSE_REG_P (operands[1])"
20164   [(const_int 0)]
20165   "ix86_split_long_move (operands); DONE;")
20166
20167 (define_split
20168   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20169         (match_operand:TF 1 "general_operand" ""))]
20170   "reload_completed && !SSE_REG_P (operands[0])
20171    && !SSE_REG_P (operands[1])"
20172   [(const_int 0)]
20173   "ix86_split_long_move (operands); DONE;")
20174
20175 ;; All 16-byte vector modes handled by SSE
20176 (define_mode_macro SSEMODE [V16QI V8HI V4SI V2DI V4SF V2DF])
20177
20178 (define_expand "movmisalign<mode>"
20179   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
20180         (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
20181   "TARGET_SSE"
20182 {
20183   ix86_expand_vector_move_misalign (<MODE>mode, operands);
20184   DONE;
20185 })
20186
20187 ;; All 8-byte vector modes handled by MMX
20188 (define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF])
20189
20190 (define_expand "movmisalign<mode>"
20191   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
20192         (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
20193   "TARGET_MMX"
20194 {
20195   ix86_expand_vector_move (<MODE>mode, operands);
20196   DONE;
20197 })
20198
20199 ;; These two patterns are useful for specifying exactly whether to use
20200 ;; movaps or movups
20201 (define_expand "sse_movaps"
20202   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20203         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20204                      UNSPEC_MOVA))]
20205   "TARGET_SSE"
20206 {
20207   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20208     {
20209       rtx tmp = gen_reg_rtx (V4SFmode);
20210       emit_insn (gen_sse_movaps (tmp, operands[1]));
20211       emit_move_insn (operands[0], tmp);
20212       DONE;
20213     }
20214 })
20215
20216 (define_insn "*sse_movaps_1"
20217   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20218         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20219                      UNSPEC_MOVA))]
20220   "TARGET_SSE
20221    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20222   "movaps\t{%1, %0|%0, %1}"
20223   [(set_attr "type" "ssemov,ssemov")
20224    (set_attr "mode" "V4SF")])
20225
20226 (define_expand "sse_movups"
20227   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20228         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20229                      UNSPEC_MOVU))]
20230   "TARGET_SSE"
20231 {
20232   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20233     {
20234       rtx tmp = gen_reg_rtx (V4SFmode);
20235       emit_insn (gen_sse_movups (tmp, operands[1]));
20236       emit_move_insn (operands[0], tmp);
20237       DONE;
20238     }
20239 })
20240
20241 (define_insn "*sse_movups_1"
20242   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20243         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20244                      UNSPEC_MOVU))]
20245   "TARGET_SSE
20246    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20247   "movups\t{%1, %0|%0, %1}"
20248   [(set_attr "type" "ssecvt,ssecvt")
20249    (set_attr "mode" "V4SF")])
20250
20251 ;; SSE Strange Moves.
20252
20253 (define_insn "sse_movmskps"
20254   [(set (match_operand:SI 0 "register_operand" "=r")
20255         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20256                    UNSPEC_MOVMSK))]
20257   "TARGET_SSE"
20258   "movmskps\t{%1, %0|%0, %1}"
20259   [(set_attr "type" "ssecvt")
20260    (set_attr "mode" "V4SF")])
20261
20262 (define_insn "mmx_pmovmskb"
20263   [(set (match_operand:SI 0 "register_operand" "=r")
20264         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20265                    UNSPEC_MOVMSK))]
20266   "TARGET_SSE || TARGET_3DNOW_A"
20267   "pmovmskb\t{%1, %0|%0, %1}"
20268   [(set_attr "type" "ssecvt")
20269    (set_attr "mode" "V4SF")])
20270
20271
20272 (define_insn "mmx_maskmovq"
20273   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20274         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20275                       (match_operand:V8QI 2 "register_operand" "y")]
20276                      UNSPEC_MASKMOV))]
20277   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20278   ;; @@@ check ordering of operands in intel/nonintel syntax
20279   "maskmovq\t{%2, %1|%1, %2}"
20280   [(set_attr "type" "mmxcvt")
20281    (set_attr "mode" "DI")])
20282
20283 (define_insn "mmx_maskmovq_rex"
20284   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20285         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20286                       (match_operand:V8QI 2 "register_operand" "y")]
20287                      UNSPEC_MASKMOV))]
20288   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20289   ;; @@@ check ordering of operands in intel/nonintel syntax
20290   "maskmovq\t{%2, %1|%1, %2}"
20291   [(set_attr "type" "mmxcvt")
20292    (set_attr "mode" "DI")])
20293
20294 (define_insn "sse_movntv4sf"
20295   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20296         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20297                      UNSPEC_MOVNT))]
20298   "TARGET_SSE"
20299   "movntps\t{%1, %0|%0, %1}"
20300   [(set_attr "type" "ssemov")
20301    (set_attr "mode" "V4SF")])
20302
20303 (define_insn "sse_movntdi"
20304   [(set (match_operand:DI 0 "memory_operand" "=m")
20305         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20306                    UNSPEC_MOVNT))]
20307   "TARGET_SSE || TARGET_3DNOW_A"
20308   "movntq\t{%1, %0|%0, %1}"
20309   [(set_attr "type" "mmxmov")
20310    (set_attr "mode" "DI")])
20311
20312 (define_insn "sse_movhlps"
20313   [(set (match_operand:V4SF 0 "register_operand" "=x")
20314         (vec_merge:V4SF
20315          (match_operand:V4SF 1 "register_operand" "0")
20316          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20317                           (parallel [(const_int 2)
20318                                      (const_int 3)
20319                                      (const_int 0)
20320                                      (const_int 1)]))
20321          (const_int 3)))]
20322   "TARGET_SSE"
20323   "movhlps\t{%2, %0|%0, %2}"
20324   [(set_attr "type" "ssecvt")
20325    (set_attr "mode" "V4SF")])
20326
20327 (define_insn "sse_movlhps"
20328   [(set (match_operand:V4SF 0 "register_operand" "=x")
20329         (vec_merge:V4SF
20330          (match_operand:V4SF 1 "register_operand" "0")
20331          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20332                           (parallel [(const_int 2)
20333                                      (const_int 3)
20334                                      (const_int 0)
20335                                      (const_int 1)]))
20336          (const_int 12)))]
20337   "TARGET_SSE"
20338   "movlhps\t{%2, %0|%0, %2}"
20339   [(set_attr "type" "ssecvt")
20340    (set_attr "mode" "V4SF")])
20341
20342 ;; Store the high V2SF of the source vector to the destination.
20343 (define_insn "sse_storehps"
20344   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
20345         (vec_select:V2SF
20346           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
20347           (parallel [(const_int 2) (const_int 3)])))]
20348   "TARGET_SSE"
20349   "@
20350    movhps\t{%1, %0|%0, %1}
20351    movhlps\t{%1, %0|%0, %1}
20352    #"
20353   [(set_attr "type" "ssecvt")
20354    (set_attr "mode" "V2SF")])
20355
20356 (define_split
20357   [(set (match_operand:V2SF 0 "register_operand" "")
20358         (vec_select:V2SF
20359           (match_operand:V4SF 1 "memory_operand" "")
20360           (parallel [(const_int 2) (const_int 3)])))]
20361   "TARGET_SSE && reload_completed"
20362   [(const_int 0)]
20363 {
20364   emit_move_insn (operands[0], adjust_address (operands[1], V2SFmode, 8));
20365   DONE;
20366 })
20367
20368 ;; Load the high V2SF of the target vector from the source vector.
20369 (define_insn "sse_loadhps"
20370   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
20371         (vec_concat:V4SF
20372           (vec_select:V2SF
20373             (match_operand:V4SF 1 "nonimmediate_operand" "0,0,0")
20374             (parallel [(const_int 0) (const_int 1)]))
20375           (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
20376   "TARGET_SSE"
20377   "@
20378    movhps\t{%2, %0|%0, %2}
20379    movlhps\t{%2, %0|%0, %2}
20380    #"
20381   [(set_attr "type" "ssecvt")
20382    (set_attr "mode" "V2SF")])
20383
20384 (define_split
20385   [(set (match_operand:V4SF 0 "memory_operand" "")
20386         (vec_concat:V4SF
20387           (vec_select:V2SF
20388             (match_dup 0)
20389             (parallel [(const_int 0) (const_int 1)]))
20390           (match_operand:V2SF 1 "register_operand" "")))]
20391   "TARGET_SSE && reload_completed"
20392   [(const_int 0)]
20393 {
20394   emit_move_insn (adjust_address (operands[0], V2SFmode, 8), operands[1]);
20395   DONE;
20396 })
20397
20398 ;; Store the low V2SF of the source vector to the destination.
20399 (define_expand "sse_storelps"
20400   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20401         (vec_select:V2SF
20402           (match_operand:V4SF 1 "nonimmediate_operand" "")
20403           (parallel [(const_int 0) (const_int 1)])))]
20404   "TARGET_SSE"
20405 {
20406   operands[1] = gen_lowpart (V2SFmode, operands[1]);
20407   emit_move_insn (operands[0], operands[1]);
20408   DONE;
20409 })
20410
20411 ;; Load the low V2SF of the target vector from the source vector.
20412 (define_insn "sse_loadlps"
20413   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
20414         (vec_concat:V4SF
20415           (match_operand:V2SF 2 "nonimmediate_operand" "m,0,x")
20416           (vec_select:V2SF
20417             (match_operand:V4SF 1 "nonimmediate_operand" "0,x,0")
20418             (parallel [(const_int 2) (const_int 3)]))))]
20419   "TARGET_SSE"
20420 {
20421   static const char * const alt[] = {
20422     "movlps\t{%2, %0|%0, %2}",
20423     "shufps\t{%2, %1, %0|%0, %1, %2}",
20424     "movlps\t{%2, %0|%0, %2}"
20425   };
20426
20427   if (which_alternative == 1)
20428     operands[2] = GEN_INT (0xe4);
20429
20430   return alt[which_alternative];
20431 }
20432   [(set_attr "type" "ssecvt")
20433    (set_attr "mode" "V2SF")])
20434
20435 (define_expand "sse_loadss"
20436   [(match_operand:V4SF 0 "register_operand" "")
20437    (match_operand:SF 1 "memory_operand" "")]
20438   "TARGET_SSE"
20439 {
20440   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20441                                CONST0_RTX (V4SFmode)));
20442   DONE;
20443 })
20444
20445 (define_insn "sse_loadss_1"
20446   [(set (match_operand:V4SF 0 "register_operand" "=x")
20447         (vec_merge:V4SF
20448          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20449          (match_operand:V4SF 2 "const0_operand" "X")
20450          (const_int 1)))]
20451   "TARGET_SSE"
20452   "movss\t{%1, %0|%0, %1}"
20453   [(set_attr "type" "ssemov")
20454    (set_attr "mode" "SF")])
20455
20456 (define_insn "sse_movss"
20457   [(set (match_operand:V4SF 0 "register_operand" "=x")
20458         (vec_merge:V4SF
20459          (match_operand:V4SF 1 "register_operand" "0")
20460          (match_operand:V4SF 2 "register_operand" "x")
20461          (const_int 14)))]
20462   "TARGET_SSE"
20463   "movss\t{%2, %0|%0, %2}"
20464   [(set_attr "type" "ssemov")
20465    (set_attr "mode" "SF")])
20466
20467 (define_insn "sse_storess"
20468   [(set (match_operand:SF 0 "memory_operand" "=m")
20469         (vec_select:SF
20470          (match_operand:V4SF 1 "register_operand" "x")
20471          (parallel [(const_int 0)])))]
20472   "TARGET_SSE"
20473   "movss\t{%1, %0|%0, %1}"
20474   [(set_attr "type" "ssemov")
20475    (set_attr "mode" "SF")])
20476
20477 (define_insn "sse_shufps"
20478   [(set (match_operand:V4SF 0 "register_operand" "=x")
20479         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20480                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20481                       (match_operand:SI 3 "const_int_operand" "n")]
20482                      UNSPEC_SHUFFLE))]
20483   "TARGET_SSE"
20484   "shufps\t{%3, %2, %0|%0, %2, %3}"
20485   [(set_attr "type" "ssecvt")
20486    (set_attr "mode" "V4SF")])
20487
20488
20489 ;; SSE arithmetic
20490
20491 (define_insn "addv4sf3"
20492   [(set (match_operand:V4SF 0 "register_operand" "=x")
20493         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20494                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20495   "TARGET_SSE"
20496   "addps\t{%2, %0|%0, %2}"
20497   [(set_attr "type" "sseadd")
20498    (set_attr "mode" "V4SF")])
20499
20500 (define_insn "vmaddv4sf3"
20501   [(set (match_operand:V4SF 0 "register_operand" "=x")
20502         (vec_merge:V4SF
20503          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20504                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20505          (match_dup 1)
20506          (const_int 1)))]
20507   "TARGET_SSE"
20508   "addss\t{%2, %0|%0, %2}"
20509   [(set_attr "type" "sseadd")
20510    (set_attr "mode" "SF")])
20511
20512 (define_insn "subv4sf3"
20513   [(set (match_operand:V4SF 0 "register_operand" "=x")
20514         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20515                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20516   "TARGET_SSE"
20517   "subps\t{%2, %0|%0, %2}"
20518   [(set_attr "type" "sseadd")
20519    (set_attr "mode" "V4SF")])
20520
20521 (define_insn "vmsubv4sf3"
20522   [(set (match_operand:V4SF 0 "register_operand" "=x")
20523         (vec_merge:V4SF
20524          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20525                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20526          (match_dup 1)
20527          (const_int 1)))]
20528   "TARGET_SSE"
20529   "subss\t{%2, %0|%0, %2}"
20530   [(set_attr "type" "sseadd")
20531    (set_attr "mode" "SF")])
20532
20533 ;; ??? Should probably be done by generic code instead.
20534 (define_expand "negv4sf2"
20535   [(set (match_operand:V4SF 0 "register_operand" "")
20536         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20537                   (match_dup 2)))]
20538   "TARGET_SSE"
20539 {
20540   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20541   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20542   operands[2] = force_reg (V4SFmode, vm0);
20543 })
20544
20545 (define_insn "mulv4sf3"
20546   [(set (match_operand:V4SF 0 "register_operand" "=x")
20547         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20548                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20549   "TARGET_SSE"
20550   "mulps\t{%2, %0|%0, %2}"
20551   [(set_attr "type" "ssemul")
20552    (set_attr "mode" "V4SF")])
20553
20554 (define_insn "vmmulv4sf3"
20555   [(set (match_operand:V4SF 0 "register_operand" "=x")
20556         (vec_merge:V4SF
20557          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20558                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20559          (match_dup 1)
20560          (const_int 1)))]
20561   "TARGET_SSE"
20562   "mulss\t{%2, %0|%0, %2}"
20563   [(set_attr "type" "ssemul")
20564    (set_attr "mode" "SF")])
20565
20566 (define_insn "divv4sf3"
20567   [(set (match_operand:V4SF 0 "register_operand" "=x")
20568         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20569                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20570   "TARGET_SSE"
20571   "divps\t{%2, %0|%0, %2}"
20572   [(set_attr "type" "ssediv")
20573    (set_attr "mode" "V4SF")])
20574
20575 (define_insn "vmdivv4sf3"
20576   [(set (match_operand:V4SF 0 "register_operand" "=x")
20577         (vec_merge:V4SF
20578          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20579                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20580          (match_dup 1)
20581          (const_int 1)))]
20582   "TARGET_SSE"
20583   "divss\t{%2, %0|%0, %2}"
20584   [(set_attr "type" "ssediv")
20585    (set_attr "mode" "SF")])
20586
20587
20588 ;; SSE square root/reciprocal
20589
20590 (define_insn "rcpv4sf2"
20591   [(set (match_operand:V4SF 0 "register_operand" "=x")
20592         (unspec:V4SF
20593          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20594   "TARGET_SSE"
20595   "rcpps\t{%1, %0|%0, %1}"
20596   [(set_attr "type" "sse")
20597    (set_attr "mode" "V4SF")])
20598
20599 (define_insn "vmrcpv4sf2"
20600   [(set (match_operand:V4SF 0 "register_operand" "=x")
20601         (vec_merge:V4SF
20602          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20603                       UNSPEC_RCP)
20604          (match_operand:V4SF 2 "register_operand" "0")
20605          (const_int 1)))]
20606   "TARGET_SSE"
20607   "rcpss\t{%1, %0|%0, %1}"
20608   [(set_attr "type" "sse")
20609    (set_attr "mode" "SF")])
20610
20611 (define_insn "rsqrtv4sf2"
20612   [(set (match_operand:V4SF 0 "register_operand" "=x")
20613         (unspec:V4SF
20614          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20615   "TARGET_SSE"
20616   "rsqrtps\t{%1, %0|%0, %1}"
20617   [(set_attr "type" "sse")
20618    (set_attr "mode" "V4SF")])
20619
20620 (define_insn "vmrsqrtv4sf2"
20621   [(set (match_operand:V4SF 0 "register_operand" "=x")
20622         (vec_merge:V4SF
20623          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20624                       UNSPEC_RSQRT)
20625          (match_operand:V4SF 2 "register_operand" "0")
20626          (const_int 1)))]
20627   "TARGET_SSE"
20628   "rsqrtss\t{%1, %0|%0, %1}"
20629   [(set_attr "type" "sse")
20630    (set_attr "mode" "SF")])
20631
20632 (define_insn "sqrtv4sf2"
20633   [(set (match_operand:V4SF 0 "register_operand" "=x")
20634         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20635   "TARGET_SSE"
20636   "sqrtps\t{%1, %0|%0, %1}"
20637   [(set_attr "type" "sse")
20638    (set_attr "mode" "V4SF")])
20639
20640 (define_insn "vmsqrtv4sf2"
20641   [(set (match_operand:V4SF 0 "register_operand" "=x")
20642         (vec_merge:V4SF
20643          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20644          (match_operand:V4SF 2 "register_operand" "0")
20645          (const_int 1)))]
20646   "TARGET_SSE"
20647   "sqrtss\t{%1, %0|%0, %1}"
20648   [(set_attr "type" "sse")
20649    (set_attr "mode" "SF")])
20650
20651 ;; SSE logical operations.
20652
20653 ;; SSE defines logical operations on floating point values.  This brings
20654 ;; interesting challenge to RTL representation where logicals are only valid
20655 ;; on integral types.  We deal with this by representing the floating point
20656 ;; logical as logical on arguments casted to TImode as this is what hardware
20657 ;; really does.  Unfortunately hardware requires the type information to be
20658 ;; present and thus we must avoid subregs from being simplified and eliminated
20659 ;; in later compilation phases.
20660 ;;
20661 ;; We have following variants from each instruction:
20662 ;; sse_andsf3 - the operation taking V4SF vector operands
20663 ;;              and doing TImode cast on them
20664 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20665 ;;                      TImode, since backend insist on eliminating casts
20666 ;;                      on memory operands
20667 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20668 ;;                   We cannot accept memory operand here as instruction reads
20669 ;;                   whole scalar.  This is generated only post reload by GCC
20670 ;;                   scalar float operations that expands to logicals (fabs)
20671 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20672 ;;                   memory operand.  Eventually combine can be able
20673 ;;                   to synthesize these using splitter.
20674 ;; sse2_anddf3, *sse2_anddf3_memory
20675 ;;              
20676 ;; 
20677 ;; These are not called andti3 etc. because we really really don't want
20678 ;; the compiler to widen DImode ands to TImode ands and then try to move
20679 ;; into DImode subregs of SSE registers, and them together, and move out
20680 ;; of DImode subregs again!
20681 ;; SSE1 single precision floating point logical operation
20682 (define_expand "sse_andv4sf3"
20683   [(set (match_operand:V4SF 0 "register_operand" "")
20684         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20685                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20686   "TARGET_SSE"
20687   "")
20688
20689 (define_insn "*sse_andv4sf3"
20690   [(set (match_operand:V4SF 0 "register_operand" "=x")
20691         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20692                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20693   "TARGET_SSE
20694    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20695   "andps\t{%2, %0|%0, %2}"
20696   [(set_attr "type" "sselog")
20697    (set_attr "mode" "V4SF")])
20698
20699 (define_expand "sse_nandv4sf3"
20700   [(set (match_operand:V4SF 0 "register_operand" "")
20701         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20702                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20703   "TARGET_SSE"
20704   "")
20705
20706 (define_insn "*sse_nandv4sf3"
20707   [(set (match_operand:V4SF 0 "register_operand" "=x")
20708         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20709                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20710   "TARGET_SSE"
20711   "andnps\t{%2, %0|%0, %2}"
20712   [(set_attr "type" "sselog")
20713    (set_attr "mode" "V4SF")])
20714
20715 (define_expand "sse_iorv4sf3"
20716   [(set (match_operand:V4SF 0 "register_operand" "")
20717         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20718                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20719   "TARGET_SSE"
20720   "")
20721
20722 (define_insn "*sse_iorv4sf3"
20723   [(set (match_operand:V4SF 0 "register_operand" "=x")
20724         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20725                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20726   "TARGET_SSE
20727    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20728   "orps\t{%2, %0|%0, %2}"
20729   [(set_attr "type" "sselog")
20730    (set_attr "mode" "V4SF")])
20731
20732 (define_expand "sse_xorv4sf3"
20733   [(set (match_operand:V4SF 0 "register_operand" "")
20734         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20735                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20736   "TARGET_SSE"
20737   "")
20738
20739 (define_insn "*sse_xorv4sf3"
20740   [(set (match_operand:V4SF 0 "register_operand" "=x")
20741         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20742                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20743   "TARGET_SSE
20744    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20745   "xorps\t{%2, %0|%0, %2}"
20746   [(set_attr "type" "sselog")
20747    (set_attr "mode" "V4SF")])
20748
20749 ;; SSE2 double precision floating point logical operation
20750
20751 (define_expand "sse2_andv2df3"
20752   [(set (match_operand:V2DF 0 "register_operand" "")
20753         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20754                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20755   "TARGET_SSE2"
20756   "")
20757
20758 (define_insn "*sse2_andv2df3"
20759   [(set (match_operand:V2DF 0 "register_operand" "=x")
20760         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20761                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20762   "TARGET_SSE2
20763    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20764   "andpd\t{%2, %0|%0, %2}"
20765   [(set_attr "type" "sselog")
20766    (set_attr "mode" "V2DF")])
20767
20768 (define_expand "sse2_nandv2df3"
20769   [(set (match_operand:V2DF 0 "register_operand" "")
20770         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20771                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20772   "TARGET_SSE2"
20773   "")
20774
20775 (define_insn "*sse2_nandv2df3"
20776   [(set (match_operand:V2DF 0 "register_operand" "=x")
20777         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20778                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20779   "TARGET_SSE2"
20780   "andnpd\t{%2, %0|%0, %2}"
20781   [(set_attr "type" "sselog")
20782    (set_attr "mode" "V2DF")])
20783
20784 (define_expand "sse2_iorv2df3"
20785   [(set (match_operand:V2DF 0 "register_operand" "")
20786         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20787                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20788   "TARGET_SSE2"
20789   "")
20790
20791 (define_insn "*sse2_iorv2df3"
20792   [(set (match_operand:V2DF 0 "register_operand" "=x")
20793         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20794                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20795   "TARGET_SSE2
20796    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20797   "orpd\t{%2, %0|%0, %2}"
20798   [(set_attr "type" "sselog")
20799    (set_attr "mode" "V2DF")])
20800
20801 (define_expand "sse2_xorv2df3"
20802   [(set (match_operand:V2DF 0 "register_operand" "")
20803         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20804                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20805   "TARGET_SSE2"
20806   "")
20807
20808 (define_insn "*sse2_xorv2df3"
20809   [(set (match_operand:V2DF 0 "register_operand" "=x")
20810         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20811                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20812   "TARGET_SSE2
20813    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20814   "xorpd\t{%2, %0|%0, %2}"
20815   [(set_attr "type" "sselog")
20816    (set_attr "mode" "V2DF")])
20817
20818 ;; SSE2 integral logicals.  These patterns must always come after floating
20819 ;; point ones since we don't want compiler to use integer opcodes on floating
20820 ;; point SSE values to avoid matching of subregs in the match_operand.
20821 (define_insn "*sse2_andti3"
20822   [(set (match_operand:TI 0 "register_operand" "=x")
20823         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20824                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20825   "TARGET_SSE2
20826    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20827   "pand\t{%2, %0|%0, %2}"
20828   [(set_attr "type" "sselog")
20829    (set_attr "mode" "TI")])
20830
20831 (define_insn "sse2_andv2di3"
20832   [(set (match_operand:V2DI 0 "register_operand" "=x")
20833         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20834                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20835   "TARGET_SSE2
20836    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20837   "pand\t{%2, %0|%0, %2}"
20838   [(set_attr "type" "sselog")
20839    (set_attr "mode" "TI")])
20840
20841 (define_insn "*sse2_nandti3"
20842   [(set (match_operand:TI 0 "register_operand" "=x")
20843         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20844                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20845   "TARGET_SSE2"
20846   "pandn\t{%2, %0|%0, %2}"
20847   [(set_attr "type" "sselog")
20848    (set_attr "mode" "TI")])
20849
20850 (define_insn "sse2_nandv2di3"
20851   [(set (match_operand:V2DI 0 "register_operand" "=x")
20852         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20853                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20854   "TARGET_SSE2
20855    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20856   "pandn\t{%2, %0|%0, %2}"
20857   [(set_attr "type" "sselog")
20858    (set_attr "mode" "TI")])
20859
20860 (define_insn "*sse2_iorti3"
20861   [(set (match_operand:TI 0 "register_operand" "=x")
20862         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20863                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20864   "TARGET_SSE2
20865    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20866   "por\t{%2, %0|%0, %2}"
20867   [(set_attr "type" "sselog")
20868    (set_attr "mode" "TI")])
20869
20870 (define_insn "sse2_iorv2di3"
20871   [(set (match_operand:V2DI 0 "register_operand" "=x")
20872         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20873                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20874   "TARGET_SSE2
20875    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20876   "por\t{%2, %0|%0, %2}"
20877   [(set_attr "type" "sselog")
20878    (set_attr "mode" "TI")])
20879
20880 (define_insn "*sse2_xorti3"
20881   [(set (match_operand:TI 0 "register_operand" "=x")
20882         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20883                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20884   "TARGET_SSE2
20885    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20886   "pxor\t{%2, %0|%0, %2}"
20887   [(set_attr "type" "sselog")
20888    (set_attr "mode" "TI")])
20889
20890 (define_insn "sse2_xorv2di3"
20891   [(set (match_operand:V2DI 0 "register_operand" "=x")
20892         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20893                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20894   "TARGET_SSE2
20895    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20896   "pxor\t{%2, %0|%0, %2}"
20897   [(set_attr "type" "sselog")
20898    (set_attr "mode" "TI")])
20899
20900 ;; Use xor, but don't show input operands so they aren't live before
20901 ;; this insn.
20902 (define_insn "sse_clrv4sf"
20903   [(set (match_operand:V4SF 0 "register_operand" "=x")
20904         (match_operand:V4SF 1 "const0_operand" "X"))]
20905   "TARGET_SSE"
20906 {
20907   if (get_attr_mode (insn) == MODE_TI)
20908     return "pxor\t{%0, %0|%0, %0}";
20909   else
20910     return "xorps\t{%0, %0|%0, %0}";
20911 }
20912   [(set_attr "type" "sselog")
20913    (set_attr "memory" "none")
20914    (set (attr "mode")
20915         (if_then_else
20916            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20917                          (const_int 0))
20918                      (ne (symbol_ref "TARGET_SSE2")
20919                          (const_int 0)))
20920                 (eq (symbol_ref "optimize_size")
20921                     (const_int 0)))
20922          (const_string "TI")
20923          (const_string "V4SF")))])
20924
20925 ;; Use xor, but don't show input operands so they aren't live before
20926 ;; this insn.
20927 (define_insn "sse_clrv2df"
20928   [(set (match_operand:V2DF 0 "register_operand" "=x")
20929         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20930   "TARGET_SSE2"
20931   "xorpd\t{%0, %0|%0, %0}"
20932   [(set_attr "type" "sselog")
20933    (set_attr "memory" "none")
20934    (set_attr "mode" "V4SF")])
20935
20936 ;; SSE mask-generating compares
20937
20938 (define_insn "maskcmpv4sf3"
20939   [(set (match_operand:V4SI 0 "register_operand" "=x")
20940         (match_operator:V4SI 3 "sse_comparison_operator"
20941                 [(match_operand:V4SF 1 "register_operand" "0")
20942                  (match_operand:V4SF 2 "register_operand" "x")]))]
20943   "TARGET_SSE"
20944   "cmp%D3ps\t{%2, %0|%0, %2}"
20945   [(set_attr "type" "ssecmp")
20946    (set_attr "mode" "V4SF")])
20947
20948 (define_insn "maskncmpv4sf3"
20949   [(set (match_operand:V4SI 0 "register_operand" "=x")
20950         (not:V4SI
20951          (match_operator:V4SI 3 "sse_comparison_operator"
20952                 [(match_operand:V4SF 1 "register_operand" "0")
20953                  (match_operand:V4SF 2 "register_operand" "x")])))]
20954   "TARGET_SSE"
20955 {
20956   if (GET_CODE (operands[3]) == UNORDERED)
20957     return "cmpordps\t{%2, %0|%0, %2}";
20958   else
20959     return "cmpn%D3ps\t{%2, %0|%0, %2}";
20960 }
20961   [(set_attr "type" "ssecmp")
20962    (set_attr "mode" "V4SF")])
20963
20964 (define_insn "vmmaskcmpv4sf3"
20965   [(set (match_operand:V4SI 0 "register_operand" "=x")
20966         (vec_merge:V4SI
20967          (match_operator:V4SI 3 "sse_comparison_operator"
20968                 [(match_operand:V4SF 1 "register_operand" "0")
20969                  (match_operand:V4SF 2 "register_operand" "x")])
20970          (subreg:V4SI (match_dup 1) 0)
20971          (const_int 1)))]
20972   "TARGET_SSE"
20973   "cmp%D3ss\t{%2, %0|%0, %2}"
20974   [(set_attr "type" "ssecmp")
20975    (set_attr "mode" "SF")])
20976
20977 (define_insn "vmmaskncmpv4sf3"
20978   [(set (match_operand:V4SI 0 "register_operand" "=x")
20979         (vec_merge:V4SI
20980          (not:V4SI
20981           (match_operator:V4SI 3 "sse_comparison_operator"
20982                 [(match_operand:V4SF 1 "register_operand" "0")
20983                  (match_operand:V4SF 2 "register_operand" "x")]))
20984          (subreg:V4SI (match_dup 1) 0)
20985          (const_int 1)))]
20986   "TARGET_SSE"
20987 {
20988   if (GET_CODE (operands[3]) == UNORDERED)
20989     return "cmpordss\t{%2, %0|%0, %2}";
20990   else
20991     return "cmpn%D3ss\t{%2, %0|%0, %2}";
20992 }
20993   [(set_attr "type" "ssecmp")
20994    (set_attr "mode" "SF")])
20995
20996 (define_insn "sse_comi"
20997   [(set (reg:CCFP FLAGS_REG)
20998         (compare:CCFP (vec_select:SF
20999                        (match_operand:V4SF 0 "register_operand" "x")
21000                        (parallel [(const_int 0)]))
21001                       (vec_select:SF
21002                        (match_operand:V4SF 1 "register_operand" "x")
21003                        (parallel [(const_int 0)]))))]
21004   "TARGET_SSE"
21005   "comiss\t{%1, %0|%0, %1}"
21006   [(set_attr "type" "ssecomi")
21007    (set_attr "mode" "SF")])
21008
21009 (define_insn "sse_ucomi"
21010   [(set (reg:CCFPU FLAGS_REG)
21011         (compare:CCFPU (vec_select:SF
21012                         (match_operand:V4SF 0 "register_operand" "x")
21013                         (parallel [(const_int 0)]))
21014                        (vec_select:SF
21015                         (match_operand:V4SF 1 "register_operand" "x")
21016                         (parallel [(const_int 0)]))))]
21017   "TARGET_SSE"
21018   "ucomiss\t{%1, %0|%0, %1}"
21019   [(set_attr "type" "ssecomi")
21020    (set_attr "mode" "SF")])
21021
21022
21023 ;; SSE unpack
21024
21025 (define_insn "sse_unpckhps"
21026   [(set (match_operand:V4SF 0 "register_operand" "=x")
21027         (vec_merge:V4SF
21028          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21029                           (parallel [(const_int 2)
21030                                      (const_int 0)
21031                                      (const_int 3)
21032                                      (const_int 1)]))
21033          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21034                           (parallel [(const_int 0)
21035                                      (const_int 2)
21036                                      (const_int 1)
21037                                      (const_int 3)]))
21038          (const_int 5)))]
21039   "TARGET_SSE"
21040   "unpckhps\t{%2, %0|%0, %2}"
21041   [(set_attr "type" "ssecvt")
21042    (set_attr "mode" "V4SF")])
21043
21044 (define_insn "sse_unpcklps"
21045   [(set (match_operand:V4SF 0 "register_operand" "=x")
21046         (vec_merge:V4SF
21047          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21048                           (parallel [(const_int 0)
21049                                      (const_int 2)
21050                                      (const_int 1)
21051                                      (const_int 3)]))
21052          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21053                           (parallel [(const_int 2)
21054                                      (const_int 0)
21055                                      (const_int 3)
21056                                      (const_int 1)]))
21057          (const_int 5)))]
21058   "TARGET_SSE"
21059   "unpcklps\t{%2, %0|%0, %2}"
21060   [(set_attr "type" "ssecvt")
21061    (set_attr "mode" "V4SF")])
21062
21063
21064 ;; SSE min/max
21065
21066 (define_insn "smaxv4sf3"
21067   [(set (match_operand:V4SF 0 "register_operand" "=x")
21068         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21069                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21070   "TARGET_SSE"
21071   "maxps\t{%2, %0|%0, %2}"
21072   [(set_attr "type" "sse")
21073    (set_attr "mode" "V4SF")])
21074
21075 (define_insn "vmsmaxv4sf3"
21076   [(set (match_operand:V4SF 0 "register_operand" "=x")
21077         (vec_merge:V4SF
21078          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21079                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21080          (match_dup 1)
21081          (const_int 1)))]
21082   "TARGET_SSE"
21083   "maxss\t{%2, %0|%0, %2}"
21084   [(set_attr "type" "sse")
21085    (set_attr "mode" "SF")])
21086
21087 (define_insn "sminv4sf3"
21088   [(set (match_operand:V4SF 0 "register_operand" "=x")
21089         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21090                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21091   "TARGET_SSE"
21092   "minps\t{%2, %0|%0, %2}"
21093   [(set_attr "type" "sse")
21094    (set_attr "mode" "V4SF")])
21095
21096 (define_insn "vmsminv4sf3"
21097   [(set (match_operand:V4SF 0 "register_operand" "=x")
21098         (vec_merge:V4SF
21099          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21100                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21101          (match_dup 1)
21102          (const_int 1)))]
21103   "TARGET_SSE"
21104   "minss\t{%2, %0|%0, %2}"
21105   [(set_attr "type" "sse")
21106    (set_attr "mode" "SF")])
21107
21108 ;; SSE <-> integer/MMX conversions
21109
21110 (define_insn "cvtpi2ps"
21111   [(set (match_operand:V4SF 0 "register_operand" "=x")
21112         (vec_merge:V4SF
21113          (match_operand:V4SF 1 "register_operand" "0")
21114          (vec_duplicate:V4SF
21115           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21116          (const_int 12)))]
21117   "TARGET_SSE"
21118   "cvtpi2ps\t{%2, %0|%0, %2}"
21119   [(set_attr "type" "ssecvt")
21120    (set_attr "mode" "V4SF")])
21121
21122 (define_insn "cvtps2pi"
21123   [(set (match_operand:V2SI 0 "register_operand" "=y")
21124         (vec_select:V2SI
21125          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21126          (parallel [(const_int 0) (const_int 1)])))]
21127   "TARGET_SSE"
21128   "cvtps2pi\t{%1, %0|%0, %1}"
21129   [(set_attr "type" "ssecvt")
21130    (set_attr "mode" "V4SF")])
21131
21132 (define_insn "cvttps2pi"
21133   [(set (match_operand:V2SI 0 "register_operand" "=y")
21134         (vec_select:V2SI
21135          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21136                       UNSPEC_FIX)
21137          (parallel [(const_int 0) (const_int 1)])))]
21138   "TARGET_SSE"
21139   "cvttps2pi\t{%1, %0|%0, %1}"
21140   [(set_attr "type" "ssecvt")
21141    (set_attr "mode" "SF")])
21142
21143 (define_insn "cvtsi2ss"
21144   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21145         (vec_merge:V4SF
21146          (match_operand:V4SF 1 "register_operand" "0,0")
21147          (vec_duplicate:V4SF
21148           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21149          (const_int 14)))]
21150   "TARGET_SSE"
21151   "cvtsi2ss\t{%2, %0|%0, %2}"
21152   [(set_attr "type" "sseicvt")
21153    (set_attr "athlon_decode" "vector,double")
21154    (set_attr "mode" "SF")])
21155
21156 (define_insn "cvtsi2ssq"
21157   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21158         (vec_merge:V4SF
21159          (match_operand:V4SF 1 "register_operand" "0,0")
21160          (vec_duplicate:V4SF
21161           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21162          (const_int 14)))]
21163   "TARGET_SSE && TARGET_64BIT"
21164   "cvtsi2ssq\t{%2, %0|%0, %2}"
21165   [(set_attr "type" "sseicvt")
21166    (set_attr "athlon_decode" "vector,double")
21167    (set_attr "mode" "SF")])
21168
21169 (define_insn "cvtss2si"
21170   [(set (match_operand:SI 0 "register_operand" "=r,r")
21171         (vec_select:SI
21172          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21173          (parallel [(const_int 0)])))]
21174   "TARGET_SSE"
21175   "cvtss2si\t{%1, %0|%0, %1}"
21176   [(set_attr "type" "sseicvt")
21177    (set_attr "athlon_decode" "double,vector")
21178    (set_attr "mode" "SI")])
21179
21180 (define_insn "cvtss2siq"
21181   [(set (match_operand:DI 0 "register_operand" "=r,r")
21182         (vec_select:DI
21183          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21184          (parallel [(const_int 0)])))]
21185   "TARGET_SSE"
21186   "cvtss2siq\t{%1, %0|%0, %1}"
21187   [(set_attr "type" "sseicvt")
21188    (set_attr "athlon_decode" "double,vector")
21189    (set_attr "mode" "DI")])
21190
21191 (define_insn "cvttss2si"
21192   [(set (match_operand:SI 0 "register_operand" "=r,r")
21193         (vec_select:SI
21194          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21195                       UNSPEC_FIX)
21196          (parallel [(const_int 0)])))]
21197   "TARGET_SSE"
21198   "cvttss2si\t{%1, %0|%0, %1}"
21199   [(set_attr "type" "sseicvt")
21200    (set_attr "mode" "SF")
21201    (set_attr "athlon_decode" "double,vector")])
21202
21203 (define_insn "cvttss2siq"
21204   [(set (match_operand:DI 0 "register_operand" "=r,r")
21205         (vec_select:DI
21206          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21207                       UNSPEC_FIX)
21208          (parallel [(const_int 0)])))]
21209   "TARGET_SSE && TARGET_64BIT"
21210   "cvttss2siq\t{%1, %0|%0, %1}"
21211   [(set_attr "type" "sseicvt")
21212    (set_attr "mode" "SF")
21213    (set_attr "athlon_decode" "double,vector")])
21214
21215
21216 ;; MMX insns
21217
21218 ;; MMX arithmetic
21219
21220 (define_insn "addv8qi3"
21221   [(set (match_operand:V8QI 0 "register_operand" "=y")
21222         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21223                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21224   "TARGET_MMX"
21225   "paddb\t{%2, %0|%0, %2}"
21226   [(set_attr "type" "mmxadd")
21227    (set_attr "mode" "DI")])
21228
21229 (define_insn "addv4hi3"
21230   [(set (match_operand:V4HI 0 "register_operand" "=y")
21231         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21232                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21233   "TARGET_MMX"
21234   "paddw\t{%2, %0|%0, %2}"
21235   [(set_attr "type" "mmxadd")
21236    (set_attr "mode" "DI")])
21237
21238 (define_insn "addv2si3"
21239   [(set (match_operand:V2SI 0 "register_operand" "=y")
21240         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21241                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21242   "TARGET_MMX"
21243   "paddd\t{%2, %0|%0, %2}"
21244   [(set_attr "type" "mmxadd")
21245    (set_attr "mode" "DI")])
21246
21247 (define_insn "mmx_adddi3"
21248   [(set (match_operand:DI 0 "register_operand" "=y")
21249         (unspec:DI
21250          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21251                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21252          UNSPEC_NOP))]
21253   "TARGET_MMX"
21254   "paddq\t{%2, %0|%0, %2}"
21255   [(set_attr "type" "mmxadd")
21256    (set_attr "mode" "DI")])
21257
21258 (define_insn "ssaddv8qi3"
21259   [(set (match_operand:V8QI 0 "register_operand" "=y")
21260         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21261                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21262   "TARGET_MMX"
21263   "paddsb\t{%2, %0|%0, %2}"
21264   [(set_attr "type" "mmxadd")
21265    (set_attr "mode" "DI")])
21266
21267 (define_insn "ssaddv4hi3"
21268   [(set (match_operand:V4HI 0 "register_operand" "=y")
21269         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21270                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21271   "TARGET_MMX"
21272   "paddsw\t{%2, %0|%0, %2}"
21273   [(set_attr "type" "mmxadd")
21274    (set_attr "mode" "DI")])
21275
21276 (define_insn "usaddv8qi3"
21277   [(set (match_operand:V8QI 0 "register_operand" "=y")
21278         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21279                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21280   "TARGET_MMX"
21281   "paddusb\t{%2, %0|%0, %2}"
21282   [(set_attr "type" "mmxadd")
21283    (set_attr "mode" "DI")])
21284
21285 (define_insn "usaddv4hi3"
21286   [(set (match_operand:V4HI 0 "register_operand" "=y")
21287         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21288                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21289   "TARGET_MMX"
21290   "paddusw\t{%2, %0|%0, %2}"
21291   [(set_attr "type" "mmxadd")
21292    (set_attr "mode" "DI")])
21293
21294 (define_insn "subv8qi3"
21295   [(set (match_operand:V8QI 0 "register_operand" "=y")
21296         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21297                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21298   "TARGET_MMX"
21299   "psubb\t{%2, %0|%0, %2}"
21300   [(set_attr "type" "mmxadd")
21301    (set_attr "mode" "DI")])
21302
21303 (define_insn "subv4hi3"
21304   [(set (match_operand:V4HI 0 "register_operand" "=y")
21305         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21306                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21307   "TARGET_MMX"
21308   "psubw\t{%2, %0|%0, %2}"
21309   [(set_attr "type" "mmxadd")
21310    (set_attr "mode" "DI")])
21311
21312 (define_insn "subv2si3"
21313   [(set (match_operand:V2SI 0 "register_operand" "=y")
21314         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21315                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21316   "TARGET_MMX"
21317   "psubd\t{%2, %0|%0, %2}"
21318   [(set_attr "type" "mmxadd")
21319    (set_attr "mode" "DI")])
21320
21321 (define_insn "mmx_subdi3"
21322   [(set (match_operand:DI 0 "register_operand" "=y")
21323         (unspec:DI
21324          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21325                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21326          UNSPEC_NOP))]
21327   "TARGET_MMX"
21328   "psubq\t{%2, %0|%0, %2}"
21329   [(set_attr "type" "mmxadd")
21330    (set_attr "mode" "DI")])
21331
21332 (define_insn "sssubv8qi3"
21333   [(set (match_operand:V8QI 0 "register_operand" "=y")
21334         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21335                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21336   "TARGET_MMX"
21337   "psubsb\t{%2, %0|%0, %2}"
21338   [(set_attr "type" "mmxadd")
21339    (set_attr "mode" "DI")])
21340
21341 (define_insn "sssubv4hi3"
21342   [(set (match_operand:V4HI 0 "register_operand" "=y")
21343         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21344                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21345   "TARGET_MMX"
21346   "psubsw\t{%2, %0|%0, %2}"
21347   [(set_attr "type" "mmxadd")
21348    (set_attr "mode" "DI")])
21349
21350 (define_insn "ussubv8qi3"
21351   [(set (match_operand:V8QI 0 "register_operand" "=y")
21352         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21353                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21354   "TARGET_MMX"
21355   "psubusb\t{%2, %0|%0, %2}"
21356   [(set_attr "type" "mmxadd")
21357    (set_attr "mode" "DI")])
21358
21359 (define_insn "ussubv4hi3"
21360   [(set (match_operand:V4HI 0 "register_operand" "=y")
21361         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21362                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21363   "TARGET_MMX"
21364   "psubusw\t{%2, %0|%0, %2}"
21365   [(set_attr "type" "mmxadd")
21366    (set_attr "mode" "DI")])
21367
21368 (define_insn "mulv4hi3"
21369   [(set (match_operand:V4HI 0 "register_operand" "=y")
21370         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21371                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21372   "TARGET_MMX"
21373   "pmullw\t{%2, %0|%0, %2}"
21374   [(set_attr "type" "mmxmul")
21375    (set_attr "mode" "DI")])
21376
21377 (define_insn "smulv4hi3_highpart"
21378   [(set (match_operand:V4HI 0 "register_operand" "=y")
21379         (truncate:V4HI
21380          (lshiftrt:V4SI
21381           (mult:V4SI (sign_extend:V4SI
21382                       (match_operand:V4HI 1 "register_operand" "0"))
21383                      (sign_extend:V4SI
21384                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21385           (const_int 16))))]
21386   "TARGET_MMX"
21387   "pmulhw\t{%2, %0|%0, %2}"
21388   [(set_attr "type" "mmxmul")
21389    (set_attr "mode" "DI")])
21390
21391 (define_insn "umulv4hi3_highpart"
21392   [(set (match_operand:V4HI 0 "register_operand" "=y")
21393         (truncate:V4HI
21394          (lshiftrt:V4SI
21395           (mult:V4SI (zero_extend:V4SI
21396                       (match_operand:V4HI 1 "register_operand" "0"))
21397                      (zero_extend:V4SI
21398                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21399           (const_int 16))))]
21400   "TARGET_SSE || TARGET_3DNOW_A"
21401   "pmulhuw\t{%2, %0|%0, %2}"
21402   [(set_attr "type" "mmxmul")
21403    (set_attr "mode" "DI")])
21404
21405 (define_insn "mmx_pmaddwd"
21406   [(set (match_operand:V2SI 0 "register_operand" "=y")
21407         (plus:V2SI
21408          (mult:V2SI
21409           (sign_extend:V2SI
21410            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21411                             (parallel [(const_int 0) (const_int 2)])))
21412           (sign_extend:V2SI
21413            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21414                             (parallel [(const_int 0) (const_int 2)]))))
21415          (mult:V2SI
21416           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21417                                              (parallel [(const_int 1)
21418                                                         (const_int 3)])))
21419           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21420                                              (parallel [(const_int 1)
21421                                                         (const_int 3)]))))))]
21422   "TARGET_MMX"
21423   "pmaddwd\t{%2, %0|%0, %2}"
21424   [(set_attr "type" "mmxmul")
21425    (set_attr "mode" "DI")])
21426
21427
21428 ;; MMX logical operations
21429 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21430 ;; normal code that also wants to use the FPU from getting broken.
21431 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21432 (define_insn "mmx_iordi3"
21433   [(set (match_operand:DI 0 "register_operand" "=y")
21434         (unspec:DI
21435          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21436                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21437          UNSPEC_NOP))]
21438   "TARGET_MMX"
21439   "por\t{%2, %0|%0, %2}"
21440   [(set_attr "type" "mmxadd")
21441    (set_attr "mode" "DI")])
21442
21443 (define_insn "mmx_xordi3"
21444   [(set (match_operand:DI 0 "register_operand" "=y")
21445         (unspec:DI
21446          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21447                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21448          UNSPEC_NOP))]
21449   "TARGET_MMX"
21450   "pxor\t{%2, %0|%0, %2}"
21451   [(set_attr "type" "mmxadd")
21452    (set_attr "mode" "DI")
21453    (set_attr "memory" "none")])
21454
21455 ;; Same as pxor, but don't show input operands so that we don't think
21456 ;; they are live.
21457 (define_insn "mmx_clrdi"
21458   [(set (match_operand:DI 0 "register_operand" "=y")
21459         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21460   "TARGET_MMX"
21461   "pxor\t{%0, %0|%0, %0}"
21462   [(set_attr "type" "mmxadd")
21463    (set_attr "mode" "DI")
21464    (set_attr "memory" "none")])
21465
21466 (define_insn "mmx_anddi3"
21467   [(set (match_operand:DI 0 "register_operand" "=y")
21468         (unspec:DI
21469          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21470                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21471          UNSPEC_NOP))]
21472   "TARGET_MMX"
21473   "pand\t{%2, %0|%0, %2}"
21474   [(set_attr "type" "mmxadd")
21475    (set_attr "mode" "DI")])
21476
21477 (define_insn "mmx_nanddi3"
21478   [(set (match_operand:DI 0 "register_operand" "=y")
21479         (unspec:DI
21480          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21481                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21482          UNSPEC_NOP))]
21483   "TARGET_MMX"
21484   "pandn\t{%2, %0|%0, %2}"
21485   [(set_attr "type" "mmxadd")
21486    (set_attr "mode" "DI")])
21487
21488
21489 ;; MMX unsigned averages/sum of absolute differences
21490
21491 (define_insn "mmx_uavgv8qi3"
21492   [(set (match_operand:V8QI 0 "register_operand" "=y")
21493         (ashiftrt:V8QI
21494          (plus:V8QI (plus:V8QI
21495                      (match_operand:V8QI 1 "register_operand" "0")
21496                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21497                     (const_vector:V8QI [(const_int 1)
21498                                         (const_int 1)
21499                                         (const_int 1)
21500                                         (const_int 1)
21501                                         (const_int 1)
21502                                         (const_int 1)
21503                                         (const_int 1)
21504                                         (const_int 1)]))
21505          (const_int 1)))]
21506   "TARGET_SSE || TARGET_3DNOW_A"
21507   "pavgb\t{%2, %0|%0, %2}"
21508   [(set_attr "type" "mmxshft")
21509    (set_attr "mode" "DI")])
21510
21511 (define_insn "mmx_uavgv4hi3"
21512   [(set (match_operand:V4HI 0 "register_operand" "=y")
21513         (ashiftrt:V4HI
21514          (plus:V4HI (plus:V4HI
21515                      (match_operand:V4HI 1 "register_operand" "0")
21516                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21517                     (const_vector:V4HI [(const_int 1)
21518                                         (const_int 1)
21519                                         (const_int 1)
21520                                         (const_int 1)]))
21521          (const_int 1)))]
21522   "TARGET_SSE || TARGET_3DNOW_A"
21523   "pavgw\t{%2, %0|%0, %2}"
21524   [(set_attr "type" "mmxshft")
21525    (set_attr "mode" "DI")])
21526
21527 (define_insn "mmx_psadbw"
21528   [(set (match_operand:DI 0 "register_operand" "=y")
21529         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21530                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21531                    UNSPEC_PSADBW))]
21532   "TARGET_SSE || TARGET_3DNOW_A"
21533   "psadbw\t{%2, %0|%0, %2}"
21534   [(set_attr "type" "mmxshft")
21535    (set_attr "mode" "DI")])
21536
21537
21538 ;; MMX insert/extract/shuffle
21539
21540 (define_expand "mmx_pinsrw"
21541   [(set (match_operand:V4HI 0 "register_operand" "")
21542         (vec_merge:V4HI
21543           (match_operand:V4HI 1 "register_operand" "")
21544           (vec_duplicate:V4HI
21545             (match_operand:SI 2 "nonimmediate_operand" ""))
21546           (match_operand:SI 3 "const_0_to_3_operand" "")))]
21547   "TARGET_SSE || TARGET_3DNOW_A"
21548 {
21549   operands[2] = gen_lowpart (HImode, operands[2]);
21550   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
21551 })
21552
21553 (define_insn "*mmx_pinsrw"
21554   [(set (match_operand:V4HI 0 "register_operand" "=y")
21555         (vec_merge:V4HI
21556           (match_operand:V4HI 1 "register_operand" "0")
21557           (vec_duplicate:V4HI
21558             (match_operand:HI 2 "nonimmediate_operand" "rm"))
21559           (match_operand:SI 3 "const_pow2_1_to_8_operand" "N")))]
21560   "TARGET_SSE || TARGET_3DNOW_A"
21561 {
21562   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
21563   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
21564 }
21565   [(set_attr "type" "mmxcvt")
21566    (set_attr "mode" "DI")])
21567
21568 (define_insn "mmx_pextrw"
21569   [(set (match_operand:SI 0 "register_operand" "=r")
21570         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21571                                        (parallel
21572                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21573   "TARGET_SSE || TARGET_3DNOW_A"
21574   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21575   [(set_attr "type" "mmxcvt")
21576    (set_attr "mode" "DI")])
21577
21578 (define_insn "mmx_pshufw"
21579   [(set (match_operand:V4HI 0 "register_operand" "=y")
21580         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21581                       (match_operand:SI 2 "immediate_operand" "i")]
21582                      UNSPEC_SHUFFLE))]
21583   "TARGET_SSE || TARGET_3DNOW_A"
21584   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21585   [(set_attr "type" "mmxcvt")
21586    (set_attr "mode" "DI")])
21587
21588
21589 ;; MMX mask-generating comparisons
21590
21591 (define_insn "eqv8qi3"
21592   [(set (match_operand:V8QI 0 "register_operand" "=y")
21593         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21594                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21595   "TARGET_MMX"
21596   "pcmpeqb\t{%2, %0|%0, %2}"
21597   [(set_attr "type" "mmxcmp")
21598    (set_attr "mode" "DI")])
21599
21600 (define_insn "eqv4hi3"
21601   [(set (match_operand:V4HI 0 "register_operand" "=y")
21602         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21603                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21604   "TARGET_MMX"
21605   "pcmpeqw\t{%2, %0|%0, %2}"
21606   [(set_attr "type" "mmxcmp")
21607    (set_attr "mode" "DI")])
21608
21609 (define_insn "eqv2si3"
21610   [(set (match_operand:V2SI 0 "register_operand" "=y")
21611         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21612                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21613   "TARGET_MMX"
21614   "pcmpeqd\t{%2, %0|%0, %2}"
21615   [(set_attr "type" "mmxcmp")
21616    (set_attr "mode" "DI")])
21617
21618 (define_insn "gtv8qi3"
21619   [(set (match_operand:V8QI 0 "register_operand" "=y")
21620         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21621                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21622   "TARGET_MMX"
21623   "pcmpgtb\t{%2, %0|%0, %2}"
21624   [(set_attr "type" "mmxcmp")
21625    (set_attr "mode" "DI")])
21626
21627 (define_insn "gtv4hi3"
21628   [(set (match_operand:V4HI 0 "register_operand" "=y")
21629         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21630                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21631   "TARGET_MMX"
21632   "pcmpgtw\t{%2, %0|%0, %2}"
21633   [(set_attr "type" "mmxcmp")
21634    (set_attr "mode" "DI")])
21635
21636 (define_insn "gtv2si3"
21637   [(set (match_operand:V2SI 0 "register_operand" "=y")
21638         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21639                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21640   "TARGET_MMX"
21641   "pcmpgtd\t{%2, %0|%0, %2}"
21642   [(set_attr "type" "mmxcmp")
21643    (set_attr "mode" "DI")])
21644
21645
21646 ;; MMX max/min insns
21647
21648 (define_insn "umaxv8qi3"
21649   [(set (match_operand:V8QI 0 "register_operand" "=y")
21650         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21651                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21652   "TARGET_SSE || TARGET_3DNOW_A"
21653   "pmaxub\t{%2, %0|%0, %2}"
21654   [(set_attr "type" "mmxadd")
21655    (set_attr "mode" "DI")])
21656
21657 (define_insn "smaxv4hi3"
21658   [(set (match_operand:V4HI 0 "register_operand" "=y")
21659         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21660                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21661   "TARGET_SSE || TARGET_3DNOW_A"
21662   "pmaxsw\t{%2, %0|%0, %2}"
21663   [(set_attr "type" "mmxadd")
21664    (set_attr "mode" "DI")])
21665
21666 (define_insn "uminv8qi3"
21667   [(set (match_operand:V8QI 0 "register_operand" "=y")
21668         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21669                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21670   "TARGET_SSE || TARGET_3DNOW_A"
21671   "pminub\t{%2, %0|%0, %2}"
21672   [(set_attr "type" "mmxadd")
21673    (set_attr "mode" "DI")])
21674
21675 (define_insn "sminv4hi3"
21676   [(set (match_operand:V4HI 0 "register_operand" "=y")
21677         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21678                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21679   "TARGET_SSE || TARGET_3DNOW_A"
21680   "pminsw\t{%2, %0|%0, %2}"
21681   [(set_attr "type" "mmxadd")
21682    (set_attr "mode" "DI")])
21683
21684
21685 ;; MMX shifts
21686
21687 (define_insn "ashrv4hi3"
21688   [(set (match_operand:V4HI 0 "register_operand" "=y")
21689         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21690                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21691   "TARGET_MMX"
21692   "psraw\t{%2, %0|%0, %2}"
21693   [(set_attr "type" "mmxshft")
21694    (set_attr "mode" "DI")])
21695
21696 (define_insn "ashrv2si3"
21697   [(set (match_operand:V2SI 0 "register_operand" "=y")
21698         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21699                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21700   "TARGET_MMX"
21701   "psrad\t{%2, %0|%0, %2}"
21702   [(set_attr "type" "mmxshft")
21703    (set_attr "mode" "DI")])
21704
21705 (define_insn "lshrv4hi3"
21706   [(set (match_operand:V4HI 0 "register_operand" "=y")
21707         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21708                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21709   "TARGET_MMX"
21710   "psrlw\t{%2, %0|%0, %2}"
21711   [(set_attr "type" "mmxshft")
21712    (set_attr "mode" "DI")])
21713
21714 (define_insn "lshrv2si3"
21715   [(set (match_operand:V2SI 0 "register_operand" "=y")
21716         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21717                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21718   "TARGET_MMX"
21719   "psrld\t{%2, %0|%0, %2}"
21720   [(set_attr "type" "mmxshft")
21721    (set_attr "mode" "DI")])
21722
21723 ;; See logical MMX insns.
21724 (define_insn "mmx_lshrdi3"
21725   [(set (match_operand:DI 0 "register_operand" "=y")
21726         (unspec:DI
21727           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21728                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21729           UNSPEC_NOP))]
21730   "TARGET_MMX"
21731   "psrlq\t{%2, %0|%0, %2}"
21732   [(set_attr "type" "mmxshft")
21733    (set_attr "mode" "DI")])
21734
21735 (define_insn "ashlv4hi3"
21736   [(set (match_operand:V4HI 0 "register_operand" "=y")
21737         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21738                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21739   "TARGET_MMX"
21740   "psllw\t{%2, %0|%0, %2}"
21741   [(set_attr "type" "mmxshft")
21742    (set_attr "mode" "DI")])
21743
21744 (define_insn "ashlv2si3"
21745   [(set (match_operand:V2SI 0 "register_operand" "=y")
21746         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21747                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21748   "TARGET_MMX"
21749   "pslld\t{%2, %0|%0, %2}"
21750   [(set_attr "type" "mmxshft")
21751    (set_attr "mode" "DI")])
21752
21753 ;; See logical MMX insns.
21754 (define_insn "mmx_ashldi3"
21755   [(set (match_operand:DI 0 "register_operand" "=y")
21756         (unspec:DI
21757          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21758                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21759          UNSPEC_NOP))]
21760   "TARGET_MMX"
21761   "psllq\t{%2, %0|%0, %2}"
21762   [(set_attr "type" "mmxshft")
21763    (set_attr "mode" "DI")])
21764
21765
21766 ;; MMX pack/unpack insns.
21767
21768 (define_insn "mmx_packsswb"
21769   [(set (match_operand:V8QI 0 "register_operand" "=y")
21770         (vec_concat:V8QI
21771          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21772          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21773   "TARGET_MMX"
21774   "packsswb\t{%2, %0|%0, %2}"
21775   [(set_attr "type" "mmxshft")
21776    (set_attr "mode" "DI")])
21777
21778 (define_insn "mmx_packssdw"
21779   [(set (match_operand:V4HI 0 "register_operand" "=y")
21780         (vec_concat:V4HI
21781          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21782          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21783   "TARGET_MMX"
21784   "packssdw\t{%2, %0|%0, %2}"
21785   [(set_attr "type" "mmxshft")
21786    (set_attr "mode" "DI")])
21787
21788 (define_insn "mmx_packuswb"
21789   [(set (match_operand:V8QI 0 "register_operand" "=y")
21790         (vec_concat:V8QI
21791          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21792          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21793   "TARGET_MMX"
21794   "packuswb\t{%2, %0|%0, %2}"
21795   [(set_attr "type" "mmxshft")
21796    (set_attr "mode" "DI")])
21797
21798 (define_insn "mmx_punpckhbw"
21799   [(set (match_operand:V8QI 0 "register_operand" "=y")
21800         (vec_merge:V8QI
21801          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21802                           (parallel [(const_int 4)
21803                                      (const_int 0)
21804                                      (const_int 5)
21805                                      (const_int 1)
21806                                      (const_int 6)
21807                                      (const_int 2)
21808                                      (const_int 7)
21809                                      (const_int 3)]))
21810          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21811                           (parallel [(const_int 0)
21812                                      (const_int 4)
21813                                      (const_int 1)
21814                                      (const_int 5)
21815                                      (const_int 2)
21816                                      (const_int 6)
21817                                      (const_int 3)
21818                                      (const_int 7)]))
21819          (const_int 85)))]
21820   "TARGET_MMX"
21821   "punpckhbw\t{%2, %0|%0, %2}"
21822   [(set_attr "type" "mmxcvt")
21823    (set_attr "mode" "DI")])
21824
21825 (define_insn "mmx_punpckhwd"
21826   [(set (match_operand:V4HI 0 "register_operand" "=y")
21827         (vec_merge:V4HI
21828          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21829                           (parallel [(const_int 0)
21830                                      (const_int 2)
21831                                      (const_int 1)
21832                                      (const_int 3)]))
21833          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21834                           (parallel [(const_int 2)
21835                                      (const_int 0)
21836                                      (const_int 3)
21837                                      (const_int 1)]))
21838          (const_int 5)))]
21839   "TARGET_MMX"
21840   "punpckhwd\t{%2, %0|%0, %2}"
21841   [(set_attr "type" "mmxcvt")
21842    (set_attr "mode" "DI")])
21843
21844 (define_insn "mmx_punpckhdq"
21845   [(set (match_operand:V2SI 0 "register_operand" "=y")
21846         (vec_merge:V2SI
21847          (match_operand:V2SI 1 "register_operand" "0")
21848          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21849                           (parallel [(const_int 1)
21850                                      (const_int 0)]))
21851          (const_int 1)))]
21852   "TARGET_MMX"
21853   "punpckhdq\t{%2, %0|%0, %2}"
21854   [(set_attr "type" "mmxcvt")
21855    (set_attr "mode" "DI")])
21856
21857 (define_insn "mmx_punpcklbw"
21858   [(set (match_operand:V8QI 0 "register_operand" "=y")
21859         (vec_merge:V8QI
21860          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21861                           (parallel [(const_int 0)
21862                                      (const_int 4)
21863                                      (const_int 1)
21864                                      (const_int 5)
21865                                      (const_int 2)
21866                                      (const_int 6)
21867                                      (const_int 3)
21868                                      (const_int 7)]))
21869          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21870                           (parallel [(const_int 4)
21871                                      (const_int 0)
21872                                      (const_int 5)
21873                                      (const_int 1)
21874                                      (const_int 6)
21875                                      (const_int 2)
21876                                      (const_int 7)
21877                                      (const_int 3)]))
21878          (const_int 85)))]
21879   "TARGET_MMX"
21880   "punpcklbw\t{%2, %0|%0, %2}"
21881   [(set_attr "type" "mmxcvt")
21882    (set_attr "mode" "DI")])
21883
21884 (define_insn "mmx_punpcklwd"
21885   [(set (match_operand:V4HI 0 "register_operand" "=y")
21886         (vec_merge:V4HI
21887          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21888                           (parallel [(const_int 2)
21889                                      (const_int 0)
21890                                      (const_int 3)
21891                                      (const_int 1)]))
21892          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21893                           (parallel [(const_int 0)
21894                                      (const_int 2)
21895                                      (const_int 1)
21896                                      (const_int 3)]))
21897          (const_int 5)))]
21898   "TARGET_MMX"
21899   "punpcklwd\t{%2, %0|%0, %2}"
21900   [(set_attr "type" "mmxcvt")
21901    (set_attr "mode" "DI")])
21902
21903 (define_insn "mmx_punpckldq"
21904   [(set (match_operand:V2SI 0 "register_operand" "=y")
21905         (vec_merge:V2SI
21906          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21907                            (parallel [(const_int 1)
21908                                       (const_int 0)]))
21909          (match_operand:V2SI 2 "register_operand" "y")
21910          (const_int 1)))]
21911   "TARGET_MMX"
21912   "punpckldq\t{%2, %0|%0, %2}"
21913   [(set_attr "type" "mmxcvt")
21914    (set_attr "mode" "DI")])
21915
21916
21917 ;; Miscellaneous stuff
21918
21919 (define_insn "emms"
21920   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21921    (clobber (reg:XF 8))
21922    (clobber (reg:XF 9))
21923    (clobber (reg:XF 10))
21924    (clobber (reg:XF 11))
21925    (clobber (reg:XF 12))
21926    (clobber (reg:XF 13))
21927    (clobber (reg:XF 14))
21928    (clobber (reg:XF 15))
21929    (clobber (reg:DI 29))
21930    (clobber (reg:DI 30))
21931    (clobber (reg:DI 31))
21932    (clobber (reg:DI 32))
21933    (clobber (reg:DI 33))
21934    (clobber (reg:DI 34))
21935    (clobber (reg:DI 35))
21936    (clobber (reg:DI 36))]
21937   "TARGET_MMX"
21938   "emms"
21939   [(set_attr "type" "mmx")
21940    (set_attr "memory" "unknown")])
21941
21942 (define_insn "ldmxcsr"
21943   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21944                     UNSPECV_LDMXCSR)]
21945   "TARGET_SSE"
21946   "ldmxcsr\t%0"
21947   [(set_attr "type" "sse")
21948    (set_attr "memory" "load")])
21949
21950 (define_insn "stmxcsr"
21951   [(set (match_operand:SI 0 "memory_operand" "=m")
21952         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21953   "TARGET_SSE"
21954   "stmxcsr\t%0"
21955   [(set_attr "type" "sse")
21956    (set_attr "memory" "store")])
21957
21958 (define_expand "sfence"
21959   [(set (match_dup 0)
21960         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21961   "TARGET_SSE || TARGET_3DNOW_A"
21962 {
21963   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21964   MEM_VOLATILE_P (operands[0]) = 1;
21965 })
21966
21967 (define_insn "*sfence_insn"
21968   [(set (match_operand:BLK 0 "" "")
21969         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21970   "TARGET_SSE || TARGET_3DNOW_A"
21971   "sfence"
21972   [(set_attr "type" "sse")
21973    (set_attr "memory" "unknown")])
21974
21975 (define_expand "sse_prologue_save"
21976   [(parallel [(set (match_operand:BLK 0 "" "")
21977                    (unspec:BLK [(reg:DI 21)
21978                                 (reg:DI 22)
21979                                 (reg:DI 23)
21980                                 (reg:DI 24)
21981                                 (reg:DI 25)
21982                                 (reg:DI 26)
21983                                 (reg:DI 27)
21984                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21985               (use (match_operand:DI 1 "register_operand" ""))
21986               (use (match_operand:DI 2 "immediate_operand" ""))
21987               (use (label_ref:DI (match_operand 3 "" "")))])]
21988   "TARGET_64BIT"
21989   "")
21990
21991 (define_insn "*sse_prologue_save_insn"
21992   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21993                           (match_operand:DI 4 "const_int_operand" "n")))
21994         (unspec:BLK [(reg:DI 21)
21995                      (reg:DI 22)
21996                      (reg:DI 23)
21997                      (reg:DI 24)
21998                      (reg:DI 25)
21999                      (reg:DI 26)
22000                      (reg:DI 27)
22001                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22002    (use (match_operand:DI 1 "register_operand" "r"))
22003    (use (match_operand:DI 2 "const_int_operand" "i"))
22004    (use (label_ref:DI (match_operand 3 "" "X")))]
22005   "TARGET_64BIT
22006    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22007    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22008   "*
22009 {
22010   int i;
22011   operands[0] = gen_rtx_MEM (Pmode,
22012                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22013   output_asm_insn (\"jmp\\t%A1\", operands);
22014   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22015     {
22016       operands[4] = adjust_address (operands[0], DImode, i*16);
22017       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22018       PUT_MODE (operands[4], TImode);
22019       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22020         output_asm_insn (\"rex\", operands);
22021       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22022     }
22023   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22024                              CODE_LABEL_NUMBER (operands[3]));
22025   RET;
22026 }
22027   "
22028   [(set_attr "type" "other")
22029    (set_attr "length_immediate" "0")
22030    (set_attr "length_address" "0")
22031    (set_attr "length" "135")
22032    (set_attr "memory" "store")
22033    (set_attr "modrm" "0")
22034    (set_attr "mode" "DI")])
22035
22036 ;; 3Dnow! instructions
22037
22038 (define_insn "addv2sf3"
22039   [(set (match_operand:V2SF 0 "register_operand" "=y")
22040         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22041                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22042   "TARGET_3DNOW"
22043   "pfadd\\t{%2, %0|%0, %2}"
22044   [(set_attr "type" "mmxadd")
22045    (set_attr "mode" "V2SF")])
22046
22047 (define_insn "subv2sf3"
22048   [(set (match_operand:V2SF 0 "register_operand" "=y")
22049         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22050                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22051   "TARGET_3DNOW"
22052   "pfsub\\t{%2, %0|%0, %2}"
22053   [(set_attr "type" "mmxadd")
22054    (set_attr "mode" "V2SF")])
22055
22056 (define_insn "subrv2sf3"
22057   [(set (match_operand:V2SF 0 "register_operand" "=y")
22058         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22059                     (match_operand:V2SF 1 "register_operand" "0")))]
22060   "TARGET_3DNOW"
22061   "pfsubr\\t{%2, %0|%0, %2}"
22062   [(set_attr "type" "mmxadd")
22063    (set_attr "mode" "V2SF")])
22064
22065 (define_insn "gtv2sf3"
22066   [(set (match_operand:V2SI 0 "register_operand" "=y")
22067         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22068                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22069   "TARGET_3DNOW"
22070   "pfcmpgt\\t{%2, %0|%0, %2}"
22071   [(set_attr "type" "mmxcmp")
22072    (set_attr "mode" "V2SF")])
22073
22074 (define_insn "gev2sf3"
22075   [(set (match_operand:V2SI 0 "register_operand" "=y")
22076         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22077                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22078   "TARGET_3DNOW"
22079   "pfcmpge\\t{%2, %0|%0, %2}"
22080   [(set_attr "type" "mmxcmp")
22081    (set_attr "mode" "V2SF")])
22082
22083 (define_insn "eqv2sf3"
22084   [(set (match_operand:V2SI 0 "register_operand" "=y")
22085         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22086                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22087   "TARGET_3DNOW"
22088   "pfcmpeq\\t{%2, %0|%0, %2}"
22089   [(set_attr "type" "mmxcmp")
22090    (set_attr "mode" "V2SF")])
22091
22092 (define_insn "pfmaxv2sf3"
22093   [(set (match_operand:V2SF 0 "register_operand" "=y")
22094         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22095                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22096   "TARGET_3DNOW"
22097   "pfmax\\t{%2, %0|%0, %2}"
22098   [(set_attr "type" "mmxadd")
22099    (set_attr "mode" "V2SF")])
22100
22101 (define_insn "pfminv2sf3"
22102   [(set (match_operand:V2SF 0 "register_operand" "=y")
22103         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22104                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22105   "TARGET_3DNOW"
22106   "pfmin\\t{%2, %0|%0, %2}"
22107   [(set_attr "type" "mmxadd")
22108    (set_attr "mode" "V2SF")])
22109
22110 (define_insn "mulv2sf3"
22111   [(set (match_operand:V2SF 0 "register_operand" "=y")
22112         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22113                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22114   "TARGET_3DNOW"
22115   "pfmul\\t{%2, %0|%0, %2}"
22116   [(set_attr "type" "mmxmul")
22117    (set_attr "mode" "V2SF")])
22118
22119 (define_insn "femms"
22120   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22121    (clobber (reg:XF 8))
22122    (clobber (reg:XF 9))
22123    (clobber (reg:XF 10))
22124    (clobber (reg:XF 11))
22125    (clobber (reg:XF 12))
22126    (clobber (reg:XF 13))
22127    (clobber (reg:XF 14))
22128    (clobber (reg:XF 15))
22129    (clobber (reg:DI 29))
22130    (clobber (reg:DI 30))
22131    (clobber (reg:DI 31))
22132    (clobber (reg:DI 32))
22133    (clobber (reg:DI 33))
22134    (clobber (reg:DI 34))
22135    (clobber (reg:DI 35))
22136    (clobber (reg:DI 36))]
22137   "TARGET_3DNOW"
22138   "femms"
22139   [(set_attr "type" "mmx")
22140    (set_attr "memory" "none")]) 
22141
22142 (define_insn "pf2id"
22143   [(set (match_operand:V2SI 0 "register_operand" "=y")
22144         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22145   "TARGET_3DNOW"
22146   "pf2id\\t{%1, %0|%0, %1}"
22147   [(set_attr "type" "mmxcvt")
22148    (set_attr "mode" "V2SF")])
22149
22150 (define_insn "pf2iw"
22151   [(set (match_operand:V2SI 0 "register_operand" "=y")
22152         (sign_extend:V2SI
22153            (ss_truncate:V2HI
22154               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22155   "TARGET_3DNOW_A"
22156   "pf2iw\\t{%1, %0|%0, %1}"
22157   [(set_attr "type" "mmxcvt")
22158    (set_attr "mode" "V2SF")])
22159
22160 (define_insn "pfacc"
22161   [(set (match_operand:V2SF 0 "register_operand" "=y")
22162         (vec_concat:V2SF
22163            (plus:SF
22164               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22165                              (parallel [(const_int  0)]))
22166               (vec_select:SF (match_dup 1)
22167                              (parallel [(const_int 1)])))
22168            (plus:SF
22169               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22170                              (parallel [(const_int  0)]))
22171               (vec_select:SF (match_dup 2)
22172                              (parallel [(const_int 1)])))))]
22173   "TARGET_3DNOW"
22174   "pfacc\\t{%2, %0|%0, %2}"
22175   [(set_attr "type" "mmxadd")
22176    (set_attr "mode" "V2SF")])
22177
22178 (define_insn "pfnacc"
22179   [(set (match_operand:V2SF 0 "register_operand" "=y")
22180         (vec_concat:V2SF
22181            (minus:SF
22182               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22183                              (parallel [(const_int 0)]))
22184               (vec_select:SF (match_dup 1)
22185                              (parallel [(const_int 1)])))
22186            (minus:SF
22187               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22188                              (parallel [(const_int  0)]))
22189               (vec_select:SF (match_dup 2)
22190                              (parallel [(const_int 1)])))))]
22191   "TARGET_3DNOW_A"
22192   "pfnacc\\t{%2, %0|%0, %2}"
22193   [(set_attr "type" "mmxadd")
22194    (set_attr "mode" "V2SF")])
22195
22196 (define_insn "pfpnacc"
22197   [(set (match_operand:V2SF 0 "register_operand" "=y")
22198         (vec_concat:V2SF
22199            (minus:SF
22200               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22201                              (parallel [(const_int 0)]))
22202               (vec_select:SF (match_dup 1)
22203                              (parallel [(const_int 1)])))
22204            (plus:SF
22205               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22206                              (parallel [(const_int 0)]))
22207               (vec_select:SF (match_dup 2)
22208                              (parallel [(const_int 1)])))))]
22209   "TARGET_3DNOW_A"
22210   "pfpnacc\\t{%2, %0|%0, %2}"
22211   [(set_attr "type" "mmxadd")
22212    (set_attr "mode" "V2SF")])
22213
22214 (define_insn "pi2fw"
22215   [(set (match_operand:V2SF 0 "register_operand" "=y")
22216         (float:V2SF
22217            (vec_concat:V2SI
22218               (sign_extend:SI
22219                  (truncate:HI
22220                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22221                                    (parallel [(const_int 0)]))))
22222               (sign_extend:SI
22223                  (truncate:HI
22224                     (vec_select:SI (match_dup 1)
22225                                    (parallel [(const_int  1)])))))))]
22226   "TARGET_3DNOW_A"
22227   "pi2fw\\t{%1, %0|%0, %1}"
22228   [(set_attr "type" "mmxcvt")
22229    (set_attr "mode" "V2SF")])
22230
22231 (define_insn "floatv2si2"
22232   [(set (match_operand:V2SF 0 "register_operand" "=y")
22233         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22234   "TARGET_3DNOW"
22235   "pi2fd\\t{%1, %0|%0, %1}"
22236   [(set_attr "type" "mmxcvt")
22237    (set_attr "mode" "V2SF")])
22238
22239 ;; This insn is identical to pavgb in operation, but the opcode is
22240 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22241
22242 (define_insn "pavgusb"
22243  [(set (match_operand:V8QI 0 "register_operand" "=y")
22244        (unspec:V8QI
22245           [(match_operand:V8QI 1 "register_operand" "0")
22246            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22247           UNSPEC_PAVGUSB))]
22248   "TARGET_3DNOW"
22249   "pavgusb\\t{%2, %0|%0, %2}"
22250   [(set_attr "type" "mmxshft")
22251    (set_attr "mode" "TI")])
22252
22253 ;; 3DNow reciprocal and sqrt
22254  
22255 (define_insn "pfrcpv2sf2"
22256   [(set (match_operand:V2SF 0 "register_operand" "=y")
22257         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22258         UNSPEC_PFRCP))]
22259   "TARGET_3DNOW"
22260   "pfrcp\\t{%1, %0|%0, %1}"
22261   [(set_attr "type" "mmx")
22262    (set_attr "mode" "TI")])
22263
22264 (define_insn "pfrcpit1v2sf3"
22265   [(set (match_operand:V2SF 0 "register_operand" "=y")
22266         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22267                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22268                      UNSPEC_PFRCPIT1))]
22269   "TARGET_3DNOW"
22270   "pfrcpit1\\t{%2, %0|%0, %2}"
22271   [(set_attr "type" "mmx")
22272    (set_attr "mode" "TI")])
22273
22274 (define_insn "pfrcpit2v2sf3"
22275   [(set (match_operand:V2SF 0 "register_operand" "=y")
22276         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22277                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22278                      UNSPEC_PFRCPIT2))]
22279   "TARGET_3DNOW"
22280   "pfrcpit2\\t{%2, %0|%0, %2}"
22281   [(set_attr "type" "mmx")
22282    (set_attr "mode" "TI")])
22283
22284 (define_insn "pfrsqrtv2sf2"
22285   [(set (match_operand:V2SF 0 "register_operand" "=y")
22286         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22287                      UNSPEC_PFRSQRT))]
22288   "TARGET_3DNOW"
22289   "pfrsqrt\\t{%1, %0|%0, %1}"
22290   [(set_attr "type" "mmx")
22291    (set_attr "mode" "TI")])
22292                 
22293 (define_insn "pfrsqit1v2sf3"
22294   [(set (match_operand:V2SF 0 "register_operand" "=y")
22295         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22296                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22297                      UNSPEC_PFRSQIT1))]
22298   "TARGET_3DNOW"
22299   "pfrsqit1\\t{%2, %0|%0, %2}"
22300   [(set_attr "type" "mmx")
22301    (set_attr "mode" "TI")])
22302
22303 (define_insn "pmulhrwv4hi3"
22304   [(set (match_operand:V4HI 0 "register_operand" "=y")
22305         (truncate:V4HI
22306            (lshiftrt:V4SI
22307               (plus:V4SI
22308                  (mult:V4SI
22309                     (sign_extend:V4SI
22310                        (match_operand:V4HI 1 "register_operand" "0"))
22311                     (sign_extend:V4SI
22312                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22313                  (const_vector:V4SI [(const_int 32768)
22314                                      (const_int 32768)
22315                                      (const_int 32768)
22316                                      (const_int 32768)]))
22317               (const_int 16))))]
22318   "TARGET_3DNOW"
22319   "pmulhrw\\t{%2, %0|%0, %2}"
22320   [(set_attr "type" "mmxmul")
22321    (set_attr "mode" "TI")])
22322
22323 (define_insn "pswapdv2si2"
22324   [(set (match_operand:V2SI 0 "register_operand" "=y")
22325         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22326                          (parallel [(const_int 1) (const_int 0)])))]
22327   "TARGET_3DNOW_A"
22328   "pswapd\\t{%1, %0|%0, %1}"
22329   [(set_attr "type" "mmxcvt")
22330    (set_attr "mode" "TI")])
22331
22332 (define_insn "pswapdv2sf2"
22333   [(set (match_operand:V2SF 0 "register_operand" "=y")
22334         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22335                          (parallel [(const_int 1) (const_int 0)])))]
22336   "TARGET_3DNOW_A"
22337   "pswapd\\t{%1, %0|%0, %1}"
22338   [(set_attr "type" "mmxcvt")
22339    (set_attr "mode" "TI")])
22340
22341 (define_expand "prefetch"
22342   [(prefetch (match_operand 0 "address_operand" "")
22343              (match_operand:SI 1 "const_int_operand" "")
22344              (match_operand:SI 2 "const_int_operand" ""))]
22345   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22346 {
22347   int rw = INTVAL (operands[1]);
22348   int locality = INTVAL (operands[2]);
22349
22350   if (rw != 0 && rw != 1)
22351     abort ();
22352   if (locality < 0 || locality > 3)
22353     abort ();
22354   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22355     abort ();
22356
22357   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22358      suported by SSE counterpart or the SSE prefetch is not available
22359      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22360      of locality.  */
22361   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22362     operands[2] = GEN_INT (3);
22363   else
22364     operands[1] = const0_rtx;
22365 })
22366
22367 (define_insn "*prefetch_sse"
22368   [(prefetch (match_operand:SI 0 "address_operand" "p")
22369              (const_int 0)
22370              (match_operand:SI 1 "const_int_operand" ""))]
22371   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22372 {
22373   static const char * const patterns[4] = {
22374    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22375   };
22376
22377   int locality = INTVAL (operands[1]);
22378   if (locality < 0 || locality > 3)
22379     abort ();
22380
22381   return patterns[locality];  
22382 }
22383   [(set_attr "type" "sse")
22384    (set_attr "memory" "none")])
22385
22386 (define_insn "*prefetch_sse_rex"
22387   [(prefetch (match_operand:DI 0 "address_operand" "p")
22388              (const_int 0)
22389              (match_operand:SI 1 "const_int_operand" ""))]
22390   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22391 {
22392   static const char * const patterns[4] = {
22393    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22394   };
22395
22396   int locality = INTVAL (operands[1]);
22397   if (locality < 0 || locality > 3)
22398     abort ();
22399
22400   return patterns[locality];  
22401 }
22402   [(set_attr "type" "sse")
22403    (set_attr "memory" "none")])
22404
22405 (define_insn "*prefetch_3dnow"
22406   [(prefetch (match_operand:SI 0 "address_operand" "p")
22407              (match_operand:SI 1 "const_int_operand" "n")
22408              (const_int 3))]
22409   "TARGET_3DNOW && !TARGET_64BIT"
22410 {
22411   if (INTVAL (operands[1]) == 0)
22412     return "prefetch\t%a0";
22413   else
22414     return "prefetchw\t%a0";
22415 }
22416   [(set_attr "type" "mmx")
22417    (set_attr "memory" "none")])
22418
22419 (define_insn "*prefetch_3dnow_rex"
22420   [(prefetch (match_operand:DI 0 "address_operand" "p")
22421              (match_operand:SI 1 "const_int_operand" "n")
22422              (const_int 3))]
22423   "TARGET_3DNOW && TARGET_64BIT"
22424 {
22425   if (INTVAL (operands[1]) == 0)
22426     return "prefetch\t%a0";
22427   else
22428     return "prefetchw\t%a0";
22429 }
22430   [(set_attr "type" "mmx")
22431    (set_attr "memory" "none")])
22432
22433 ;; SSE2 support
22434
22435 (define_insn "addv2df3"
22436   [(set (match_operand:V2DF 0 "register_operand" "=x")
22437         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22438                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22439   "TARGET_SSE2"
22440   "addpd\t{%2, %0|%0, %2}"
22441   [(set_attr "type" "sseadd")
22442    (set_attr "mode" "V2DF")])
22443
22444 (define_insn "vmaddv2df3"
22445   [(set (match_operand:V2DF 0 "register_operand" "=x")
22446         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22447                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22448                         (match_dup 1)
22449                         (const_int 1)))]
22450   "TARGET_SSE2"
22451   "addsd\t{%2, %0|%0, %2}"
22452   [(set_attr "type" "sseadd")
22453    (set_attr "mode" "DF")])
22454
22455 (define_insn "subv2df3"
22456   [(set (match_operand:V2DF 0 "register_operand" "=x")
22457         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22458                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22459   "TARGET_SSE2"
22460   "subpd\t{%2, %0|%0, %2}"
22461   [(set_attr "type" "sseadd")
22462    (set_attr "mode" "V2DF")])
22463
22464 (define_insn "vmsubv2df3"
22465   [(set (match_operand:V2DF 0 "register_operand" "=x")
22466         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22467                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22468                         (match_dup 1)
22469                         (const_int 1)))]
22470   "TARGET_SSE2"
22471   "subsd\t{%2, %0|%0, %2}"
22472   [(set_attr "type" "sseadd")
22473    (set_attr "mode" "DF")])
22474
22475 (define_insn "mulv2df3"
22476   [(set (match_operand:V2DF 0 "register_operand" "=x")
22477         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22478                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22479   "TARGET_SSE2"
22480   "mulpd\t{%2, %0|%0, %2}"
22481   [(set_attr "type" "ssemul")
22482    (set_attr "mode" "V2DF")])
22483
22484 (define_insn "vmmulv2df3"
22485   [(set (match_operand:V2DF 0 "register_operand" "=x")
22486         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22487                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22488                         (match_dup 1)
22489                         (const_int 1)))]
22490   "TARGET_SSE2"
22491   "mulsd\t{%2, %0|%0, %2}"
22492   [(set_attr "type" "ssemul")
22493    (set_attr "mode" "DF")])
22494
22495 (define_insn "divv2df3"
22496   [(set (match_operand:V2DF 0 "register_operand" "=x")
22497         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22498                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22499   "TARGET_SSE2"
22500   "divpd\t{%2, %0|%0, %2}"
22501   [(set_attr "type" "ssediv")
22502    (set_attr "mode" "V2DF")])
22503
22504 (define_insn "vmdivv2df3"
22505   [(set (match_operand:V2DF 0 "register_operand" "=x")
22506         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22507                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22508                         (match_dup 1)
22509                         (const_int 1)))]
22510   "TARGET_SSE2"
22511   "divsd\t{%2, %0|%0, %2}"
22512   [(set_attr "type" "ssediv")
22513    (set_attr "mode" "DF")])
22514
22515 ;; SSE min/max
22516
22517 (define_insn "smaxv2df3"
22518   [(set (match_operand:V2DF 0 "register_operand" "=x")
22519         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22520                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22521   "TARGET_SSE2"
22522   "maxpd\t{%2, %0|%0, %2}"
22523   [(set_attr "type" "sseadd")
22524    (set_attr "mode" "V2DF")])
22525
22526 (define_insn "vmsmaxv2df3"
22527   [(set (match_operand:V2DF 0 "register_operand" "=x")
22528         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22529                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22530                         (match_dup 1)
22531                         (const_int 1)))]
22532   "TARGET_SSE2"
22533   "maxsd\t{%2, %0|%0, %2}"
22534   [(set_attr "type" "sseadd")
22535    (set_attr "mode" "DF")])
22536
22537 (define_insn "sminv2df3"
22538   [(set (match_operand:V2DF 0 "register_operand" "=x")
22539         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22540                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22541   "TARGET_SSE2"
22542   "minpd\t{%2, %0|%0, %2}"
22543   [(set_attr "type" "sseadd")
22544    (set_attr "mode" "V2DF")])
22545
22546 (define_insn "vmsminv2df3"
22547   [(set (match_operand:V2DF 0 "register_operand" "=x")
22548         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22549                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22550                         (match_dup 1)
22551                         (const_int 1)))]
22552   "TARGET_SSE2"
22553   "minsd\t{%2, %0|%0, %2}"
22554   [(set_attr "type" "sseadd")
22555    (set_attr "mode" "DF")])
22556 ;; SSE2 square root.  There doesn't appear to be an extension for the
22557 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22558
22559 (define_insn "sqrtv2df2"
22560   [(set (match_operand:V2DF 0 "register_operand" "=x")
22561         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22562   "TARGET_SSE2"
22563   "sqrtpd\t{%1, %0|%0, %1}"
22564   [(set_attr "type" "sse")
22565    (set_attr "mode" "V2DF")])
22566
22567 (define_insn "vmsqrtv2df2"
22568   [(set (match_operand:V2DF 0 "register_operand" "=x")
22569         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22570                         (match_operand:V2DF 2 "register_operand" "0")
22571                         (const_int 1)))]
22572   "TARGET_SSE2"
22573   "sqrtsd\t{%1, %0|%0, %1}"
22574   [(set_attr "type" "sse")
22575    (set_attr "mode" "SF")])
22576
22577 ;; SSE mask-generating compares
22578
22579 (define_insn "maskcmpv2df3"
22580   [(set (match_operand:V2DI 0 "register_operand" "=x")
22581         (match_operator:V2DI 3 "sse_comparison_operator"
22582                              [(match_operand:V2DF 1 "register_operand" "0")
22583                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22584   "TARGET_SSE2"
22585   "cmp%D3pd\t{%2, %0|%0, %2}"
22586   [(set_attr "type" "ssecmp")
22587    (set_attr "mode" "V2DF")])
22588
22589 (define_insn "maskncmpv2df3"
22590   [(set (match_operand:V2DI 0 "register_operand" "=x")
22591         (not:V2DI
22592          (match_operator:V2DI 3 "sse_comparison_operator"
22593                               [(match_operand:V2DF 1 "register_operand" "0")
22594                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22595   "TARGET_SSE2"
22596 {
22597   if (GET_CODE (operands[3]) == UNORDERED)
22598     return "cmpordps\t{%2, %0|%0, %2}";
22599   else
22600     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22601 }
22602   [(set_attr "type" "ssecmp")
22603    (set_attr "mode" "V2DF")])
22604
22605 (define_insn "vmmaskcmpv2df3"
22606   [(set (match_operand:V2DI 0 "register_operand" "=x")
22607         (vec_merge:V2DI
22608          (match_operator:V2DI 3 "sse_comparison_operator"
22609                               [(match_operand:V2DF 1 "register_operand" "0")
22610                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22611          (subreg:V2DI (match_dup 1) 0)
22612          (const_int 1)))]
22613   "TARGET_SSE2"
22614   "cmp%D3sd\t{%2, %0|%0, %2}"
22615   [(set_attr "type" "ssecmp")
22616    (set_attr "mode" "DF")])
22617
22618 (define_insn "vmmaskncmpv2df3"
22619   [(set (match_operand:V2DI 0 "register_operand" "=x")
22620         (vec_merge:V2DI
22621          (not:V2DI
22622           (match_operator:V2DI 3 "sse_comparison_operator"
22623                                [(match_operand:V2DF 1 "register_operand" "0")
22624                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22625          (subreg:V2DI (match_dup 1) 0)
22626          (const_int 1)))]
22627   "TARGET_SSE2"
22628 {
22629   if (GET_CODE (operands[3]) == UNORDERED)
22630     return "cmpordsd\t{%2, %0|%0, %2}";
22631   else
22632     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22633 }
22634   [(set_attr "type" "ssecmp")
22635    (set_attr "mode" "DF")])
22636
22637 (define_insn "sse2_comi"
22638   [(set (reg:CCFP FLAGS_REG)
22639         (compare:CCFP (vec_select:DF
22640                        (match_operand:V2DF 0 "register_operand" "x")
22641                        (parallel [(const_int 0)]))
22642                       (vec_select:DF
22643                        (match_operand:V2DF 1 "register_operand" "x")
22644                        (parallel [(const_int 0)]))))]
22645   "TARGET_SSE2"
22646   "comisd\t{%1, %0|%0, %1}"
22647   [(set_attr "type" "ssecomi")
22648    (set_attr "mode" "DF")])
22649
22650 (define_insn "sse2_ucomi"
22651   [(set (reg:CCFPU FLAGS_REG)
22652         (compare:CCFPU (vec_select:DF
22653                          (match_operand:V2DF 0 "register_operand" "x")
22654                          (parallel [(const_int 0)]))
22655                         (vec_select:DF
22656                          (match_operand:V2DF 1 "register_operand" "x")
22657                          (parallel [(const_int 0)]))))]
22658   "TARGET_SSE2"
22659   "ucomisd\t{%1, %0|%0, %1}"
22660   [(set_attr "type" "ssecomi")
22661    (set_attr "mode" "DF")])
22662
22663 ;; SSE Strange Moves.
22664
22665 (define_insn "sse2_movmskpd"
22666   [(set (match_operand:SI 0 "register_operand" "=r")
22667         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22668                    UNSPEC_MOVMSK))]
22669   "TARGET_SSE2"
22670   "movmskpd\t{%1, %0|%0, %1}"
22671   [(set_attr "type" "ssecvt")
22672    (set_attr "mode" "V2DF")])
22673
22674 (define_insn "sse2_pmovmskb"
22675   [(set (match_operand:SI 0 "register_operand" "=r")
22676         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22677                    UNSPEC_MOVMSK))]
22678   "TARGET_SSE2"
22679   "pmovmskb\t{%1, %0|%0, %1}"
22680   [(set_attr "type" "ssecvt")
22681    (set_attr "mode" "V2DF")])
22682
22683 (define_insn "sse2_maskmovdqu"
22684   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22685         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22686                        (match_operand:V16QI 2 "register_operand" "x")]
22687                       UNSPEC_MASKMOV))]
22688   "TARGET_SSE2"
22689   ;; @@@ check ordering of operands in intel/nonintel syntax
22690   "maskmovdqu\t{%2, %1|%1, %2}"
22691   [(set_attr "type" "ssecvt")
22692    (set_attr "mode" "TI")])
22693
22694 (define_insn "sse2_maskmovdqu_rex64"
22695   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22696         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22697                        (match_operand:V16QI 2 "register_operand" "x")]
22698                       UNSPEC_MASKMOV))]
22699   "TARGET_SSE2"
22700   ;; @@@ check ordering of operands in intel/nonintel syntax
22701   "maskmovdqu\t{%2, %1|%1, %2}"
22702   [(set_attr "type" "ssecvt")
22703    (set_attr "mode" "TI")])
22704
22705 (define_insn "sse2_movntv2df"
22706   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22707         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22708                      UNSPEC_MOVNT))]
22709   "TARGET_SSE2"
22710   "movntpd\t{%1, %0|%0, %1}"
22711   [(set_attr "type" "ssecvt")
22712    (set_attr "mode" "V2DF")])
22713
22714 (define_insn "sse2_movntv2di"
22715   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22716         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22717                      UNSPEC_MOVNT))]
22718   "TARGET_SSE2"
22719   "movntdq\t{%1, %0|%0, %1}"
22720   [(set_attr "type" "ssecvt")
22721    (set_attr "mode" "TI")])
22722
22723 (define_insn "sse2_movntsi"
22724   [(set (match_operand:SI 0 "memory_operand" "=m")
22725         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22726                    UNSPEC_MOVNT))]
22727   "TARGET_SSE2"
22728   "movnti\t{%1, %0|%0, %1}"
22729   [(set_attr "type" "ssecvt")
22730    (set_attr "mode" "V2DF")])
22731
22732 ;; SSE <-> integer/MMX conversions
22733
22734 ;; Conversions between SI and SF
22735
22736 (define_insn "cvtdq2ps"
22737   [(set (match_operand:V4SF 0 "register_operand" "=x")
22738         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22739   "TARGET_SSE2"
22740   "cvtdq2ps\t{%1, %0|%0, %1}"
22741   [(set_attr "type" "ssecvt")
22742    (set_attr "mode" "V2DF")])
22743
22744 (define_insn "cvtps2dq"
22745   [(set (match_operand:V4SI 0 "register_operand" "=x")
22746         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22747   "TARGET_SSE2"
22748   "cvtps2dq\t{%1, %0|%0, %1}"
22749   [(set_attr "type" "ssecvt")
22750    (set_attr "mode" "TI")])
22751
22752 (define_insn "cvttps2dq"
22753   [(set (match_operand:V4SI 0 "register_operand" "=x")
22754         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22755                      UNSPEC_FIX))]
22756   "TARGET_SSE2"
22757   "cvttps2dq\t{%1, %0|%0, %1}"
22758   [(set_attr "type" "ssecvt")
22759    (set_attr "mode" "TI")])
22760
22761 ;; Conversions between SI and DF
22762
22763 (define_insn "cvtdq2pd"
22764   [(set (match_operand:V2DF 0 "register_operand" "=x")
22765         (float:V2DF (vec_select:V2SI
22766                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22767                      (parallel
22768                       [(const_int 0)
22769                        (const_int 1)]))))]
22770   "TARGET_SSE2"
22771   "cvtdq2pd\t{%1, %0|%0, %1}"
22772   [(set_attr "type" "ssecvt")
22773    (set_attr "mode" "V2DF")])
22774
22775 (define_insn "cvtpd2dq"
22776   [(set (match_operand:V4SI 0 "register_operand" "=x")
22777         (vec_concat:V4SI
22778          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22779          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22780   "TARGET_SSE2"
22781   "cvtpd2dq\t{%1, %0|%0, %1}"
22782   [(set_attr "type" "ssecvt")
22783    (set_attr "mode" "TI")])
22784
22785 (define_insn "cvttpd2dq"
22786   [(set (match_operand:V4SI 0 "register_operand" "=x")
22787         (vec_concat:V4SI
22788          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22789                       UNSPEC_FIX)
22790          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22791   "TARGET_SSE2"
22792   "cvttpd2dq\t{%1, %0|%0, %1}"
22793   [(set_attr "type" "ssecvt")
22794    (set_attr "mode" "TI")])
22795
22796 (define_insn "cvtpd2pi"
22797   [(set (match_operand:V2SI 0 "register_operand" "=y")
22798         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22799   "TARGET_SSE2"
22800   "cvtpd2pi\t{%1, %0|%0, %1}"
22801   [(set_attr "type" "ssecvt")
22802    (set_attr "mode" "TI")])
22803
22804 (define_insn "cvttpd2pi"
22805   [(set (match_operand:V2SI 0 "register_operand" "=y")
22806         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22807                      UNSPEC_FIX))]
22808   "TARGET_SSE2"
22809   "cvttpd2pi\t{%1, %0|%0, %1}"
22810   [(set_attr "type" "ssecvt")
22811    (set_attr "mode" "TI")])
22812
22813 (define_insn "cvtpi2pd"
22814   [(set (match_operand:V2DF 0 "register_operand" "=x")
22815         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22816   "TARGET_SSE2"
22817   "cvtpi2pd\t{%1, %0|%0, %1}"
22818   [(set_attr "type" "ssecvt")
22819    (set_attr "mode" "TI")])
22820
22821 ;; Conversions between SI and DF
22822
22823 (define_insn "cvtsd2si"
22824   [(set (match_operand:SI 0 "register_operand" "=r,r")
22825         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22826                                (parallel [(const_int 0)]))))]
22827   "TARGET_SSE2"
22828   "cvtsd2si\t{%1, %0|%0, %1}"
22829   [(set_attr "type" "sseicvt")
22830    (set_attr "athlon_decode" "double,vector")
22831    (set_attr "mode" "SI")])
22832
22833 (define_insn "cvtsd2siq"
22834   [(set (match_operand:DI 0 "register_operand" "=r,r")
22835         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22836                                (parallel [(const_int 0)]))))]
22837   "TARGET_SSE2 && TARGET_64BIT"
22838   "cvtsd2siq\t{%1, %0|%0, %1}"
22839   [(set_attr "type" "sseicvt")
22840    (set_attr "athlon_decode" "double,vector")
22841    (set_attr "mode" "DI")])
22842
22843 (define_insn "cvttsd2si"
22844   [(set (match_operand:SI 0 "register_operand" "=r,r")
22845         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22846                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22847   "TARGET_SSE2"
22848   "cvttsd2si\t{%1, %0|%0, %1}"
22849   [(set_attr "type" "sseicvt")
22850    (set_attr "mode" "SI")
22851    (set_attr "athlon_decode" "double,vector")])
22852
22853 (define_insn "cvttsd2siq"
22854   [(set (match_operand:DI 0 "register_operand" "=r,r")
22855         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22856                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22857   "TARGET_SSE2 && TARGET_64BIT"
22858   "cvttsd2siq\t{%1, %0|%0, %1}"
22859   [(set_attr "type" "sseicvt")
22860    (set_attr "mode" "DI")
22861    (set_attr "athlon_decode" "double,vector")])
22862
22863 (define_insn "cvtsi2sd"
22864   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22865         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22866                         (vec_duplicate:V2DF
22867                           (float:DF
22868                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22869                         (const_int 2)))]
22870   "TARGET_SSE2"
22871   "cvtsi2sd\t{%2, %0|%0, %2}"
22872   [(set_attr "type" "sseicvt")
22873    (set_attr "mode" "DF")
22874    (set_attr "athlon_decode" "double,direct")])
22875
22876 (define_insn "cvtsi2sdq"
22877   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22878         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22879                         (vec_duplicate:V2DF
22880                           (float:DF
22881                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22882                         (const_int 2)))]
22883   "TARGET_SSE2 && TARGET_64BIT"
22884   "cvtsi2sdq\t{%2, %0|%0, %2}"
22885   [(set_attr "type" "sseicvt")
22886    (set_attr "mode" "DF")
22887    (set_attr "athlon_decode" "double,direct")])
22888
22889 ;; Conversions between SF and DF
22890
22891 (define_insn "cvtsd2ss"
22892   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22893         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22894                         (vec_duplicate:V4SF
22895                           (float_truncate:V2SF
22896                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22897                         (const_int 14)))]
22898   "TARGET_SSE2"
22899   "cvtsd2ss\t{%2, %0|%0, %2}"
22900   [(set_attr "type" "ssecvt")
22901    (set_attr "athlon_decode" "vector,double")
22902    (set_attr "mode" "SF")])
22903
22904 (define_insn "cvtss2sd"
22905   [(set (match_operand:V2DF 0 "register_operand" "=x")
22906         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22907                         (float_extend:V2DF
22908                           (vec_select:V2SF
22909                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22910                             (parallel [(const_int 0)
22911                                        (const_int 1)])))
22912                         (const_int 2)))]
22913   "TARGET_SSE2"
22914   "cvtss2sd\t{%2, %0|%0, %2}"
22915   [(set_attr "type" "ssecvt")
22916    (set_attr "mode" "DF")])
22917
22918 (define_insn "cvtpd2ps"
22919   [(set (match_operand:V4SF 0 "register_operand" "=x")
22920         (subreg:V4SF
22921           (vec_concat:V4SI
22922             (subreg:V2SI (float_truncate:V2SF
22923                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22924             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22925   "TARGET_SSE2"
22926   "cvtpd2ps\t{%1, %0|%0, %1}"
22927   [(set_attr "type" "ssecvt")
22928    (set_attr "mode" "V4SF")])
22929
22930 (define_insn "cvtps2pd"
22931   [(set (match_operand:V2DF 0 "register_operand" "=x")
22932         (float_extend:V2DF
22933           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22934                            (parallel [(const_int 0)
22935                                       (const_int 1)]))))]
22936   "TARGET_SSE2"
22937   "cvtps2pd\t{%1, %0|%0, %1}"
22938   [(set_attr "type" "ssecvt")
22939    (set_attr "mode" "V2DF")])
22940
22941 ;; SSE2 variants of MMX insns
22942
22943 ;; MMX arithmetic
22944
22945 (define_insn "addv16qi3"
22946   [(set (match_operand:V16QI 0 "register_operand" "=x")
22947         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22948                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22949   "TARGET_SSE2"
22950   "paddb\t{%2, %0|%0, %2}"
22951   [(set_attr "type" "sseiadd")
22952    (set_attr "mode" "TI")])
22953
22954 (define_insn "addv8hi3"
22955   [(set (match_operand:V8HI 0 "register_operand" "=x")
22956         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22957                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22958   "TARGET_SSE2"
22959   "paddw\t{%2, %0|%0, %2}"
22960   [(set_attr "type" "sseiadd")
22961    (set_attr "mode" "TI")])
22962
22963 (define_insn "addv4si3"
22964   [(set (match_operand:V4SI 0 "register_operand" "=x")
22965         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22966                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22967   "TARGET_SSE2"
22968   "paddd\t{%2, %0|%0, %2}"
22969   [(set_attr "type" "sseiadd")
22970    (set_attr "mode" "TI")])
22971
22972 (define_insn "addv2di3"
22973   [(set (match_operand:V2DI 0 "register_operand" "=x")
22974         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22975                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22976   "TARGET_SSE2"
22977   "paddq\t{%2, %0|%0, %2}"
22978   [(set_attr "type" "sseiadd")
22979    (set_attr "mode" "TI")])
22980
22981 (define_insn "ssaddv16qi3"
22982   [(set (match_operand:V16QI 0 "register_operand" "=x")
22983         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22984                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22985   "TARGET_SSE2"
22986   "paddsb\t{%2, %0|%0, %2}"
22987   [(set_attr "type" "sseiadd")
22988    (set_attr "mode" "TI")])
22989
22990 (define_insn "ssaddv8hi3"
22991   [(set (match_operand:V8HI 0 "register_operand" "=x")
22992         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22993                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22994   "TARGET_SSE2"
22995   "paddsw\t{%2, %0|%0, %2}"
22996   [(set_attr "type" "sseiadd")
22997    (set_attr "mode" "TI")])
22998
22999 (define_insn "usaddv16qi3"
23000   [(set (match_operand:V16QI 0 "register_operand" "=x")
23001         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23002                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23003   "TARGET_SSE2"
23004   "paddusb\t{%2, %0|%0, %2}"
23005   [(set_attr "type" "sseiadd")
23006    (set_attr "mode" "TI")])
23007
23008 (define_insn "usaddv8hi3"
23009   [(set (match_operand:V8HI 0 "register_operand" "=x")
23010         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23011                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23012   "TARGET_SSE2"
23013   "paddusw\t{%2, %0|%0, %2}"
23014   [(set_attr "type" "sseiadd")
23015    (set_attr "mode" "TI")])
23016
23017 (define_insn "subv16qi3"
23018   [(set (match_operand:V16QI 0 "register_operand" "=x")
23019         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23020                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23021   "TARGET_SSE2"
23022   "psubb\t{%2, %0|%0, %2}"
23023   [(set_attr "type" "sseiadd")
23024    (set_attr "mode" "TI")])
23025
23026 (define_insn "subv8hi3"
23027   [(set (match_operand:V8HI 0 "register_operand" "=x")
23028         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23029                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23030   "TARGET_SSE2"
23031   "psubw\t{%2, %0|%0, %2}"
23032   [(set_attr "type" "sseiadd")
23033    (set_attr "mode" "TI")])
23034
23035 (define_insn "subv4si3"
23036   [(set (match_operand:V4SI 0 "register_operand" "=x")
23037         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23038                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23039   "TARGET_SSE2"
23040   "psubd\t{%2, %0|%0, %2}"
23041   [(set_attr "type" "sseiadd")
23042    (set_attr "mode" "TI")])
23043
23044 (define_insn "subv2di3"
23045   [(set (match_operand:V2DI 0 "register_operand" "=x")
23046         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23047                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23048   "TARGET_SSE2"
23049   "psubq\t{%2, %0|%0, %2}"
23050   [(set_attr "type" "sseiadd")
23051    (set_attr "mode" "TI")])
23052
23053 (define_insn "sssubv16qi3"
23054   [(set (match_operand:V16QI 0 "register_operand" "=x")
23055         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23056                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23057   "TARGET_SSE2"
23058   "psubsb\t{%2, %0|%0, %2}"
23059   [(set_attr "type" "sseiadd")
23060    (set_attr "mode" "TI")])
23061
23062 (define_insn "sssubv8hi3"
23063   [(set (match_operand:V8HI 0 "register_operand" "=x")
23064         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23065                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23066   "TARGET_SSE2"
23067   "psubsw\t{%2, %0|%0, %2}"
23068   [(set_attr "type" "sseiadd")
23069    (set_attr "mode" "TI")])
23070
23071 (define_insn "ussubv16qi3"
23072   [(set (match_operand:V16QI 0 "register_operand" "=x")
23073         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23074                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23075   "TARGET_SSE2"
23076   "psubusb\t{%2, %0|%0, %2}"
23077   [(set_attr "type" "sseiadd")
23078    (set_attr "mode" "TI")])
23079
23080 (define_insn "ussubv8hi3"
23081   [(set (match_operand:V8HI 0 "register_operand" "=x")
23082         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23083                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23084   "TARGET_SSE2"
23085   "psubusw\t{%2, %0|%0, %2}"
23086   [(set_attr "type" "sseiadd")
23087    (set_attr "mode" "TI")])
23088
23089 (define_insn "mulv8hi3"
23090   [(set (match_operand:V8HI 0 "register_operand" "=x")
23091         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23092                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23093   "TARGET_SSE2"
23094   "pmullw\t{%2, %0|%0, %2}"
23095   [(set_attr "type" "sseimul")
23096    (set_attr "mode" "TI")])
23097
23098 (define_insn "smulv8hi3_highpart"
23099   [(set (match_operand:V8HI 0 "register_operand" "=x")
23100         (truncate:V8HI
23101          (lshiftrt:V8SI
23102           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23103                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23104           (const_int 16))))]
23105   "TARGET_SSE2"
23106   "pmulhw\t{%2, %0|%0, %2}"
23107   [(set_attr "type" "sseimul")
23108    (set_attr "mode" "TI")])
23109
23110 (define_insn "umulv8hi3_highpart"
23111   [(set (match_operand:V8HI 0 "register_operand" "=x")
23112         (truncate:V8HI
23113          (lshiftrt:V8SI
23114           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23115                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23116           (const_int 16))))]
23117   "TARGET_SSE2"
23118   "pmulhuw\t{%2, %0|%0, %2}"
23119   [(set_attr "type" "sseimul")
23120    (set_attr "mode" "TI")])
23121
23122 (define_insn "sse2_umulsidi3"
23123   [(set (match_operand:DI 0 "register_operand" "=y")
23124         (mult:DI (zero_extend:DI (vec_select:SI
23125                                   (match_operand:V2SI 1 "register_operand" "0")
23126                                   (parallel [(const_int 0)])))
23127                  (zero_extend:DI (vec_select:SI
23128                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23129                                   (parallel [(const_int 0)])))))]
23130   "TARGET_SSE2"
23131   "pmuludq\t{%2, %0|%0, %2}"
23132   [(set_attr "type" "mmxmul")
23133    (set_attr "mode" "DI")])
23134
23135 (define_insn "sse2_umulv2siv2di3"
23136   [(set (match_operand:V2DI 0 "register_operand" "=x")
23137         (mult:V2DI (zero_extend:V2DI
23138                      (vec_select:V2SI
23139                        (match_operand:V4SI 1 "register_operand" "0")
23140                        (parallel [(const_int 0) (const_int 2)])))
23141                    (zero_extend:V2DI
23142                      (vec_select:V2SI
23143                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23144                        (parallel [(const_int 0) (const_int 2)])))))]
23145   "TARGET_SSE2"
23146   "pmuludq\t{%2, %0|%0, %2}"
23147   [(set_attr "type" "sseimul")
23148    (set_attr "mode" "TI")])
23149
23150 (define_insn "sse2_pmaddwd"
23151   [(set (match_operand:V4SI 0 "register_operand" "=x")
23152         (plus:V4SI
23153          (mult:V4SI
23154           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23155                                              (parallel [(const_int 0)
23156                                                         (const_int 2)
23157                                                         (const_int 4)
23158                                                         (const_int 6)])))
23159           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23160                                              (parallel [(const_int 0)
23161                                                         (const_int 2)
23162                                                         (const_int 4)
23163                                                         (const_int 6)]))))
23164          (mult:V4SI
23165           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23166                                              (parallel [(const_int 1)
23167                                                         (const_int 3)
23168                                                         (const_int 5)
23169                                                         (const_int 7)])))
23170           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23171                                              (parallel [(const_int 1)
23172                                                         (const_int 3)
23173                                                         (const_int 5)
23174                                                         (const_int 7)]))))))]
23175   "TARGET_SSE2"
23176   "pmaddwd\t{%2, %0|%0, %2}"
23177   [(set_attr "type" "sseiadd")
23178    (set_attr "mode" "TI")])
23179
23180 ;; Same as pxor, but don't show input operands so that we don't think
23181 ;; they are live.
23182 (define_insn "sse2_clrti"
23183   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23184   "TARGET_SSE2"
23185 {
23186   if (get_attr_mode (insn) == MODE_TI)
23187     return "pxor\t%0, %0";
23188   else
23189     return "xorps\t%0, %0";
23190 }
23191   [(set_attr "type" "ssemov")
23192    (set_attr "memory" "none")
23193    (set (attr "mode")
23194               (if_then_else
23195                 (ne (symbol_ref "optimize_size")
23196                     (const_int 0))
23197                 (const_string "V4SF")
23198                 (const_string "TI")))])
23199
23200 ;; MMX unsigned averages/sum of absolute differences
23201
23202 (define_insn "sse2_uavgv16qi3"
23203   [(set (match_operand:V16QI 0 "register_operand" "=x")
23204         (ashiftrt:V16QI
23205          (plus:V16QI (plus:V16QI
23206                      (match_operand:V16QI 1 "register_operand" "0")
23207                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23208                      (const_vector:V16QI [(const_int 1) (const_int 1)
23209                                           (const_int 1) (const_int 1)
23210                                           (const_int 1) (const_int 1)
23211                                           (const_int 1) (const_int 1)
23212                                           (const_int 1) (const_int 1)
23213                                           (const_int 1) (const_int 1)
23214                                           (const_int 1) (const_int 1)
23215                                           (const_int 1) (const_int 1)]))
23216          (const_int 1)))]
23217   "TARGET_SSE2"
23218   "pavgb\t{%2, %0|%0, %2}"
23219   [(set_attr "type" "sseiadd")
23220    (set_attr "mode" "TI")])
23221
23222 (define_insn "sse2_uavgv8hi3"
23223   [(set (match_operand:V8HI 0 "register_operand" "=x")
23224         (ashiftrt:V8HI
23225          (plus:V8HI (plus:V8HI
23226                      (match_operand:V8HI 1 "register_operand" "0")
23227                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23228                     (const_vector:V8HI [(const_int 1) (const_int 1)
23229                                         (const_int 1) (const_int 1)
23230                                         (const_int 1) (const_int 1)
23231                                         (const_int 1) (const_int 1)]))
23232          (const_int 1)))]
23233   "TARGET_SSE2"
23234   "pavgw\t{%2, %0|%0, %2}"
23235   [(set_attr "type" "sseiadd")
23236    (set_attr "mode" "TI")])
23237
23238 ;; @@@ this isn't the right representation.
23239 (define_insn "sse2_psadbw"
23240   [(set (match_operand:V2DI 0 "register_operand" "=x")
23241         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23242                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23243                      UNSPEC_PSADBW))]
23244   "TARGET_SSE2"
23245   "psadbw\t{%2, %0|%0, %2}"
23246   [(set_attr "type" "sseiadd")
23247    (set_attr "mode" "TI")])
23248
23249
23250 ;; MMX insert/extract/shuffle
23251
23252 (define_expand "sse2_pinsrw"
23253   [(set (match_operand:V8HI 0 "register_operand" "")
23254         (vec_merge:V8HI
23255           (match_operand:V8HI 1 "register_operand" "")
23256           (vec_duplicate:V8HI
23257             (match_operand:SI 2 "nonimmediate_operand" ""))
23258           (match_operand:SI 3 "const_0_to_7_operand" "")))]
23259   "TARGET_SSE2"
23260 {
23261   operands[2] = gen_lowpart (HImode, operands[2]);
23262   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
23263 })
23264
23265 (define_insn "*sse2_pinsrw"
23266   [(set (match_operand:V8HI 0 "register_operand" "=x")
23267         (vec_merge:V8HI
23268           (match_operand:V8HI 1 "register_operand" "0")
23269           (vec_duplicate:V8HI
23270             (match_operand:HI 2 "nonimmediate_operand" "rm"))
23271           (match_operand:SI 3 "const_pow2_1_to_128_operand" "N")))]
23272   "TARGET_SSE2"
23273 {
23274   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
23275   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
23276 }
23277   [(set_attr "type" "ssecvt")
23278    (set_attr "mode" "TI")])
23279
23280 (define_insn "sse2_pextrw"
23281   [(set (match_operand:SI 0 "register_operand" "=r")
23282         (zero_extend:SI
23283           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23284                          (parallel
23285                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23286   "TARGET_SSE2"
23287   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23288   [(set_attr "type" "ssecvt")
23289    (set_attr "mode" "TI")])
23290
23291 (define_insn "sse2_pshufd"
23292   [(set (match_operand:V4SI 0 "register_operand" "=x")
23293         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23294                       (match_operand:SI 2 "immediate_operand" "i")]
23295                      UNSPEC_SHUFFLE))]
23296   "TARGET_SSE2"
23297   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23298   [(set_attr "type" "ssecvt")
23299    (set_attr "mode" "TI")])
23300
23301 (define_insn "sse2_pshuflw"
23302   [(set (match_operand:V8HI 0 "register_operand" "=x")
23303         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23304                       (match_operand:SI 2 "immediate_operand" "i")]
23305                      UNSPEC_PSHUFLW))]
23306   "TARGET_SSE2"
23307   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23308   [(set_attr "type" "ssecvt")
23309    (set_attr "mode" "TI")])
23310
23311 (define_insn "sse2_pshufhw"
23312   [(set (match_operand:V8HI 0 "register_operand" "=x")
23313         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23314                       (match_operand:SI 2 "immediate_operand" "i")]
23315                      UNSPEC_PSHUFHW))]
23316   "TARGET_SSE2"
23317   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23318   [(set_attr "type" "ssecvt")
23319    (set_attr "mode" "TI")])
23320
23321 ;; MMX mask-generating comparisons
23322
23323 (define_insn "eqv16qi3"
23324   [(set (match_operand:V16QI 0 "register_operand" "=x")
23325         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23326                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23327   "TARGET_SSE2"
23328   "pcmpeqb\t{%2, %0|%0, %2}"
23329   [(set_attr "type" "ssecmp")
23330    (set_attr "mode" "TI")])
23331
23332 (define_insn "eqv8hi3"
23333   [(set (match_operand:V8HI 0 "register_operand" "=x")
23334         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23335                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23336   "TARGET_SSE2"
23337   "pcmpeqw\t{%2, %0|%0, %2}"
23338   [(set_attr "type" "ssecmp")
23339    (set_attr "mode" "TI")])
23340
23341 (define_insn "eqv4si3"
23342   [(set (match_operand:V4SI 0 "register_operand" "=x")
23343         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23344                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23345   "TARGET_SSE2"
23346   "pcmpeqd\t{%2, %0|%0, %2}"
23347   [(set_attr "type" "ssecmp")
23348    (set_attr "mode" "TI")])
23349
23350 (define_insn "gtv16qi3"
23351   [(set (match_operand:V16QI 0 "register_operand" "=x")
23352         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23353                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23354   "TARGET_SSE2"
23355   "pcmpgtb\t{%2, %0|%0, %2}"
23356   [(set_attr "type" "ssecmp")
23357    (set_attr "mode" "TI")])
23358
23359 (define_insn "gtv8hi3"
23360   [(set (match_operand:V8HI 0 "register_operand" "=x")
23361         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23362                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23363   "TARGET_SSE2"
23364   "pcmpgtw\t{%2, %0|%0, %2}"
23365   [(set_attr "type" "ssecmp")
23366    (set_attr "mode" "TI")])
23367
23368 (define_insn "gtv4si3"
23369   [(set (match_operand:V4SI 0 "register_operand" "=x")
23370         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23371                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23372   "TARGET_SSE2"
23373   "pcmpgtd\t{%2, %0|%0, %2}"
23374   [(set_attr "type" "ssecmp")
23375    (set_attr "mode" "TI")])
23376
23377
23378 ;; MMX max/min insns
23379
23380 (define_insn "umaxv16qi3"
23381   [(set (match_operand:V16QI 0 "register_operand" "=x")
23382         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23383                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23384   "TARGET_SSE2"
23385   "pmaxub\t{%2, %0|%0, %2}"
23386   [(set_attr "type" "sseiadd")
23387    (set_attr "mode" "TI")])
23388
23389 (define_insn "smaxv8hi3"
23390   [(set (match_operand:V8HI 0 "register_operand" "=x")
23391         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23392                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23393   "TARGET_SSE2"
23394   "pmaxsw\t{%2, %0|%0, %2}"
23395   [(set_attr "type" "sseiadd")
23396    (set_attr "mode" "TI")])
23397
23398 (define_insn "uminv16qi3"
23399   [(set (match_operand:V16QI 0 "register_operand" "=x")
23400         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23401                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23402   "TARGET_SSE2"
23403   "pminub\t{%2, %0|%0, %2}"
23404   [(set_attr "type" "sseiadd")
23405    (set_attr "mode" "TI")])
23406
23407 (define_insn "sminv8hi3"
23408   [(set (match_operand:V8HI 0 "register_operand" "=x")
23409         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23410                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23411   "TARGET_SSE2"
23412   "pminsw\t{%2, %0|%0, %2}"
23413   [(set_attr "type" "sseiadd")
23414    (set_attr "mode" "TI")])
23415
23416
23417 ;; MMX shifts
23418
23419 (define_insn "ashrv8hi3"
23420   [(set (match_operand:V8HI 0 "register_operand" "=x")
23421         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23422                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23423   "TARGET_SSE2"
23424   "psraw\t{%2, %0|%0, %2}"
23425   [(set_attr "type" "sseishft")
23426    (set_attr "mode" "TI")])
23427
23428 (define_insn "ashrv4si3"
23429   [(set (match_operand:V4SI 0 "register_operand" "=x")
23430         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23431                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23432   "TARGET_SSE2"
23433   "psrad\t{%2, %0|%0, %2}"
23434   [(set_attr "type" "sseishft")
23435    (set_attr "mode" "TI")])
23436
23437 (define_insn "lshrv8hi3"
23438   [(set (match_operand:V8HI 0 "register_operand" "=x")
23439         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23440                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23441   "TARGET_SSE2"
23442   "psrlw\t{%2, %0|%0, %2}"
23443   [(set_attr "type" "sseishft")
23444    (set_attr "mode" "TI")])
23445
23446 (define_insn "lshrv4si3"
23447   [(set (match_operand:V4SI 0 "register_operand" "=x")
23448         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23449                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23450   "TARGET_SSE2"
23451   "psrld\t{%2, %0|%0, %2}"
23452   [(set_attr "type" "sseishft")
23453    (set_attr "mode" "TI")])
23454
23455 (define_insn "lshrv2di3"
23456   [(set (match_operand:V2DI 0 "register_operand" "=x")
23457         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23458                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23459   "TARGET_SSE2"
23460   "psrlq\t{%2, %0|%0, %2}"
23461   [(set_attr "type" "sseishft")
23462    (set_attr "mode" "TI")])
23463
23464 (define_insn "ashlv8hi3"
23465   [(set (match_operand:V8HI 0 "register_operand" "=x")
23466         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23467                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23468   "TARGET_SSE2"
23469   "psllw\t{%2, %0|%0, %2}"
23470   [(set_attr "type" "sseishft")
23471    (set_attr "mode" "TI")])
23472
23473 (define_insn "ashlv4si3"
23474   [(set (match_operand:V4SI 0 "register_operand" "=x")
23475         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23476                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23477   "TARGET_SSE2"
23478   "pslld\t{%2, %0|%0, %2}"
23479   [(set_attr "type" "sseishft")
23480    (set_attr "mode" "TI")])
23481
23482 (define_insn "ashlv2di3"
23483   [(set (match_operand:V2DI 0 "register_operand" "=x")
23484         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23485                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23486   "TARGET_SSE2"
23487   "psllq\t{%2, %0|%0, %2}"
23488   [(set_attr "type" "sseishft")
23489    (set_attr "mode" "TI")])
23490
23491 (define_insn "ashrv8hi3_ti"
23492   [(set (match_operand:V8HI 0 "register_operand" "=x")
23493         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23494                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23495   "TARGET_SSE2"
23496   "psraw\t{%2, %0|%0, %2}"
23497   [(set_attr "type" "sseishft")
23498    (set_attr "mode" "TI")])
23499
23500 (define_insn "ashrv4si3_ti"
23501   [(set (match_operand:V4SI 0 "register_operand" "=x")
23502         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23503                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23504   "TARGET_SSE2"
23505   "psrad\t{%2, %0|%0, %2}"
23506   [(set_attr "type" "sseishft")
23507    (set_attr "mode" "TI")])
23508
23509 (define_insn "lshrv8hi3_ti"
23510   [(set (match_operand:V8HI 0 "register_operand" "=x")
23511         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23512                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23513   "TARGET_SSE2"
23514   "psrlw\t{%2, %0|%0, %2}"
23515   [(set_attr "type" "sseishft")
23516    (set_attr "mode" "TI")])
23517
23518 (define_insn "lshrv4si3_ti"
23519   [(set (match_operand:V4SI 0 "register_operand" "=x")
23520         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23521                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23522   "TARGET_SSE2"
23523   "psrld\t{%2, %0|%0, %2}"
23524   [(set_attr "type" "sseishft")
23525    (set_attr "mode" "TI")])
23526
23527 (define_insn "lshrv2di3_ti"
23528   [(set (match_operand:V2DI 0 "register_operand" "=x")
23529         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23530                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23531   "TARGET_SSE2"
23532   "psrlq\t{%2, %0|%0, %2}"
23533   [(set_attr "type" "sseishft")
23534    (set_attr "mode" "TI")])
23535
23536 (define_insn "ashlv8hi3_ti"
23537   [(set (match_operand:V8HI 0 "register_operand" "=x")
23538         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23539                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23540   "TARGET_SSE2"
23541   "psllw\t{%2, %0|%0, %2}"
23542   [(set_attr "type" "sseishft")
23543    (set_attr "mode" "TI")])
23544
23545 (define_insn "ashlv4si3_ti"
23546   [(set (match_operand:V4SI 0 "register_operand" "=x")
23547         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23548                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23549   "TARGET_SSE2"
23550   "pslld\t{%2, %0|%0, %2}"
23551   [(set_attr "type" "sseishft")
23552    (set_attr "mode" "TI")])
23553
23554 (define_insn "ashlv2di3_ti"
23555   [(set (match_operand:V2DI 0 "register_operand" "=x")
23556         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23557                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23558   "TARGET_SSE2"
23559   "psllq\t{%2, %0|%0, %2}"
23560   [(set_attr "type" "sseishft")
23561    (set_attr "mode" "TI")])
23562
23563 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23564 ;; we wouldn't need here it since we never generate TImode arithmetic.
23565
23566 ;; There has to be some kind of prize for the weirdest new instruction...
23567 (define_insn "sse2_ashlti3"
23568   [(set (match_operand:TI 0 "register_operand" "=x")
23569         (unspec:TI
23570          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23571                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23572                                (const_int 8)))] UNSPEC_NOP))]
23573   "TARGET_SSE2"
23574   "pslldq\t{%2, %0|%0, %2}"
23575   [(set_attr "type" "sseishft")
23576    (set_attr "mode" "TI")])
23577
23578 (define_insn "sse2_lshrti3"
23579   [(set (match_operand:TI 0 "register_operand" "=x")
23580         (unspec:TI
23581          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23582                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23583                                 (const_int 8)))] UNSPEC_NOP))]
23584   "TARGET_SSE2"
23585   "psrldq\t{%2, %0|%0, %2}"
23586   [(set_attr "type" "sseishft")
23587    (set_attr "mode" "TI")])
23588
23589 ;; SSE unpack
23590
23591 (define_insn "sse2_unpckhpd"
23592   [(set (match_operand:V2DF 0 "register_operand" "=x")
23593         (vec_concat:V2DF
23594          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23595                         (parallel [(const_int 1)]))
23596          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23597                         (parallel [(const_int 1)]))))]
23598   "TARGET_SSE2"
23599   "unpckhpd\t{%2, %0|%0, %2}"
23600   [(set_attr "type" "ssecvt")
23601    (set_attr "mode" "V2DF")])
23602
23603 (define_insn "sse2_unpcklpd"
23604   [(set (match_operand:V2DF 0 "register_operand" "=x")
23605         (vec_concat:V2DF
23606          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23607                         (parallel [(const_int 0)]))
23608          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23609                         (parallel [(const_int 0)]))))]
23610   "TARGET_SSE2"
23611   "unpcklpd\t{%2, %0|%0, %2}"
23612   [(set_attr "type" "ssecvt")
23613    (set_attr "mode" "V2DF")])
23614
23615 ;; MMX pack/unpack insns.
23616
23617 (define_insn "sse2_packsswb"
23618   [(set (match_operand:V16QI 0 "register_operand" "=x")
23619         (vec_concat:V16QI
23620          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23621          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23622   "TARGET_SSE2"
23623   "packsswb\t{%2, %0|%0, %2}"
23624   [(set_attr "type" "ssecvt")
23625    (set_attr "mode" "TI")])
23626
23627 (define_insn "sse2_packssdw"
23628   [(set (match_operand:V8HI 0 "register_operand" "=x")
23629         (vec_concat:V8HI
23630          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23631          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23632   "TARGET_SSE2"
23633   "packssdw\t{%2, %0|%0, %2}"
23634   [(set_attr "type" "ssecvt")
23635    (set_attr "mode" "TI")])
23636
23637 (define_insn "sse2_packuswb"
23638   [(set (match_operand:V16QI 0 "register_operand" "=x")
23639         (vec_concat:V16QI
23640          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23641          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23642   "TARGET_SSE2"
23643   "packuswb\t{%2, %0|%0, %2}"
23644   [(set_attr "type" "ssecvt")
23645    (set_attr "mode" "TI")])
23646
23647 (define_insn "sse2_punpckhbw"
23648   [(set (match_operand:V16QI 0 "register_operand" "=x")
23649         (vec_merge:V16QI
23650          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23651                            (parallel [(const_int 8) (const_int 0)
23652                                       (const_int 9) (const_int 1)
23653                                       (const_int 10) (const_int 2)
23654                                       (const_int 11) (const_int 3)
23655                                       (const_int 12) (const_int 4)
23656                                       (const_int 13) (const_int 5)
23657                                       (const_int 14) (const_int 6)
23658                                       (const_int 15) (const_int 7)]))
23659          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23660                            (parallel [(const_int 0) (const_int 8)
23661                                       (const_int 1) (const_int 9)
23662                                       (const_int 2) (const_int 10)
23663                                       (const_int 3) (const_int 11)
23664                                       (const_int 4) (const_int 12)
23665                                       (const_int 5) (const_int 13)
23666                                       (const_int 6) (const_int 14)
23667                                       (const_int 7) (const_int 15)]))
23668          (const_int 21845)))]
23669   "TARGET_SSE2"
23670   "punpckhbw\t{%2, %0|%0, %2}"
23671   [(set_attr "type" "ssecvt")
23672    (set_attr "mode" "TI")])
23673
23674 (define_insn "sse2_punpckhwd"
23675   [(set (match_operand:V8HI 0 "register_operand" "=x")
23676         (vec_merge:V8HI
23677          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23678                           (parallel [(const_int 4) (const_int 0)
23679                                      (const_int 5) (const_int 1)
23680                                      (const_int 6) (const_int 2)
23681                                      (const_int 7) (const_int 3)]))
23682          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23683                           (parallel [(const_int 0) (const_int 4)
23684                                      (const_int 1) (const_int 5)
23685                                      (const_int 2) (const_int 6)
23686                                      (const_int 3) (const_int 7)]))
23687          (const_int 85)))]
23688   "TARGET_SSE2"
23689   "punpckhwd\t{%2, %0|%0, %2}"
23690   [(set_attr "type" "ssecvt")
23691    (set_attr "mode" "TI")])
23692
23693 (define_insn "sse2_punpckhdq"
23694   [(set (match_operand:V4SI 0 "register_operand" "=x")
23695         (vec_merge:V4SI
23696          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23697                           (parallel [(const_int 2) (const_int 0)
23698                                      (const_int 3) (const_int 1)]))
23699          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23700                           (parallel [(const_int 0) (const_int 2)
23701                                      (const_int 1) (const_int 3)]))
23702          (const_int 5)))]
23703   "TARGET_SSE2"
23704   "punpckhdq\t{%2, %0|%0, %2}"
23705   [(set_attr "type" "ssecvt")
23706    (set_attr "mode" "TI")])
23707
23708 (define_insn "sse2_punpcklbw"
23709   [(set (match_operand:V16QI 0 "register_operand" "=x")
23710         (vec_merge:V16QI
23711          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23712                            (parallel [(const_int 0) (const_int 8)
23713                                       (const_int 1) (const_int 9)
23714                                       (const_int 2) (const_int 10)
23715                                       (const_int 3) (const_int 11)
23716                                       (const_int 4) (const_int 12)
23717                                       (const_int 5) (const_int 13)
23718                                       (const_int 6) (const_int 14)
23719                                       (const_int 7) (const_int 15)]))
23720          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23721                            (parallel [(const_int 8) (const_int 0)
23722                                       (const_int 9) (const_int 1)
23723                                       (const_int 10) (const_int 2)
23724                                       (const_int 11) (const_int 3)
23725                                       (const_int 12) (const_int 4)
23726                                       (const_int 13) (const_int 5)
23727                                       (const_int 14) (const_int 6)
23728                                       (const_int 15) (const_int 7)]))
23729          (const_int 21845)))]
23730   "TARGET_SSE2"
23731   "punpcklbw\t{%2, %0|%0, %2}"
23732   [(set_attr "type" "ssecvt")
23733    (set_attr "mode" "TI")])
23734
23735 (define_insn "sse2_punpcklwd"
23736   [(set (match_operand:V8HI 0 "register_operand" "=x")
23737         (vec_merge:V8HI
23738          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23739                           (parallel [(const_int 0) (const_int 4)
23740                                      (const_int 1) (const_int 5)
23741                                      (const_int 2) (const_int 6)
23742                                      (const_int 3) (const_int 7)]))
23743          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23744                           (parallel [(const_int 4) (const_int 0)
23745                                      (const_int 5) (const_int 1)
23746                                      (const_int 6) (const_int 2)
23747                                      (const_int 7) (const_int 3)]))
23748          (const_int 85)))]
23749   "TARGET_SSE2"
23750   "punpcklwd\t{%2, %0|%0, %2}"
23751   [(set_attr "type" "ssecvt")
23752    (set_attr "mode" "TI")])
23753
23754 (define_insn "sse2_punpckldq"
23755   [(set (match_operand:V4SI 0 "register_operand" "=x")
23756         (vec_merge:V4SI
23757          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23758                           (parallel [(const_int 0) (const_int 2)
23759                                      (const_int 1) (const_int 3)]))
23760          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23761                           (parallel [(const_int 2) (const_int 0)
23762                                      (const_int 3) (const_int 1)]))
23763          (const_int 5)))]
23764   "TARGET_SSE2"
23765   "punpckldq\t{%2, %0|%0, %2}"
23766   [(set_attr "type" "ssecvt")
23767    (set_attr "mode" "TI")])
23768
23769 (define_insn "sse2_punpcklqdq"
23770   [(set (match_operand:V2DI 0 "register_operand" "=x")
23771         (vec_merge:V2DI
23772          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23773                           (parallel [(const_int 1)
23774                                      (const_int 0)]))
23775          (match_operand:V2DI 1 "register_operand" "0")
23776          (const_int 1)))]
23777   "TARGET_SSE2"
23778   "punpcklqdq\t{%2, %0|%0, %2}"
23779   [(set_attr "type" "ssecvt")
23780    (set_attr "mode" "TI")])
23781
23782 (define_insn "sse2_punpckhqdq"
23783   [(set (match_operand:V2DI 0 "register_operand" "=x")
23784         (vec_merge:V2DI
23785          (match_operand:V2DI 1 "register_operand" "0")
23786          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23787                           (parallel [(const_int 1)
23788                                      (const_int 0)]))
23789          (const_int 1)))]
23790   "TARGET_SSE2"
23791   "punpckhqdq\t{%2, %0|%0, %2}"
23792   [(set_attr "type" "ssecvt")
23793    (set_attr "mode" "TI")])
23794
23795 ;; SSE2 moves
23796
23797 (define_insn "sse2_movapd"
23798   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23799         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23800                      UNSPEC_MOVA))]
23801   "TARGET_SSE2
23802    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23803   "movapd\t{%1, %0|%0, %1}"
23804   [(set_attr "type" "ssemov")
23805    (set_attr "mode" "V2DF")])
23806
23807 (define_insn "sse2_movupd"
23808   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23809         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23810                      UNSPEC_MOVU))]
23811   "TARGET_SSE2
23812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23813   "movupd\t{%1, %0|%0, %1}"
23814   [(set_attr "type" "ssecvt")
23815    (set_attr "mode" "V2DF")])
23816
23817 (define_insn "sse2_movdqa"
23818   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23819         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23820                        UNSPEC_MOVA))]
23821   "TARGET_SSE2
23822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23823   "movdqa\t{%1, %0|%0, %1}"
23824   [(set_attr "type" "ssemov")
23825    (set_attr "mode" "TI")])
23826
23827 (define_insn "sse2_movdqu"
23828   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23829         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23830                        UNSPEC_MOVU))]
23831   "TARGET_SSE2
23832    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23833   "movdqu\t{%1, %0|%0, %1}"
23834   [(set_attr "type" "ssecvt")
23835    (set_attr "mode" "TI")])
23836
23837 (define_insn "sse2_movdq2q"
23838   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23839         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23840                        (parallel [(const_int 0)])))]
23841   "TARGET_SSE2 && !TARGET_64BIT"
23842   "@
23843    movq\t{%1, %0|%0, %1}
23844    movdq2q\t{%1, %0|%0, %1}"
23845   [(set_attr "type" "ssecvt")
23846    (set_attr "mode" "TI")])
23847
23848 (define_insn "sse2_movdq2q_rex64"
23849   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23850         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23851                        (parallel [(const_int 0)])))]
23852   "TARGET_SSE2 && TARGET_64BIT"
23853   "@
23854    movq\t{%1, %0|%0, %1}
23855    movdq2q\t{%1, %0|%0, %1}
23856    movd\t{%1, %0|%0, %1}"
23857   [(set_attr "type" "ssecvt")
23858    (set_attr "mode" "TI")])
23859
23860 (define_insn "sse2_movq2dq"
23861   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23862         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23863                          (const_int 0)))]
23864   "TARGET_SSE2 && !TARGET_64BIT"
23865   "@
23866    movq\t{%1, %0|%0, %1}
23867    movq2dq\t{%1, %0|%0, %1}"
23868   [(set_attr "type" "ssecvt,ssemov")
23869    (set_attr "mode" "TI")])
23870
23871 (define_insn "sse2_movq2dq_rex64"
23872   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23873         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23874                          (const_int 0)))]
23875   "TARGET_SSE2 && TARGET_64BIT"
23876   "@
23877    movq\t{%1, %0|%0, %1}
23878    movq2dq\t{%1, %0|%0, %1}
23879    movd\t{%1, %0|%0, %1}"
23880   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23881    (set_attr "mode" "TI")])
23882
23883 (define_insn "sse2_movq"
23884   [(set (match_operand:V2DI 0 "register_operand" "=x")
23885         (vec_concat:V2DI (vec_select:DI
23886                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23887                           (parallel [(const_int 0)]))
23888                          (const_int 0)))]
23889   "TARGET_SSE2"
23890   "movq\t{%1, %0|%0, %1}"
23891   [(set_attr "type" "ssemov")
23892    (set_attr "mode" "TI")])
23893
23894 (define_insn "sse2_loadd"
23895   [(set (match_operand:V4SI 0 "register_operand" "=x")
23896         (vec_merge:V4SI
23897          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23898          (const_vector:V4SI [(const_int 0)
23899                              (const_int 0)
23900                              (const_int 0)
23901                              (const_int 0)])
23902          (const_int 1)))]
23903   "TARGET_SSE2"
23904   "movd\t{%1, %0|%0, %1}"
23905   [(set_attr "type" "ssemov")
23906    (set_attr "mode" "TI")])
23907
23908 (define_insn "sse2_stored"
23909   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23910         (vec_select:SI
23911          (match_operand:V4SI 1 "register_operand" "x")
23912          (parallel [(const_int 0)])))]
23913   "TARGET_SSE2"
23914   "movd\t{%1, %0|%0, %1}"
23915   [(set_attr "type" "ssemov")
23916    (set_attr "mode" "TI")])
23917
23918 ;; Store the high double of the source vector into the double destination.
23919 (define_insn "sse2_storehpd"
23920   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,Y,Y")
23921         (vec_select:DF
23922           (match_operand:V2DF 1 "nonimmediate_operand" " Y,0,o")
23923           (parallel [(const_int 1)])))]
23924   "TARGET_SSE2"
23925   "@
23926    movhpd\t{%1, %0|%0, %1}
23927    unpckhpd\t%0, %0
23928    #"
23929   [(set_attr "type" "ssecvt")
23930    (set_attr "mode" "V2DF")])
23931
23932 (define_split
23933   [(set (match_operand:DF 0 "register_operand" "")
23934         (vec_select:DF
23935           (match_operand:V2DF 1 "memory_operand" "")
23936           (parallel [(const_int 1)])))]
23937   "TARGET_SSE2 && reload_completed"
23938   [(const_int 0)]
23939 {
23940   emit_move_insn (operands[0], adjust_address (operands[1], DFmode, 8));
23941   DONE;
23942 })
23943
23944 ;; Load the high double of the target vector from the source scalar.
23945 (define_insn "sse2_loadhpd"
23946   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=Y,Y,o")
23947         (vec_concat:V2DF
23948           (vec_select:DF
23949             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
23950             (parallel [(const_int 0)]))
23951           (match_operand:DF 2 "nonimmediate_operand"     " m,Y,Y")))]
23952   "TARGET_SSE2"
23953   "@
23954    movhpd\t{%2, %0|%0, %2}
23955    unpcklpd\t{%2, %0|%0, %2}
23956    #"
23957   [(set_attr "type" "ssecvt")
23958    (set_attr "mode" "V2DF")])
23959
23960 (define_split
23961   [(set (match_operand:V2DF 0 "memory_operand" "")
23962         (vec_concat:V2DF
23963           (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
23964           (match_operand:DF 1 "register_operand" "")))]
23965   "TARGET_SSE2 && reload_completed"
23966   [(const_int 0)]
23967 {
23968   emit_move_insn (adjust_address (operands[0], DFmode, 8), operands[1]);
23969   DONE;
23970 })
23971
23972 ;; Store the low double of the source vector into the double destination.
23973 (define_expand "sse2_storelpd"
23974   [(set (match_operand:DF 0 "nonimmediate_operand" "")
23975         (vec_select:DF
23976           (match_operand:V2DF 1 "nonimmediate_operand" "")
23977           (parallel [(const_int 0)])))]
23978   "TARGET_SSE2"
23979 {
23980   operands[1] = gen_lowpart (DFmode, operands[1]);
23981   emit_move_insn (operands[0], operands[1]);
23982   DONE;
23983 })
23984
23985 ;; Load the low double of the target vector from the source scalar.
23986 (define_insn "sse2_loadlpd"
23987   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=Y,Y,m")
23988         (vec_concat:V2DF
23989           (match_operand:DF 2 "nonimmediate_operand"     " m,Y,Y")
23990           (vec_select:DF
23991             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
23992             (parallel [(const_int 1)]))))]
23993   "TARGET_SSE2"
23994   "@
23995    movlpd\t{%2, %0|%0, %2}
23996    movsd\t{%2, %0|%0, %2}
23997    movlpd\t{%2, %0|%0, %2}"
23998   [(set_attr "type" "ssecvt")
23999    (set_attr "mode" "V2DF")])
24000
24001 ;; Merge the low part of the source vector into the low part of the target.
24002 (define_insn "sse2_movsd"
24003   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=Y,Y,m")
24004         (vec_merge:V2DF
24005          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24006          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,Y")
24007          (const_int 2)))]
24008   "TARGET_SSE2"
24009   "@movsd\t{%2, %0|%0, %2}
24010     movlpd\t{%2, %0|%0, %2}
24011     movlpd\t{%2, %0|%0, %2}"
24012   [(set_attr "type" "ssecvt")
24013    (set_attr "mode" "DF,V2DF,V2DF")])
24014
24015 (define_expand "sse2_loadsd"
24016   [(match_operand:V2DF 0 "register_operand" "")
24017    (match_operand:DF 1 "memory_operand" "")]
24018   "TARGET_SSE2"
24019 {
24020   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24021                                 CONST0_RTX (V2DFmode)));
24022   DONE;
24023 })
24024
24025 (define_insn "sse2_loadsd_1"
24026   [(set (match_operand:V2DF 0 "register_operand" "=x")
24027         (vec_merge:V2DF
24028          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24029          (match_operand:V2DF 2 "const0_operand" "X")
24030          (const_int 1)))]
24031   "TARGET_SSE2"
24032   "movsd\t{%1, %0|%0, %1}"
24033   [(set_attr "type" "ssecvt")
24034    (set_attr "mode" "DF")])
24035
24036 (define_insn "sse2_storesd"
24037   [(set (match_operand:DF 0 "memory_operand" "=m")
24038         (vec_select:DF
24039          (match_operand:V2DF 1 "register_operand" "x")
24040          (parallel [(const_int 0)])))]
24041   "TARGET_SSE2"
24042   "movsd\t{%1, %0|%0, %1}"
24043   [(set_attr "type" "ssecvt")
24044    (set_attr "mode" "DF")])
24045
24046 (define_insn "sse2_shufpd"
24047   [(set (match_operand:V2DF 0 "register_operand" "=x")
24048         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24049                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24050                       (match_operand:SI 3 "immediate_operand" "i")]
24051                      UNSPEC_SHUFFLE))]
24052   "TARGET_SSE2"
24053   ;; @@@ check operand order for intel/nonintel syntax
24054   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24055   [(set_attr "type" "ssecvt")
24056    (set_attr "mode" "V2DF")])
24057
24058 (define_insn "sse2_clflush"
24059   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24060                     UNSPECV_CLFLUSH)]
24061   "TARGET_SSE2"
24062   "clflush\t%a0"
24063   [(set_attr "type" "sse")
24064    (set_attr "memory" "unknown")])
24065
24066 (define_expand "sse2_mfence"
24067   [(set (match_dup 0)
24068         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24069   "TARGET_SSE2"
24070 {
24071   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24072   MEM_VOLATILE_P (operands[0]) = 1;
24073 })
24074
24075 (define_insn "*mfence_insn"
24076   [(set (match_operand:BLK 0 "" "")
24077         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24078   "TARGET_SSE2"
24079   "mfence"
24080   [(set_attr "type" "sse")
24081    (set_attr "memory" "unknown")])
24082
24083 (define_expand "sse2_lfence"
24084   [(set (match_dup 0)
24085         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24086   "TARGET_SSE2"
24087 {
24088   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24089   MEM_VOLATILE_P (operands[0]) = 1;
24090 })
24091
24092 (define_insn "*lfence_insn"
24093   [(set (match_operand:BLK 0 "" "")
24094         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24095   "TARGET_SSE2"
24096   "lfence"
24097   [(set_attr "type" "sse")
24098    (set_attr "memory" "unknown")])
24099
24100 ;; SSE3
24101
24102 (define_insn "mwait"
24103   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24104                      (match_operand:SI 1 "register_operand" "c")]
24105                     UNSPECV_MWAIT)]
24106   "TARGET_SSE3"
24107   "mwait\t%0, %1"
24108   [(set_attr "length" "3")])
24109
24110 (define_insn "monitor"
24111   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24112                      (match_operand:SI 1 "register_operand" "c")
24113                      (match_operand:SI 2 "register_operand" "d")]
24114                     UNSPECV_MONITOR)]
24115   "TARGET_SSE3"
24116   "monitor\t%0, %1, %2"
24117   [(set_attr "length" "3")])
24118
24119 ;; SSE3 arithmetic
24120
24121 (define_insn "addsubv4sf3"
24122   [(set (match_operand:V4SF 0 "register_operand" "=x")
24123         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24124                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24125                      UNSPEC_ADDSUB))]
24126   "TARGET_SSE3"
24127   "addsubps\t{%2, %0|%0, %2}"
24128   [(set_attr "type" "sseadd")
24129    (set_attr "mode" "V4SF")])
24130
24131 (define_insn "addsubv2df3"
24132   [(set (match_operand:V2DF 0 "register_operand" "=x")
24133         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24134                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24135                      UNSPEC_ADDSUB))]
24136   "TARGET_SSE3"
24137   "addsubpd\t{%2, %0|%0, %2}"
24138   [(set_attr "type" "sseadd")
24139    (set_attr "mode" "V2DF")])
24140
24141 (define_insn "haddv4sf3"
24142   [(set (match_operand:V4SF 0 "register_operand" "=x")
24143         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24144                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24145                      UNSPEC_HADD))]
24146   "TARGET_SSE3"
24147   "haddps\t{%2, %0|%0, %2}"
24148   [(set_attr "type" "sseadd")
24149    (set_attr "mode" "V4SF")])
24150
24151 (define_insn "haddv2df3"
24152   [(set (match_operand:V2DF 0 "register_operand" "=x")
24153         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24154                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24155                      UNSPEC_HADD))]
24156   "TARGET_SSE3"
24157   "haddpd\t{%2, %0|%0, %2}"
24158   [(set_attr "type" "sseadd")
24159    (set_attr "mode" "V2DF")])
24160
24161 (define_insn "hsubv4sf3"
24162   [(set (match_operand:V4SF 0 "register_operand" "=x")
24163         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24164                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24165                      UNSPEC_HSUB))]
24166   "TARGET_SSE3"
24167   "hsubps\t{%2, %0|%0, %2}"
24168   [(set_attr "type" "sseadd")
24169    (set_attr "mode" "V4SF")])
24170
24171 (define_insn "hsubv2df3"
24172   [(set (match_operand:V2DF 0 "register_operand" "=x")
24173         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24174                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24175                      UNSPEC_HSUB))]
24176   "TARGET_SSE3"
24177   "hsubpd\t{%2, %0|%0, %2}"
24178   [(set_attr "type" "sseadd")
24179    (set_attr "mode" "V2DF")])
24180
24181 (define_insn "movshdup"
24182   [(set (match_operand:V4SF 0 "register_operand" "=x")
24183         (unspec:V4SF
24184          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24185   "TARGET_SSE3"
24186   "movshdup\t{%1, %0|%0, %1}"
24187   [(set_attr "type" "sse")
24188    (set_attr "mode" "V4SF")])
24189
24190 (define_insn "movsldup"
24191   [(set (match_operand:V4SF 0 "register_operand" "=x")
24192         (unspec:V4SF
24193          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24194   "TARGET_SSE3"
24195   "movsldup\t{%1, %0|%0, %1}"
24196   [(set_attr "type" "sse")
24197    (set_attr "mode" "V4SF")])
24198
24199 (define_insn "lddqu"
24200   [(set (match_operand:V16QI 0 "register_operand" "=x")
24201         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24202                        UNSPEC_LDQQU))]
24203   "TARGET_SSE3"
24204   "lddqu\t{%1, %0|%0, %1}"
24205   [(set_attr "type" "ssecvt")
24206    (set_attr "mode" "TI")])
24207
24208 (define_insn "loadddup"
24209   [(set (match_operand:V2DF 0 "register_operand" "=x")
24210         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24211   "TARGET_SSE3"
24212   "movddup\t{%1, %0|%0, %1}"
24213   [(set_attr "type" "ssecvt")
24214    (set_attr "mode" "DF")])
24215
24216 (define_insn "movddup"
24217   [(set (match_operand:V2DF 0 "register_operand" "=x")
24218         (vec_duplicate:V2DF
24219          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24220                         (parallel [(const_int 0)]))))]
24221   "TARGET_SSE3"
24222   "movddup\t{%1, %0|%0, %1}"
24223   [(set_attr "type" "ssecvt")
24224    (set_attr "mode" "DF")])