OSDN Git Service

PR target/19028
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1108  
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1116 {
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1126         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1127   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1128    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1129 {
1130   switch (get_attr_type (insn))
1131     {
1132     case TYPE_SSEMOV:
1133       if (get_attr_mode (insn) == MODE_TI)
1134         return "movdqa\t{%1, %0|%0, %1}";
1135       return "movd\t{%1, %0|%0, %1}";
1136
1137     case TYPE_MMXMOV:
1138       if (get_attr_mode (insn) == MODE_DI)
1139         return "movq\t{%1, %0|%0, %1}";
1140       return "movd\t{%1, %0|%0, %1}";
1141
1142     case TYPE_LEA:
1143       return "lea{l}\t{%1, %0|%0, %1}";
1144
1145     default:
1146       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1147         abort();
1148       return "mov{l}\t{%1, %0|%0, %1}";
1149     }
1150 }
1151   [(set (attr "type")
1152      (cond [(eq_attr "alternative" "2,3,4")
1153               (const_string "mmxmov")
1154             (eq_attr "alternative" "5,6,7")
1155               (const_string "ssemov")
1156             (and (ne (symbol_ref "flag_pic") (const_int 0))
1157                  (match_operand:SI 1 "symbolic_operand" ""))
1158               (const_string "lea")
1159            ]
1160            (const_string "imov")))
1161    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1162
1163 (define_insn "*movsi_1_nointernunit"
1164   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1165         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1166   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1168 {
1169   switch (get_attr_type (insn))
1170     {
1171     case TYPE_SSEMOV:
1172       if (get_attr_mode (insn) == MODE_TI)
1173         return "movdqa\t{%1, %0|%0, %1}";
1174       return "movd\t{%1, %0|%0, %1}";
1175
1176     case TYPE_MMXMOV:
1177       if (get_attr_mode (insn) == MODE_DI)
1178         return "movq\t{%1, %0|%0, %1}";
1179       return "movd\t{%1, %0|%0, %1}";
1180
1181     case TYPE_LEA:
1182       return "lea{l}\t{%1, %0|%0, %1}";
1183
1184     default:
1185       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1186         abort();
1187       return "mov{l}\t{%1, %0|%0, %1}";
1188     }
1189 }
1190   [(set (attr "type")
1191      (cond [(eq_attr "alternative" "2,3,4")
1192               (const_string "mmxmov")
1193             (eq_attr "alternative" "5,6,7")
1194               (const_string "ssemov")
1195             (and (ne (symbol_ref "flag_pic") (const_int 0))
1196                  (match_operand:SI 1 "symbolic_operand" ""))
1197               (const_string "lea")
1198            ]
1199            (const_string "imov")))
1200    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1201
1202 ;; Stores and loads of ax to arbitrary constant address.
1203 ;; We fake an second form of instruction to force reload to load address
1204 ;; into register when rax is not available
1205 (define_insn "*movabssi_1_rex64"
1206   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1207         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1208   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1209   "@
1210    movabs{l}\t{%1, %P0|%P0, %1}
1211    mov{l}\t{%1, %a0|%a0, %1}"
1212   [(set_attr "type" "imov")
1213    (set_attr "modrm" "0,*")
1214    (set_attr "length_address" "8,0")
1215    (set_attr "length_immediate" "0,*")
1216    (set_attr "memory" "store")
1217    (set_attr "mode" "SI")])
1218
1219 (define_insn "*movabssi_2_rex64"
1220   [(set (match_operand:SI 0 "register_operand" "=a,r")
1221         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1222   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1223   "@
1224    movabs{l}\t{%P1, %0|%0, %P1}
1225    mov{l}\t{%a1, %0|%0, %a1}"
1226   [(set_attr "type" "imov")
1227    (set_attr "modrm" "0,*")
1228    (set_attr "length_address" "8,0")
1229    (set_attr "length_immediate" "0")
1230    (set_attr "memory" "load")
1231    (set_attr "mode" "SI")])
1232
1233 (define_insn "*swapsi"
1234   [(set (match_operand:SI 0 "register_operand" "+r")
1235         (match_operand:SI 1 "register_operand" "+r"))
1236    (set (match_dup 1)
1237         (match_dup 0))]
1238   ""
1239   "xchg{l}\t%1, %0"
1240   [(set_attr "type" "imov")
1241    (set_attr "mode" "SI")
1242    (set_attr "pent_pair" "np")
1243    (set_attr "athlon_decode" "vector")])
1244
1245 (define_expand "movhi"
1246   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1247         (match_operand:HI 1 "general_operand" ""))]
1248   ""
1249   "ix86_expand_move (HImode, operands); DONE;")
1250
1251 (define_insn "*pushhi2"
1252   [(set (match_operand:HI 0 "push_operand" "=<,<")
1253         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1254   "!TARGET_64BIT"
1255   "@
1256    push{w}\t{|WORD PTR }%1
1257    push{w}\t%1"
1258   [(set_attr "type" "push")
1259    (set_attr "mode" "HI")])
1260
1261 ;; For 64BIT abi we always round up to 8 bytes.
1262 (define_insn "*pushhi2_rex64"
1263   [(set (match_operand:HI 0 "push_operand" "=X")
1264         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1265   "TARGET_64BIT"
1266   "push{q}\t%q1"
1267   [(set_attr "type" "push")
1268    (set_attr "mode" "QI")])
1269
1270 (define_insn "*movhi_1"
1271   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1272         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1273   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1274 {
1275   switch (get_attr_type (insn))
1276     {
1277     case TYPE_IMOVX:
1278       /* movzwl is faster than movw on p2 due to partial word stalls,
1279          though not as fast as an aligned movl.  */
1280       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1281     default:
1282       if (get_attr_mode (insn) == MODE_SI)
1283         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1284       else
1285         return "mov{w}\t{%1, %0|%0, %1}";
1286     }
1287 }
1288   [(set (attr "type")
1289      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1290               (const_string "imov")
1291             (and (eq_attr "alternative" "0")
1292                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1293                           (const_int 0))
1294                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1295                           (const_int 0))))
1296               (const_string "imov")
1297             (and (eq_attr "alternative" "1,2")
1298                  (match_operand:HI 1 "aligned_operand" ""))
1299               (const_string "imov")
1300             (and (ne (symbol_ref "TARGET_MOVX")
1301                      (const_int 0))
1302                  (eq_attr "alternative" "0,2"))
1303               (const_string "imovx")
1304            ]
1305            (const_string "imov")))
1306     (set (attr "mode")
1307       (cond [(eq_attr "type" "imovx")
1308                (const_string "SI")
1309              (and (eq_attr "alternative" "1,2")
1310                   (match_operand:HI 1 "aligned_operand" ""))
1311                (const_string "SI")
1312              (and (eq_attr "alternative" "0")
1313                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1314                            (const_int 0))
1315                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1316                            (const_int 0))))
1317                (const_string "SI")
1318             ]
1319             (const_string "HI")))])
1320
1321 ;; Stores and loads of ax to arbitrary constant address.
1322 ;; We fake an second form of instruction to force reload to load address
1323 ;; into register when rax is not available
1324 (define_insn "*movabshi_1_rex64"
1325   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1326         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1327   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1328   "@
1329    movabs{w}\t{%1, %P0|%P0, %1}
1330    mov{w}\t{%1, %a0|%a0, %1}"
1331   [(set_attr "type" "imov")
1332    (set_attr "modrm" "0,*")
1333    (set_attr "length_address" "8,0")
1334    (set_attr "length_immediate" "0,*")
1335    (set_attr "memory" "store")
1336    (set_attr "mode" "HI")])
1337
1338 (define_insn "*movabshi_2_rex64"
1339   [(set (match_operand:HI 0 "register_operand" "=a,r")
1340         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1341   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1342   "@
1343    movabs{w}\t{%P1, %0|%0, %P1}
1344    mov{w}\t{%a1, %0|%0, %a1}"
1345   [(set_attr "type" "imov")
1346    (set_attr "modrm" "0,*")
1347    (set_attr "length_address" "8,0")
1348    (set_attr "length_immediate" "0")
1349    (set_attr "memory" "load")
1350    (set_attr "mode" "HI")])
1351
1352 (define_insn "*swaphi_1"
1353   [(set (match_operand:HI 0 "register_operand" "+r")
1354         (match_operand:HI 1 "register_operand" "+r"))
1355    (set (match_dup 1)
1356         (match_dup 0))]
1357   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1358   "xchg{l}\t%k1, %k0"
1359   [(set_attr "type" "imov")
1360    (set_attr "mode" "SI")
1361    (set_attr "pent_pair" "np")
1362    (set_attr "athlon_decode" "vector")])
1363
1364 (define_insn "*swaphi_2"
1365   [(set (match_operand:HI 0 "register_operand" "+r")
1366         (match_operand:HI 1 "register_operand" "+r"))
1367    (set (match_dup 1)
1368         (match_dup 0))]
1369   "TARGET_PARTIAL_REG_STALL"
1370   "xchg{w}\t%1, %0"
1371   [(set_attr "type" "imov")
1372    (set_attr "mode" "HI")
1373    (set_attr "pent_pair" "np")
1374    (set_attr "athlon_decode" "vector")])
1375
1376 (define_expand "movstricthi"
1377   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1378         (match_operand:HI 1 "general_operand" ""))]
1379   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1380 {
1381   /* Don't generate memory->memory moves, go through a register */
1382   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1383     operands[1] = force_reg (HImode, operands[1]);
1384 })
1385
1386 (define_insn "*movstricthi_1"
1387   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1388         (match_operand:HI 1 "general_operand" "rn,m"))]
1389   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1390    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1391   "mov{w}\t{%1, %0|%0, %1}"
1392   [(set_attr "type" "imov")
1393    (set_attr "mode" "HI")])
1394
1395 (define_insn "*movstricthi_xor"
1396   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1397         (match_operand:HI 1 "const0_operand" "i"))
1398    (clobber (reg:CC FLAGS_REG))]
1399   "reload_completed
1400    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1401   "xor{w}\t{%0, %0|%0, %0}"
1402   [(set_attr "type" "alu1")
1403    (set_attr "mode" "HI")
1404    (set_attr "length_immediate" "0")])
1405
1406 (define_expand "movqi"
1407   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1408         (match_operand:QI 1 "general_operand" ""))]
1409   ""
1410   "ix86_expand_move (QImode, operands); DONE;")
1411
1412 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1413 ;; "push a byte".  But actually we use pushw, which has the effect
1414 ;; of rounding the amount pushed up to a halfword.
1415
1416 (define_insn "*pushqi2"
1417   [(set (match_operand:QI 0 "push_operand" "=X,X")
1418         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1419   "!TARGET_64BIT"
1420   "@
1421    push{w}\t{|word ptr }%1
1422    push{w}\t%w1"
1423   [(set_attr "type" "push")
1424    (set_attr "mode" "HI")])
1425
1426 ;; For 64BIT abi we always round up to 8 bytes.
1427 (define_insn "*pushqi2_rex64"
1428   [(set (match_operand:QI 0 "push_operand" "=X")
1429         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1430   "TARGET_64BIT"
1431   "push{q}\t%q1"
1432   [(set_attr "type" "push")
1433    (set_attr "mode" "QI")])
1434
1435 ;; Situation is quite tricky about when to choose full sized (SImode) move
1436 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1437 ;; partial register dependency machines (such as AMD Athlon), where QImode
1438 ;; moves issue extra dependency and for partial register stalls machines
1439 ;; that don't use QImode patterns (and QImode move cause stall on the next
1440 ;; instruction).
1441 ;;
1442 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1443 ;; register stall machines with, where we use QImode instructions, since
1444 ;; partial register stall can be caused there.  Then we use movzx.
1445 (define_insn "*movqi_1"
1446   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1447         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1448   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1449 {
1450   switch (get_attr_type (insn))
1451     {
1452     case TYPE_IMOVX:
1453       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1454         abort ();
1455       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1456     default:
1457       if (get_attr_mode (insn) == MODE_SI)
1458         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1459       else
1460         return "mov{b}\t{%1, %0|%0, %1}";
1461     }
1462 }
1463   [(set (attr "type")
1464      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1465               (const_string "imov")
1466             (and (eq_attr "alternative" "3")
1467                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1468                           (const_int 0))
1469                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1470                           (const_int 0))))
1471               (const_string "imov")
1472             (eq_attr "alternative" "3,5")
1473               (const_string "imovx")
1474             (and (ne (symbol_ref "TARGET_MOVX")
1475                      (const_int 0))
1476                  (eq_attr "alternative" "2"))
1477               (const_string "imovx")
1478            ]
1479            (const_string "imov")))
1480    (set (attr "mode")
1481       (cond [(eq_attr "alternative" "3,4,5")
1482                (const_string "SI")
1483              (eq_attr "alternative" "6")
1484                (const_string "QI")
1485              (eq_attr "type" "imovx")
1486                (const_string "SI")
1487              (and (eq_attr "type" "imov")
1488                   (and (eq_attr "alternative" "0,1,2")
1489                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1490                            (const_int 0))))
1491                (const_string "SI")
1492              ;; Avoid partial register stalls when not using QImode arithmetic
1493              (and (eq_attr "type" "imov")
1494                   (and (eq_attr "alternative" "0,1,2")
1495                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1496                                 (const_int 0))
1497                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1498                                 (const_int 0)))))
1499                (const_string "SI")
1500            ]
1501            (const_string "QI")))])
1502
1503 (define_expand "reload_outqi"
1504   [(parallel [(match_operand:QI 0 "" "=m")
1505               (match_operand:QI 1 "register_operand" "r")
1506               (match_operand:QI 2 "register_operand" "=&q")])]
1507   ""
1508 {
1509   rtx op0, op1, op2;
1510   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1511
1512   if (reg_overlap_mentioned_p (op2, op0))
1513     abort ();
1514   if (! q_regs_operand (op1, QImode))
1515     {
1516       emit_insn (gen_movqi (op2, op1));
1517       op1 = op2;
1518     }
1519   emit_insn (gen_movqi (op0, op1));
1520   DONE;
1521 })
1522
1523 (define_insn "*swapqi_1"
1524   [(set (match_operand:QI 0 "register_operand" "+r")
1525         (match_operand:QI 1 "register_operand" "+r"))
1526    (set (match_dup 1)
1527         (match_dup 0))]
1528   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1529   "xchg{l}\t%k1, %k0"
1530   [(set_attr "type" "imov")
1531    (set_attr "mode" "SI")
1532    (set_attr "pent_pair" "np")
1533    (set_attr "athlon_decode" "vector")])
1534
1535 (define_insn "*swapqi_2"
1536   [(set (match_operand:QI 0 "register_operand" "+q")
1537         (match_operand:QI 1 "register_operand" "+q"))
1538    (set (match_dup 1)
1539         (match_dup 0))]
1540   "TARGET_PARTIAL_REG_STALL"
1541   "xchg{b}\t%1, %0"
1542   [(set_attr "type" "imov")
1543    (set_attr "mode" "QI")
1544    (set_attr "pent_pair" "np")
1545    (set_attr "athlon_decode" "vector")])
1546
1547 (define_expand "movstrictqi"
1548   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1549         (match_operand:QI 1 "general_operand" ""))]
1550   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1551 {
1552   /* Don't generate memory->memory moves, go through a register.  */
1553   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1554     operands[1] = force_reg (QImode, operands[1]);
1555 })
1556
1557 (define_insn "*movstrictqi_1"
1558   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1559         (match_operand:QI 1 "general_operand" "*qn,m"))]
1560   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1561    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1562   "mov{b}\t{%1, %0|%0, %1}"
1563   [(set_attr "type" "imov")
1564    (set_attr "mode" "QI")])
1565
1566 (define_insn "*movstrictqi_xor"
1567   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1568         (match_operand:QI 1 "const0_operand" "i"))
1569    (clobber (reg:CC FLAGS_REG))]
1570   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1571   "xor{b}\t{%0, %0|%0, %0}"
1572   [(set_attr "type" "alu1")
1573    (set_attr "mode" "QI")
1574    (set_attr "length_immediate" "0")])
1575
1576 (define_insn "*movsi_extv_1"
1577   [(set (match_operand:SI 0 "register_operand" "=R")
1578         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1579                          (const_int 8)
1580                          (const_int 8)))]
1581   ""
1582   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1583   [(set_attr "type" "imovx")
1584    (set_attr "mode" "SI")])
1585
1586 (define_insn "*movhi_extv_1"
1587   [(set (match_operand:HI 0 "register_operand" "=R")
1588         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1589                          (const_int 8)
1590                          (const_int 8)))]
1591   ""
1592   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1593   [(set_attr "type" "imovx")
1594    (set_attr "mode" "SI")])
1595
1596 (define_insn "*movqi_extv_1"
1597   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1598         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1599                          (const_int 8)
1600                          (const_int 8)))]
1601   "!TARGET_64BIT"
1602 {
1603   switch (get_attr_type (insn))
1604     {
1605     case TYPE_IMOVX:
1606       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1607     default:
1608       return "mov{b}\t{%h1, %0|%0, %h1}";
1609     }
1610 }
1611   [(set (attr "type")
1612      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1613                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1614                              (ne (symbol_ref "TARGET_MOVX")
1615                                  (const_int 0))))
1616         (const_string "imovx")
1617         (const_string "imov")))
1618    (set (attr "mode")
1619      (if_then_else (eq_attr "type" "imovx")
1620         (const_string "SI")
1621         (const_string "QI")))])
1622
1623 (define_insn "*movqi_extv_1_rex64"
1624   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1625         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1626                          (const_int 8)
1627                          (const_int 8)))]
1628   "TARGET_64BIT"
1629 {
1630   switch (get_attr_type (insn))
1631     {
1632     case TYPE_IMOVX:
1633       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1634     default:
1635       return "mov{b}\t{%h1, %0|%0, %h1}";
1636     }
1637 }
1638   [(set (attr "type")
1639      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1640                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1641                              (ne (symbol_ref "TARGET_MOVX")
1642                                  (const_int 0))))
1643         (const_string "imovx")
1644         (const_string "imov")))
1645    (set (attr "mode")
1646      (if_then_else (eq_attr "type" "imovx")
1647         (const_string "SI")
1648         (const_string "QI")))])
1649
1650 ;; Stores and loads of ax to arbitrary constant address.
1651 ;; We fake an second form of instruction to force reload to load address
1652 ;; into register when rax is not available
1653 (define_insn "*movabsqi_1_rex64"
1654   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1655         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1656   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1657   "@
1658    movabs{b}\t{%1, %P0|%P0, %1}
1659    mov{b}\t{%1, %a0|%a0, %1}"
1660   [(set_attr "type" "imov")
1661    (set_attr "modrm" "0,*")
1662    (set_attr "length_address" "8,0")
1663    (set_attr "length_immediate" "0,*")
1664    (set_attr "memory" "store")
1665    (set_attr "mode" "QI")])
1666
1667 (define_insn "*movabsqi_2_rex64"
1668   [(set (match_operand:QI 0 "register_operand" "=a,r")
1669         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1670   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1671   "@
1672    movabs{b}\t{%P1, %0|%0, %P1}
1673    mov{b}\t{%a1, %0|%0, %a1}"
1674   [(set_attr "type" "imov")
1675    (set_attr "modrm" "0,*")
1676    (set_attr "length_address" "8,0")
1677    (set_attr "length_immediate" "0")
1678    (set_attr "memory" "load")
1679    (set_attr "mode" "QI")])
1680
1681 (define_insn "*movsi_extzv_1"
1682   [(set (match_operand:SI 0 "register_operand" "=R")
1683         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1684                          (const_int 8)
1685                          (const_int 8)))]
1686   ""
1687   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1688   [(set_attr "type" "imovx")
1689    (set_attr "mode" "SI")])
1690
1691 (define_insn "*movqi_extzv_2"
1692   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1693         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1694                                     (const_int 8)
1695                                     (const_int 8)) 0))]
1696   "!TARGET_64BIT"
1697 {
1698   switch (get_attr_type (insn))
1699     {
1700     case TYPE_IMOVX:
1701       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1702     default:
1703       return "mov{b}\t{%h1, %0|%0, %h1}";
1704     }
1705 }
1706   [(set (attr "type")
1707      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1708                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1709                              (ne (symbol_ref "TARGET_MOVX")
1710                                  (const_int 0))))
1711         (const_string "imovx")
1712         (const_string "imov")))
1713    (set (attr "mode")
1714      (if_then_else (eq_attr "type" "imovx")
1715         (const_string "SI")
1716         (const_string "QI")))])
1717
1718 (define_insn "*movqi_extzv_2_rex64"
1719   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1720         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1721                                     (const_int 8)
1722                                     (const_int 8)) 0))]
1723   "TARGET_64BIT"
1724 {
1725   switch (get_attr_type (insn))
1726     {
1727     case TYPE_IMOVX:
1728       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1729     default:
1730       return "mov{b}\t{%h1, %0|%0, %h1}";
1731     }
1732 }
1733   [(set (attr "type")
1734      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1735                         (ne (symbol_ref "TARGET_MOVX")
1736                             (const_int 0)))
1737         (const_string "imovx")
1738         (const_string "imov")))
1739    (set (attr "mode")
1740      (if_then_else (eq_attr "type" "imovx")
1741         (const_string "SI")
1742         (const_string "QI")))])
1743
1744 (define_insn "movsi_insv_1"
1745   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1746                          (const_int 8)
1747                          (const_int 8))
1748         (match_operand:SI 1 "general_operand" "Qmn"))]
1749   "!TARGET_64BIT"
1750   "mov{b}\t{%b1, %h0|%h0, %b1}"
1751   [(set_attr "type" "imov")
1752    (set_attr "mode" "QI")])
1753
1754 (define_insn "movdi_insv_1_rex64"
1755   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1756                          (const_int 8)
1757                          (const_int 8))
1758         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1759   "TARGET_64BIT"
1760   "mov{b}\t{%b1, %h0|%h0, %b1}"
1761   [(set_attr "type" "imov")
1762    (set_attr "mode" "QI")])
1763
1764 (define_insn "*movqi_insv_2"
1765   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1766                          (const_int 8)
1767                          (const_int 8))
1768         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1769                      (const_int 8)))]
1770   ""
1771   "mov{b}\t{%h1, %h0|%h0, %h1}"
1772   [(set_attr "type" "imov")
1773    (set_attr "mode" "QI")])
1774
1775 (define_expand "movdi"
1776   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1777         (match_operand:DI 1 "general_operand" ""))]
1778   ""
1779   "ix86_expand_move (DImode, operands); DONE;")
1780
1781 (define_insn "*pushdi"
1782   [(set (match_operand:DI 0 "push_operand" "=<")
1783         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1784   "!TARGET_64BIT"
1785   "#")
1786
1787 (define_insn "pushdi2_rex64"
1788   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1789         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1790   "TARGET_64BIT"
1791   "@
1792    push{q}\t%1
1793    #"
1794   [(set_attr "type" "push,multi")
1795    (set_attr "mode" "DI")])
1796
1797 ;; Convert impossible pushes of immediate to existing instructions.
1798 ;; First try to get scratch register and go through it.  In case this
1799 ;; fails, push sign extended lower part first and then overwrite
1800 ;; upper part by 32bit move.
1801 (define_peephole2
1802   [(match_scratch:DI 2 "r")
1803    (set (match_operand:DI 0 "push_operand" "")
1804         (match_operand:DI 1 "immediate_operand" ""))]
1805   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1806    && !x86_64_immediate_operand (operands[1], DImode)"
1807   [(set (match_dup 2) (match_dup 1))
1808    (set (match_dup 0) (match_dup 2))]
1809   "")
1810
1811 ;; We need to define this as both peepholer and splitter for case
1812 ;; peephole2 pass is not run.
1813 ;; "&& 1" is needed to keep it from matching the previous pattern.
1814 (define_peephole2
1815   [(set (match_operand:DI 0 "push_operand" "")
1816         (match_operand:DI 1 "immediate_operand" ""))]
1817   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1818    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1819   [(set (match_dup 0) (match_dup 1))
1820    (set (match_dup 2) (match_dup 3))]
1821   "split_di (operands + 1, 1, operands + 2, operands + 3);
1822    operands[1] = gen_lowpart (DImode, operands[2]);
1823    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1824                                                     GEN_INT (4)));
1825   ")
1826
1827 (define_split
1828   [(set (match_operand:DI 0 "push_operand" "")
1829         (match_operand:DI 1 "immediate_operand" ""))]
1830   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1831    && !symbolic_operand (operands[1], DImode)
1832    && !x86_64_immediate_operand (operands[1], DImode)"
1833   [(set (match_dup 0) (match_dup 1))
1834    (set (match_dup 2) (match_dup 3))]
1835   "split_di (operands + 1, 1, operands + 2, operands + 3);
1836    operands[1] = gen_lowpart (DImode, operands[2]);
1837    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1838                                                     GEN_INT (4)));
1839   ")
1840
1841 (define_insn "*pushdi2_prologue_rex64"
1842   [(set (match_operand:DI 0 "push_operand" "=<")
1843         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1844    (clobber (mem:BLK (scratch)))]
1845   "TARGET_64BIT"
1846   "push{q}\t%1"
1847   [(set_attr "type" "push")
1848    (set_attr "mode" "DI")])
1849
1850 (define_insn "*popdi1_epilogue_rex64"
1851   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1852         (mem:DI (reg:DI SP_REG)))
1853    (set (reg:DI SP_REG)
1854         (plus:DI (reg:DI SP_REG) (const_int 8)))
1855    (clobber (mem:BLK (scratch)))]
1856   "TARGET_64BIT"
1857   "pop{q}\t%0"
1858   [(set_attr "type" "pop")
1859    (set_attr "mode" "DI")])
1860
1861 (define_insn "popdi1"
1862   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1863         (mem:DI (reg:DI SP_REG)))
1864    (set (reg:DI SP_REG)
1865         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1866   "TARGET_64BIT"
1867   "pop{q}\t%0"
1868   [(set_attr "type" "pop")
1869    (set_attr "mode" "DI")])
1870
1871 (define_insn "*movdi_xor_rex64"
1872   [(set (match_operand:DI 0 "register_operand" "=r")
1873         (match_operand:DI 1 "const0_operand" "i"))
1874    (clobber (reg:CC FLAGS_REG))]
1875   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1876    && reload_completed"
1877   "xor{l}\t{%k0, %k0|%k0, %k0}"
1878   [(set_attr "type" "alu1")
1879    (set_attr "mode" "SI")
1880    (set_attr "length_immediate" "0")])
1881
1882 (define_insn "*movdi_or_rex64"
1883   [(set (match_operand:DI 0 "register_operand" "=r")
1884         (match_operand:DI 1 "const_int_operand" "i"))
1885    (clobber (reg:CC FLAGS_REG))]
1886   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1887    && reload_completed
1888    && operands[1] == constm1_rtx"
1889 {
1890   operands[1] = constm1_rtx;
1891   return "or{q}\t{%1, %0|%0, %1}";
1892 }
1893   [(set_attr "type" "alu1")
1894    (set_attr "mode" "DI")
1895    (set_attr "length_immediate" "1")])
1896
1897 (define_insn "*movdi_2"
1898   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1899         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1900   "!TARGET_64BIT
1901    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1902   "@
1903    #
1904    #
1905    movq\t{%1, %0|%0, %1}
1906    movq\t{%1, %0|%0, %1}
1907    movq\t{%1, %0|%0, %1}
1908    movdqa\t{%1, %0|%0, %1}
1909    movq\t{%1, %0|%0, %1}"
1910   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1911    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1912
1913 (define_split
1914   [(set (match_operand:DI 0 "push_operand" "")
1915         (match_operand:DI 1 "general_operand" ""))]
1916   "!TARGET_64BIT && reload_completed
1917    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1918   [(const_int 0)]
1919   "ix86_split_long_move (operands); DONE;")
1920
1921 ;; %%% This multiword shite has got to go.
1922 (define_split
1923   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1924         (match_operand:DI 1 "general_operand" ""))]
1925   "!TARGET_64BIT && reload_completed
1926    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1927    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1928   [(const_int 0)]
1929   "ix86_split_long_move (operands); DONE;")
1930
1931 (define_insn "*movdi_1_rex64"
1932   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1933         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1934   "TARGET_64BIT
1935    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1936    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1937 {
1938   switch (get_attr_type (insn))
1939     {
1940     case TYPE_SSECVT:
1941       if (which_alternative == 11)
1942         return "movq2dq\t{%1, %0|%0, %1}";
1943       else
1944         return "movdq2q\t{%1, %0|%0, %1}";
1945     case TYPE_SSEMOV:
1946       if (get_attr_mode (insn) == MODE_TI)
1947           return "movdqa\t{%1, %0|%0, %1}";
1948       /* FALLTHRU */
1949     case TYPE_MMXMOV:
1950       /* Moves from and into integer register is done using movd opcode with
1951          REX prefix.  */
1952       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1953           return "movd\t{%1, %0|%0, %1}";
1954       return "movq\t{%1, %0|%0, %1}";
1955     case TYPE_MULTI:
1956       return "#";
1957     case TYPE_LEA:
1958       return "lea{q}\t{%a1, %0|%0, %a1}";
1959     default:
1960       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1961         abort ();
1962       if (get_attr_mode (insn) == MODE_SI)
1963         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1964       else if (which_alternative == 2)
1965         return "movabs{q}\t{%1, %0|%0, %1}";
1966       else
1967         return "mov{q}\t{%1, %0|%0, %1}";
1968     }
1969 }
1970   [(set (attr "type")
1971      (cond [(eq_attr "alternative" "5,6,7")
1972               (const_string "mmxmov")
1973             (eq_attr "alternative" "8,9,10")
1974               (const_string "ssemov")
1975             (eq_attr "alternative" "11,12")
1976               (const_string "ssecvt")
1977             (eq_attr "alternative" "4")
1978               (const_string "multi")
1979             (and (ne (symbol_ref "flag_pic") (const_int 0))
1980                  (match_operand:DI 1 "symbolic_operand" ""))
1981               (const_string "lea")
1982            ]
1983            (const_string "imov")))
1984    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1985    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1986    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1987
1988 (define_insn "*movdi_1_rex64_nointerunit"
1989   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1990         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1991   "TARGET_64BIT
1992    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1993    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1994 {
1995   switch (get_attr_type (insn))
1996     {
1997     case TYPE_SSEMOV:
1998       if (get_attr_mode (insn) == MODE_TI)
1999           return "movdqa\t{%1, %0|%0, %1}";
2000       /* FALLTHRU */
2001     case TYPE_MMXMOV:
2002       return "movq\t{%1, %0|%0, %1}";
2003     case TYPE_MULTI:
2004       return "#";
2005     case TYPE_LEA:
2006       return "lea{q}\t{%a1, %0|%0, %a1}";
2007     default:
2008       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2009         abort ();
2010       if (get_attr_mode (insn) == MODE_SI)
2011         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012       else if (which_alternative == 2)
2013         return "movabs{q}\t{%1, %0|%0, %1}";
2014       else
2015         return "mov{q}\t{%1, %0|%0, %1}";
2016     }
2017 }
2018   [(set (attr "type")
2019      (cond [(eq_attr "alternative" "5,6,7")
2020               (const_string "mmxmov")
2021             (eq_attr "alternative" "8,9,10")
2022               (const_string "ssemov")
2023             (eq_attr "alternative" "4")
2024               (const_string "multi")
2025             (and (ne (symbol_ref "flag_pic") (const_int 0))
2026                  (match_operand:DI 1 "symbolic_operand" ""))
2027               (const_string "lea")
2028            ]
2029            (const_string "imov")))
2030    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2031    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2032    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2033
2034 ;; Stores and loads of ax to arbitrary constant address.
2035 ;; We fake an second form of instruction to force reload to load address
2036 ;; into register when rax is not available
2037 (define_insn "*movabsdi_1_rex64"
2038   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2039         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2040   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2041   "@
2042    movabs{q}\t{%1, %P0|%P0, %1}
2043    mov{q}\t{%1, %a0|%a0, %1}"
2044   [(set_attr "type" "imov")
2045    (set_attr "modrm" "0,*")
2046    (set_attr "length_address" "8,0")
2047    (set_attr "length_immediate" "0,*")
2048    (set_attr "memory" "store")
2049    (set_attr "mode" "DI")])
2050
2051 (define_insn "*movabsdi_2_rex64"
2052   [(set (match_operand:DI 0 "register_operand" "=a,r")
2053         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2054   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2055   "@
2056    movabs{q}\t{%P1, %0|%0, %P1}
2057    mov{q}\t{%a1, %0|%0, %a1}"
2058   [(set_attr "type" "imov")
2059    (set_attr "modrm" "0,*")
2060    (set_attr "length_address" "8,0")
2061    (set_attr "length_immediate" "0")
2062    (set_attr "memory" "load")
2063    (set_attr "mode" "DI")])
2064
2065 ;; Convert impossible stores of immediate to existing instructions.
2066 ;; First try to get scratch register and go through it.  In case this
2067 ;; fails, move by 32bit parts.
2068 (define_peephole2
2069   [(match_scratch:DI 2 "r")
2070    (set (match_operand:DI 0 "memory_operand" "")
2071         (match_operand:DI 1 "immediate_operand" ""))]
2072   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2073    && !x86_64_immediate_operand (operands[1], DImode)"
2074   [(set (match_dup 2) (match_dup 1))
2075    (set (match_dup 0) (match_dup 2))]
2076   "")
2077
2078 ;; We need to define this as both peepholer and splitter for case
2079 ;; peephole2 pass is not run.
2080 ;; "&& 1" is needed to keep it from matching the previous pattern.
2081 (define_peephole2
2082   [(set (match_operand:DI 0 "memory_operand" "")
2083         (match_operand:DI 1 "immediate_operand" ""))]
2084   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2085    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2086   [(set (match_dup 2) (match_dup 3))
2087    (set (match_dup 4) (match_dup 5))]
2088   "split_di (operands, 2, operands + 2, operands + 4);")
2089
2090 (define_split
2091   [(set (match_operand:DI 0 "memory_operand" "")
2092         (match_operand:DI 1 "immediate_operand" ""))]
2093   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2094    && !symbolic_operand (operands[1], DImode)
2095    && !x86_64_immediate_operand (operands[1], DImode)"
2096   [(set (match_dup 2) (match_dup 3))
2097    (set (match_dup 4) (match_dup 5))]
2098   "split_di (operands, 2, operands + 2, operands + 4);")
2099
2100 (define_insn "*swapdi_rex64"
2101   [(set (match_operand:DI 0 "register_operand" "+r")
2102         (match_operand:DI 1 "register_operand" "+r"))
2103    (set (match_dup 1)
2104         (match_dup 0))]
2105   "TARGET_64BIT"
2106   "xchg{q}\t%1, %0"
2107   [(set_attr "type" "imov")
2108    (set_attr "mode" "DI")
2109    (set_attr "pent_pair" "np")
2110    (set_attr "athlon_decode" "vector")])
2111
2112 (define_expand "movsf"
2113   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2114         (match_operand:SF 1 "general_operand" ""))]
2115   ""
2116   "ix86_expand_move (SFmode, operands); DONE;")
2117
2118 (define_insn "*pushsf"
2119   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2120         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2121   "!TARGET_64BIT"
2122 {
2123   switch (which_alternative)
2124     {
2125     case 1:
2126       return "push{l}\t%1";
2127
2128     default:
2129       /* This insn should be already split before reg-stack.  */
2130       abort ();
2131     }
2132 }
2133   [(set_attr "type" "multi,push,multi")
2134    (set_attr "mode" "SF,SI,SF")])
2135
2136 (define_insn "*pushsf_rex64"
2137   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2138         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2139   "TARGET_64BIT"
2140 {
2141   switch (which_alternative)
2142     {
2143     case 1:
2144       return "push{q}\t%q1";
2145
2146     default:
2147       /* This insn should be already split before reg-stack.  */
2148       abort ();
2149     }
2150 }
2151   [(set_attr "type" "multi,push,multi")
2152    (set_attr "mode" "SF,DI,SF")])
2153
2154 (define_split
2155   [(set (match_operand:SF 0 "push_operand" "")
2156         (match_operand:SF 1 "memory_operand" ""))]
2157   "reload_completed
2158    && GET_CODE (operands[1]) == MEM
2159    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2160    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2161   [(set (match_dup 0)
2162         (match_dup 1))]
2163   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2164
2165
2166 ;; %%% Kill this when call knows how to work this out.
2167 (define_split
2168   [(set (match_operand:SF 0 "push_operand" "")
2169         (match_operand:SF 1 "any_fp_register_operand" ""))]
2170   "!TARGET_64BIT"
2171   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2172    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2173
2174 (define_split
2175   [(set (match_operand:SF 0 "push_operand" "")
2176         (match_operand:SF 1 "any_fp_register_operand" ""))]
2177   "TARGET_64BIT"
2178   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2179    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2180
2181 (define_insn "*movsf_1"
2182   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2183         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2184   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2185    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2186    && (reload_in_progress || reload_completed
2187        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2188        || GET_CODE (operands[1]) != CONST_DOUBLE
2189        || memory_operand (operands[0], SFmode))" 
2190 {
2191   switch (which_alternative)
2192     {
2193     case 0:
2194       return output_387_reg_move (insn, operands);
2195
2196     case 1:
2197       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2198         return "fstp%z0\t%y0";
2199       else
2200         return "fst%z0\t%y0";
2201
2202     case 2:
2203       return standard_80387_constant_opcode (operands[1]);
2204
2205     case 3:
2206     case 4:
2207       return "mov{l}\t{%1, %0|%0, %1}";
2208     case 5:
2209       if (get_attr_mode (insn) == MODE_TI)
2210         return "pxor\t%0, %0";
2211       else
2212         return "xorps\t%0, %0";
2213     case 6:
2214       if (get_attr_mode (insn) == MODE_V4SF)
2215         return "movaps\t{%1, %0|%0, %1}";
2216       else
2217         return "movss\t{%1, %0|%0, %1}";
2218     case 7:
2219     case 8:
2220       return "movss\t{%1, %0|%0, %1}";
2221
2222     case 9:
2223     case 10:
2224       return "movd\t{%1, %0|%0, %1}";
2225
2226     case 11:
2227       return "movq\t{%1, %0|%0, %1}";
2228
2229     default:
2230       abort();
2231     }
2232 }
2233   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2234    (set (attr "mode")
2235         (cond [(eq_attr "alternative" "3,4,9,10")
2236                  (const_string "SI")
2237                (eq_attr "alternative" "5")
2238                  (if_then_else
2239                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2240                                  (const_int 0))
2241                              (ne (symbol_ref "TARGET_SSE2")
2242                                  (const_int 0)))
2243                         (eq (symbol_ref "optimize_size")
2244                             (const_int 0)))
2245                    (const_string "TI")
2246                    (const_string "V4SF"))
2247                /* For architectures resolving dependencies on
2248                   whole SSE registers use APS move to break dependency
2249                   chains, otherwise use short move to avoid extra work. 
2250
2251                   Do the same for architectures resolving dependencies on
2252                   the parts.  While in DF mode it is better to always handle
2253                   just register parts, the SF mode is different due to lack
2254                   of instructions to load just part of the register.  It is
2255                   better to maintain the whole registers in single format
2256                   to avoid problems on using packed logical operations.  */
2257                (eq_attr "alternative" "6")
2258                  (if_then_else
2259                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2260                             (const_int 0))
2261                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2262                             (const_int 0)))
2263                    (const_string "V4SF")
2264                    (const_string "SF"))
2265                (eq_attr "alternative" "11")
2266                  (const_string "DI")]
2267                (const_string "SF")))])
2268
2269 (define_insn "*movsf_1_nointerunit"
2270   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2271         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2272   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2273    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2274    && (reload_in_progress || reload_completed
2275        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2276        || GET_CODE (operands[1]) != CONST_DOUBLE
2277        || memory_operand (operands[0], SFmode))" 
2278 {
2279   switch (which_alternative)
2280     {
2281     case 0:
2282       return output_387_reg_move (insn, operands);
2283
2284     case 1:
2285       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2286         return "fstp%z0\t%y0";
2287       else
2288         return "fst%z0\t%y0";
2289
2290     case 2:
2291       return standard_80387_constant_opcode (operands[1]);
2292
2293     case 3:
2294     case 4:
2295       return "mov{l}\t{%1, %0|%0, %1}";
2296     case 5:
2297       if (get_attr_mode (insn) == MODE_TI)
2298         return "pxor\t%0, %0";
2299       else
2300         return "xorps\t%0, %0";
2301     case 6:
2302       if (get_attr_mode (insn) == MODE_V4SF)
2303         return "movaps\t{%1, %0|%0, %1}";
2304       else
2305         return "movss\t{%1, %0|%0, %1}";
2306     case 7:
2307     case 8:
2308       return "movss\t{%1, %0|%0, %1}";
2309
2310     case 9:
2311     case 10:
2312       return "movd\t{%1, %0|%0, %1}";
2313
2314     case 11:
2315       return "movq\t{%1, %0|%0, %1}";
2316
2317     default:
2318       abort();
2319     }
2320 }
2321   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2322    (set (attr "mode")
2323         (cond [(eq_attr "alternative" "3,4,9,10")
2324                  (const_string "SI")
2325                (eq_attr "alternative" "5")
2326                  (if_then_else
2327                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2328                                  (const_int 0))
2329                              (ne (symbol_ref "TARGET_SSE2")
2330                                  (const_int 0)))
2331                         (eq (symbol_ref "optimize_size")
2332                             (const_int 0)))
2333                    (const_string "TI")
2334                    (const_string "V4SF"))
2335                /* For architectures resolving dependencies on
2336                   whole SSE registers use APS move to break dependency
2337                   chains, otherwise use short move to avoid extra work. 
2338
2339                   Do the same for architectures resolving dependencies on
2340                   the parts.  While in DF mode it is better to always handle
2341                   just register parts, the SF mode is different due to lack
2342                   of instructions to load just part of the register.  It is
2343                   better to maintain the whole registers in single format
2344                   to avoid problems on using packed logical operations.  */
2345                (eq_attr "alternative" "6")
2346                  (if_then_else
2347                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2348                             (const_int 0))
2349                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2350                             (const_int 0)))
2351                    (const_string "V4SF")
2352                    (const_string "SF"))
2353                (eq_attr "alternative" "11")
2354                  (const_string "DI")]
2355                (const_string "SF")))])
2356
2357 (define_insn "*swapsf"
2358   [(set (match_operand:SF 0 "register_operand" "+f")
2359         (match_operand:SF 1 "register_operand" "+f"))
2360    (set (match_dup 1)
2361         (match_dup 0))]
2362   "reload_completed || !TARGET_SSE"
2363 {
2364   if (STACK_TOP_P (operands[0]))
2365     return "fxch\t%1";
2366   else
2367     return "fxch\t%0";
2368 }
2369   [(set_attr "type" "fxch")
2370    (set_attr "mode" "SF")])
2371
2372 (define_expand "movdf"
2373   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2374         (match_operand:DF 1 "general_operand" ""))]
2375   ""
2376   "ix86_expand_move (DFmode, operands); DONE;")
2377
2378 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2379 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2380 ;; On the average, pushdf using integers can be still shorter.  Allow this
2381 ;; pattern for optimize_size too.
2382
2383 (define_insn "*pushdf_nointeger"
2384   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2385         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2386   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2387 {
2388   /* This insn should be already split before reg-stack.  */
2389   abort ();
2390 }
2391   [(set_attr "type" "multi")
2392    (set_attr "mode" "DF,SI,SI,DF")])
2393
2394 (define_insn "*pushdf_integer"
2395   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2396         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2397   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2398 {
2399   /* This insn should be already split before reg-stack.  */
2400   abort ();
2401 }
2402   [(set_attr "type" "multi")
2403    (set_attr "mode" "DF,SI,DF")])
2404
2405 ;; %%% Kill this when call knows how to work this out.
2406 (define_split
2407   [(set (match_operand:DF 0 "push_operand" "")
2408         (match_operand:DF 1 "any_fp_register_operand" ""))]
2409   "!TARGET_64BIT && reload_completed"
2410   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2411    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2412   "")
2413
2414 (define_split
2415   [(set (match_operand:DF 0 "push_operand" "")
2416         (match_operand:DF 1 "any_fp_register_operand" ""))]
2417   "TARGET_64BIT && reload_completed"
2418   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2419    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2420   "")
2421
2422 (define_split
2423   [(set (match_operand:DF 0 "push_operand" "")
2424         (match_operand:DF 1 "general_operand" ""))]
2425   "reload_completed"
2426   [(const_int 0)]
2427   "ix86_split_long_move (operands); DONE;")
2428
2429 ;; Moving is usually shorter when only FP registers are used. This separate
2430 ;; movdf pattern avoids the use of integer registers for FP operations
2431 ;; when optimizing for size.
2432
2433 (define_insn "*movdf_nointeger"
2434   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2435         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2436   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2437    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2438    && (reload_in_progress || reload_completed
2439        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2440        || GET_CODE (operands[1]) != CONST_DOUBLE
2441        || memory_operand (operands[0], DFmode))" 
2442 {
2443   switch (which_alternative)
2444     {
2445     case 0:
2446       return output_387_reg_move (insn, operands);
2447
2448     case 1:
2449       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2450         return "fstp%z0\t%y0";
2451       else
2452         return "fst%z0\t%y0";
2453
2454     case 2:
2455       return standard_80387_constant_opcode (operands[1]);
2456
2457     case 3:
2458     case 4:
2459       return "#";
2460     case 5:
2461       switch (get_attr_mode (insn))
2462         {
2463         case MODE_V4SF:
2464           return "xorps\t%0, %0";
2465         case MODE_V2DF:
2466           return "xorpd\t%0, %0";
2467         case MODE_TI:
2468           return "pxor\t%0, %0";
2469         default:
2470           abort ();
2471         }
2472     case 6:
2473       switch (get_attr_mode (insn))
2474         {
2475         case MODE_V4SF:
2476           return "movaps\t{%1, %0|%0, %1}";
2477         case MODE_V2DF:
2478           return "movapd\t{%1, %0|%0, %1}";
2479         case MODE_DF:
2480           return "movsd\t{%1, %0|%0, %1}";
2481         default:
2482           abort ();
2483         }
2484     case 7:
2485       if (get_attr_mode (insn) == MODE_V2DF)
2486         return "movlpd\t{%1, %0|%0, %1}";
2487       else
2488         return "movsd\t{%1, %0|%0, %1}";
2489     case 8:
2490       return "movsd\t{%1, %0|%0, %1}";
2491
2492     default:
2493       abort();
2494     }
2495 }
2496   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2497    (set (attr "mode")
2498         (cond [(eq_attr "alternative" "3,4")
2499                  (const_string "SI")
2500                /* xorps is one byte shorter.  */
2501                (eq_attr "alternative" "5")
2502                  (cond [(ne (symbol_ref "optimize_size")
2503                             (const_int 0))
2504                           (const_string "V4SF")
2505                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2506                             (const_int 0))
2507                           (const_string "TI")]
2508                        (const_string "V2DF"))
2509                /* For architectures resolving dependencies on
2510                   whole SSE registers use APD move to break dependency
2511                   chains, otherwise use short move to avoid extra work.
2512
2513                   movaps encodes one byte shorter.  */
2514                (eq_attr "alternative" "6")
2515                  (cond
2516                   [(ne (symbol_ref "optimize_size")
2517                        (const_int 0))
2518                      (const_string "V4SF")
2519                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2520                        (const_int 0))
2521                      (const_string "V2DF")]
2522                    (const_string "DF"))
2523                /* For architectures resolving dependencies on register
2524                   parts we may avoid extra work to zero out upper part
2525                   of register.  */
2526                (eq_attr "alternative" "7")
2527                  (if_then_else
2528                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2529                        (const_int 0))
2530                    (const_string "V2DF")
2531                    (const_string "DF"))]
2532                (const_string "DF")))])
2533
2534 (define_insn "*movdf_integer"
2535   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2536         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2537   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2538    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2539    && (reload_in_progress || reload_completed
2540        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2541        || GET_CODE (operands[1]) != CONST_DOUBLE
2542        || memory_operand (operands[0], DFmode))" 
2543 {
2544   switch (which_alternative)
2545     {
2546     case 0:
2547       return output_387_reg_move (insn, operands);
2548
2549     case 1:
2550       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2551         return "fstp%z0\t%y0";
2552       else
2553         return "fst%z0\t%y0";
2554
2555     case 2:
2556       return standard_80387_constant_opcode (operands[1]);
2557
2558     case 3:
2559     case 4:
2560       return "#";
2561
2562     case 5:
2563       switch (get_attr_mode (insn))
2564         {
2565         case MODE_V4SF:
2566           return "xorps\t%0, %0";
2567         case MODE_V2DF:
2568           return "xorpd\t%0, %0";
2569         case MODE_TI:
2570           return "pxor\t%0, %0";
2571         default:
2572           abort ();
2573         }
2574     case 6:
2575       switch (get_attr_mode (insn))
2576         {
2577         case MODE_V4SF:
2578           return "movaps\t{%1, %0|%0, %1}";
2579         case MODE_V2DF:
2580           return "movapd\t{%1, %0|%0, %1}";
2581         case MODE_DF:
2582           return "movsd\t{%1, %0|%0, %1}";
2583         default:
2584           abort ();
2585         }
2586     case 7:
2587       if (get_attr_mode (insn) == MODE_V2DF)
2588         return "movlpd\t{%1, %0|%0, %1}";
2589       else
2590         return "movsd\t{%1, %0|%0, %1}";
2591     case 8:
2592       return "movsd\t{%1, %0|%0, %1}";
2593
2594     default:
2595       abort();
2596     }
2597 }
2598   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2599    (set (attr "mode")
2600         (cond [(eq_attr "alternative" "3,4")
2601                  (const_string "SI")
2602                /* xorps is one byte shorter.  */
2603                (eq_attr "alternative" "5")
2604                  (cond [(ne (symbol_ref "optimize_size")
2605                             (const_int 0))
2606                           (const_string "V4SF")
2607                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2608                             (const_int 0))
2609                           (const_string "TI")]
2610                        (const_string "V2DF"))
2611                /* For architectures resolving dependencies on
2612                   whole SSE registers use APD move to break dependency
2613                   chains, otherwise use short move to avoid extra work.  
2614
2615                   movaps encodes one byte shorter.  */
2616                (eq_attr "alternative" "6")
2617                  (cond
2618                   [(ne (symbol_ref "optimize_size")
2619                        (const_int 0))
2620                      (const_string "V4SF")
2621                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2622                        (const_int 0))
2623                      (const_string "V2DF")]
2624                    (const_string "DF"))
2625                /* For architectures resolving dependencies on register
2626                   parts we may avoid extra work to zero out upper part
2627                   of register.  */
2628                (eq_attr "alternative" "7")
2629                  (if_then_else
2630                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2631                        (const_int 0))
2632                    (const_string "V2DF")
2633                    (const_string "DF"))]
2634                (const_string "DF")))])
2635
2636 (define_split
2637   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2638         (match_operand:DF 1 "general_operand" ""))]
2639   "reload_completed
2640    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2641    && ! (ANY_FP_REG_P (operands[0]) || 
2642          (GET_CODE (operands[0]) == SUBREG
2643           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2644    && ! (ANY_FP_REG_P (operands[1]) || 
2645          (GET_CODE (operands[1]) == SUBREG
2646           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2647   [(const_int 0)]
2648   "ix86_split_long_move (operands); DONE;")
2649
2650 (define_insn "*swapdf"
2651   [(set (match_operand:DF 0 "register_operand" "+f")
2652         (match_operand:DF 1 "register_operand" "+f"))
2653    (set (match_dup 1)
2654         (match_dup 0))]
2655   "reload_completed || !TARGET_SSE2"
2656 {
2657   if (STACK_TOP_P (operands[0]))
2658     return "fxch\t%1";
2659   else
2660     return "fxch\t%0";
2661 }
2662   [(set_attr "type" "fxch")
2663    (set_attr "mode" "DF")])
2664
2665 (define_expand "movxf"
2666   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2667         (match_operand:XF 1 "general_operand" ""))]
2668   ""
2669   "ix86_expand_move (XFmode, operands); DONE;")
2670
2671 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2672 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2673 ;; Pushing using integer instructions is longer except for constants
2674 ;; and direct memory references.
2675 ;; (assuming that any given constant is pushed only once, but this ought to be
2676 ;;  handled elsewhere).
2677
2678 (define_insn "*pushxf_nointeger"
2679   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2680         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2681   "optimize_size"
2682 {
2683   /* This insn should be already split before reg-stack.  */
2684   abort ();
2685 }
2686   [(set_attr "type" "multi")
2687    (set_attr "mode" "XF,SI,SI")])
2688
2689 (define_insn "*pushxf_integer"
2690   [(set (match_operand:XF 0 "push_operand" "=<,<")
2691         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2692   "!optimize_size"
2693 {
2694   /* This insn should be already split before reg-stack.  */
2695   abort ();
2696 }
2697   [(set_attr "type" "multi")
2698    (set_attr "mode" "XF,SI")])
2699
2700 (define_split
2701   [(set (match_operand 0 "push_operand" "")
2702         (match_operand 1 "general_operand" ""))]
2703   "reload_completed
2704    && (GET_MODE (operands[0]) == XFmode
2705        || GET_MODE (operands[0]) == DFmode)
2706    && !ANY_FP_REG_P (operands[1])"
2707   [(const_int 0)]
2708   "ix86_split_long_move (operands); DONE;")
2709
2710 (define_split
2711   [(set (match_operand:XF 0 "push_operand" "")
2712         (match_operand:XF 1 "any_fp_register_operand" ""))]
2713   "!TARGET_64BIT"
2714   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2715    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2716   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2717
2718 (define_split
2719   [(set (match_operand:XF 0 "push_operand" "")
2720         (match_operand:XF 1 "any_fp_register_operand" ""))]
2721   "TARGET_64BIT"
2722   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2723    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2724   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2725
2726 ;; Do not use integer registers when optimizing for size
2727 (define_insn "*movxf_nointeger"
2728   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2729         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2730   "optimize_size
2731    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2732    && (reload_in_progress || reload_completed
2733        || GET_CODE (operands[1]) != CONST_DOUBLE
2734        || memory_operand (operands[0], XFmode))" 
2735 {
2736   switch (which_alternative)
2737     {
2738     case 0:
2739       return output_387_reg_move (insn, operands);
2740
2741     case 1:
2742       /* There is no non-popping store to memory for XFmode.  So if
2743          we need one, follow the store with a load.  */
2744       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2745         return "fstp%z0\t%y0\;fld%z0\t%y0";
2746       else
2747         return "fstp%z0\t%y0";
2748
2749     case 2:
2750       return standard_80387_constant_opcode (operands[1]);
2751
2752     case 3: case 4:
2753       return "#";
2754     }
2755   abort();
2756 }
2757   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2758    (set_attr "mode" "XF,XF,XF,SI,SI")])
2759
2760 (define_insn "*movxf_integer"
2761   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2762         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2763   "!optimize_size
2764    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2765    && (reload_in_progress || reload_completed
2766        || GET_CODE (operands[1]) != CONST_DOUBLE
2767        || memory_operand (operands[0], XFmode))" 
2768 {
2769   switch (which_alternative)
2770     {
2771     case 0:
2772       return output_387_reg_move (insn, operands);
2773
2774     case 1:
2775       /* There is no non-popping store to memory for XFmode.  So if
2776          we need one, follow the store with a load.  */
2777       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2778         return "fstp%z0\t%y0\;fld%z0\t%y0";
2779       else
2780         return "fstp%z0\t%y0";
2781
2782     case 2:
2783       return standard_80387_constant_opcode (operands[1]);
2784
2785     case 3: case 4:
2786       return "#";
2787     }
2788   abort();
2789 }
2790   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2791    (set_attr "mode" "XF,XF,XF,SI,SI")])
2792
2793 (define_split
2794   [(set (match_operand 0 "nonimmediate_operand" "")
2795         (match_operand 1 "general_operand" ""))]
2796   "reload_completed
2797    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2798    && GET_MODE (operands[0]) == XFmode
2799    && ! (ANY_FP_REG_P (operands[0]) || 
2800          (GET_CODE (operands[0]) == SUBREG
2801           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2802    && ! (ANY_FP_REG_P (operands[1]) || 
2803          (GET_CODE (operands[1]) == SUBREG
2804           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2805   [(const_int 0)]
2806   "ix86_split_long_move (operands); DONE;")
2807
2808 (define_split
2809   [(set (match_operand 0 "register_operand" "")
2810         (match_operand 1 "memory_operand" ""))]
2811   "reload_completed
2812    && GET_CODE (operands[1]) == MEM
2813    && (GET_MODE (operands[0]) == XFmode
2814        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2815    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2816    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2817   [(set (match_dup 0) (match_dup 1))]
2818 {
2819   rtx c = get_pool_constant (XEXP (operands[1], 0));
2820   rtx r = operands[0];
2821
2822   if (GET_CODE (r) == SUBREG)
2823     r = SUBREG_REG (r);
2824
2825   if (SSE_REG_P (r))
2826     {
2827       if (!standard_sse_constant_p (c))
2828         FAIL;
2829     }
2830   else if (FP_REG_P (r))
2831     {
2832       if (!standard_80387_constant_p (c))
2833         FAIL;
2834     }
2835   else if (MMX_REG_P (r))
2836     FAIL;
2837
2838   operands[1] = c;
2839 })
2840
2841 (define_insn "swapxf"
2842   [(set (match_operand:XF 0 "register_operand" "+f")
2843         (match_operand:XF 1 "register_operand" "+f"))
2844    (set (match_dup 1)
2845         (match_dup 0))]
2846   ""
2847 {
2848   if (STACK_TOP_P (operands[0]))
2849     return "fxch\t%1";
2850   else
2851     return "fxch\t%0";
2852 }
2853   [(set_attr "type" "fxch")
2854    (set_attr "mode" "XF")])
2855 \f
2856 ;; Zero extension instructions
2857
2858 (define_expand "zero_extendhisi2"
2859   [(set (match_operand:SI 0 "register_operand" "")
2860      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2861   ""
2862 {
2863   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2864     {
2865       operands[1] = force_reg (HImode, operands[1]);
2866       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2867       DONE;
2868     }
2869 })
2870
2871 (define_insn "zero_extendhisi2_and"
2872   [(set (match_operand:SI 0 "register_operand" "=r")
2873      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2874    (clobber (reg:CC FLAGS_REG))]
2875   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2876   "#"
2877   [(set_attr "type" "alu1")
2878    (set_attr "mode" "SI")])
2879
2880 (define_split
2881   [(set (match_operand:SI 0 "register_operand" "")
2882         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2883    (clobber (reg:CC FLAGS_REG))]
2884   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2885   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2886               (clobber (reg:CC FLAGS_REG))])]
2887   "")
2888
2889 (define_insn "*zero_extendhisi2_movzwl"
2890   [(set (match_operand:SI 0 "register_operand" "=r")
2891      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2892   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2893   "movz{wl|x}\t{%1, %0|%0, %1}"
2894   [(set_attr "type" "imovx")
2895    (set_attr "mode" "SI")])
2896
2897 (define_expand "zero_extendqihi2"
2898   [(parallel
2899     [(set (match_operand:HI 0 "register_operand" "")
2900        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2901      (clobber (reg:CC FLAGS_REG))])]
2902   ""
2903   "")
2904
2905 (define_insn "*zero_extendqihi2_and"
2906   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2907      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2908    (clobber (reg:CC FLAGS_REG))]
2909   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2910   "#"
2911   [(set_attr "type" "alu1")
2912    (set_attr "mode" "HI")])
2913
2914 (define_insn "*zero_extendqihi2_movzbw_and"
2915   [(set (match_operand:HI 0 "register_operand" "=r,r")
2916      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2917    (clobber (reg:CC FLAGS_REG))]
2918   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2919   "#"
2920   [(set_attr "type" "imovx,alu1")
2921    (set_attr "mode" "HI")])
2922
2923 (define_insn "*zero_extendqihi2_movzbw"
2924   [(set (match_operand:HI 0 "register_operand" "=r")
2925      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2926   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2927   "movz{bw|x}\t{%1, %0|%0, %1}"
2928   [(set_attr "type" "imovx")
2929    (set_attr "mode" "HI")])
2930
2931 ;; For the movzbw case strip only the clobber
2932 (define_split
2933   [(set (match_operand:HI 0 "register_operand" "")
2934         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2935    (clobber (reg:CC FLAGS_REG))]
2936   "reload_completed 
2937    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2938    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2939   [(set (match_operand:HI 0 "register_operand" "")
2940         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2941
2942 ;; When source and destination does not overlap, clear destination
2943 ;; first and then do the movb
2944 (define_split
2945   [(set (match_operand:HI 0 "register_operand" "")
2946         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2947    (clobber (reg:CC FLAGS_REG))]
2948   "reload_completed
2949    && ANY_QI_REG_P (operands[0])
2950    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2951    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2952   [(set (match_dup 0) (const_int 0))
2953    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2954   "operands[2] = gen_lowpart (QImode, operands[0]);")
2955
2956 ;; Rest is handled by single and.
2957 (define_split
2958   [(set (match_operand:HI 0 "register_operand" "")
2959         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2960    (clobber (reg:CC FLAGS_REG))]
2961   "reload_completed
2962    && true_regnum (operands[0]) == true_regnum (operands[1])"
2963   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2964               (clobber (reg:CC FLAGS_REG))])]
2965   "")
2966
2967 (define_expand "zero_extendqisi2"
2968   [(parallel
2969     [(set (match_operand:SI 0 "register_operand" "")
2970        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2971      (clobber (reg:CC FLAGS_REG))])]
2972   ""
2973   "")
2974
2975 (define_insn "*zero_extendqisi2_and"
2976   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2977      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2978    (clobber (reg:CC FLAGS_REG))]
2979   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2980   "#"
2981   [(set_attr "type" "alu1")
2982    (set_attr "mode" "SI")])
2983
2984 (define_insn "*zero_extendqisi2_movzbw_and"
2985   [(set (match_operand:SI 0 "register_operand" "=r,r")
2986      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2987    (clobber (reg:CC FLAGS_REG))]
2988   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2989   "#"
2990   [(set_attr "type" "imovx,alu1")
2991    (set_attr "mode" "SI")])
2992
2993 (define_insn "*zero_extendqisi2_movzbw"
2994   [(set (match_operand:SI 0 "register_operand" "=r")
2995      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2996   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2997   "movz{bl|x}\t{%1, %0|%0, %1}"
2998   [(set_attr "type" "imovx")
2999    (set_attr "mode" "SI")])
3000
3001 ;; For the movzbl case strip only the clobber
3002 (define_split
3003   [(set (match_operand:SI 0 "register_operand" "")
3004         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3005    (clobber (reg:CC FLAGS_REG))]
3006   "reload_completed 
3007    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3008    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3009   [(set (match_dup 0)
3010         (zero_extend:SI (match_dup 1)))])
3011
3012 ;; When source and destination does not overlap, clear destination
3013 ;; first and then do the movb
3014 (define_split
3015   [(set (match_operand:SI 0 "register_operand" "")
3016         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3017    (clobber (reg:CC FLAGS_REG))]
3018   "reload_completed
3019    && ANY_QI_REG_P (operands[0])
3020    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3021    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3022    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3023   [(set (match_dup 0) (const_int 0))
3024    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3025   "operands[2] = gen_lowpart (QImode, operands[0]);")
3026
3027 ;; Rest is handled by single and.
3028 (define_split
3029   [(set (match_operand:SI 0 "register_operand" "")
3030         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3031    (clobber (reg:CC FLAGS_REG))]
3032   "reload_completed
3033    && true_regnum (operands[0]) == true_regnum (operands[1])"
3034   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3035               (clobber (reg:CC FLAGS_REG))])]
3036   "")
3037
3038 ;; %%% Kill me once multi-word ops are sane.
3039 (define_expand "zero_extendsidi2"
3040   [(set (match_operand:DI 0 "register_operand" "=r")
3041      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3042   ""
3043   "if (!TARGET_64BIT)
3044      {
3045        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3046        DONE;
3047      }
3048   ")
3049
3050 (define_insn "zero_extendsidi2_32"
3051   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3052         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3055   "@
3056    #
3057    #
3058    #
3059    movd\t{%1, %0|%0, %1}
3060    movd\t{%1, %0|%0, %1}"
3061   [(set_attr "mode" "SI,SI,SI,DI,TI")
3062    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3063
3064 (define_insn "*zero_extendsidi2_32_1"
3065   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3066         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3067    (clobber (reg:CC FLAGS_REG))]
3068   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3069   "@
3070    #
3071    #
3072    #
3073    movd\t{%1, %0|%0, %1}
3074    movd\t{%1, %0|%0, %1}"
3075   [(set_attr "mode" "SI,SI,SI,DI,TI")
3076    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3077
3078 (define_insn "zero_extendsidi2_rex64"
3079   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3080      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3081   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3082   "@
3083    mov\t{%k1, %k0|%k0, %k1}
3084    #
3085    movd\t{%1, %0|%0, %1}
3086    movd\t{%1, %0|%0, %1}"
3087   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3088    (set_attr "mode" "SI,DI,DI,TI")])
3089
3090 (define_insn "*zero_extendsidi2_rex64_1"
3091   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3092      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3093   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3094   "@
3095    mov\t{%k1, %k0|%k0, %k1}
3096    #
3097    movd\t{%1, %0|%0, %1}
3098    movd\t{%1, %0|%0, %1}"
3099   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3100    (set_attr "mode" "SI,DI,SI,SI")])
3101
3102 (define_split
3103   [(set (match_operand:DI 0 "memory_operand" "")
3104      (zero_extend:DI (match_dup 0)))]
3105   "TARGET_64BIT"
3106   [(set (match_dup 4) (const_int 0))]
3107   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3108
3109 (define_split 
3110   [(set (match_operand:DI 0 "register_operand" "")
3111         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3112    (clobber (reg:CC FLAGS_REG))]
3113   "!TARGET_64BIT && reload_completed
3114    && true_regnum (operands[0]) == true_regnum (operands[1])"
3115   [(set (match_dup 4) (const_int 0))]
3116   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3117
3118 (define_split 
3119   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3120         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3121    (clobber (reg:CC FLAGS_REG))]
3122   "!TARGET_64BIT && reload_completed
3123    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3124   [(set (match_dup 3) (match_dup 1))
3125    (set (match_dup 4) (const_int 0))]
3126   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3127
3128 (define_insn "zero_extendhidi2"
3129   [(set (match_operand:DI 0 "register_operand" "=r,r")
3130      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3131   "TARGET_64BIT"
3132   "@
3133    movz{wl|x}\t{%1, %k0|%k0, %1}
3134    movz{wq|x}\t{%1, %0|%0, %1}"
3135   [(set_attr "type" "imovx")
3136    (set_attr "mode" "SI,DI")])
3137
3138 (define_insn "zero_extendqidi2"
3139   [(set (match_operand:DI 0 "register_operand" "=r,r")
3140      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3141   "TARGET_64BIT"
3142   "@
3143    movz{bl|x}\t{%1, %k0|%k0, %1}
3144    movz{bq|x}\t{%1, %0|%0, %1}"
3145   [(set_attr "type" "imovx")
3146    (set_attr "mode" "SI,DI")])
3147 \f
3148 ;; Sign extension instructions
3149
3150 (define_expand "extendsidi2"
3151   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3152                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3153               (clobber (reg:CC FLAGS_REG))
3154               (clobber (match_scratch:SI 2 ""))])]
3155   ""
3156 {
3157   if (TARGET_64BIT)
3158     {
3159       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3160       DONE;
3161     }
3162 })
3163
3164 (define_insn "*extendsidi2_1"
3165   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3166         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3167    (clobber (reg:CC FLAGS_REG))
3168    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3169   "!TARGET_64BIT"
3170   "#")
3171
3172 (define_insn "extendsidi2_rex64"
3173   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3174         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3175   "TARGET_64BIT"
3176   "@
3177    {cltq|cdqe}
3178    movs{lq|x}\t{%1,%0|%0, %1}"
3179   [(set_attr "type" "imovx")
3180    (set_attr "mode" "DI")
3181    (set_attr "prefix_0f" "0")
3182    (set_attr "modrm" "0,1")])
3183
3184 (define_insn "extendhidi2"
3185   [(set (match_operand:DI 0 "register_operand" "=r")
3186         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3187   "TARGET_64BIT"
3188   "movs{wq|x}\t{%1,%0|%0, %1}"
3189   [(set_attr "type" "imovx")
3190    (set_attr "mode" "DI")])
3191
3192 (define_insn "extendqidi2"
3193   [(set (match_operand:DI 0 "register_operand" "=r")
3194         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3195   "TARGET_64BIT"
3196   "movs{bq|x}\t{%1,%0|%0, %1}"
3197    [(set_attr "type" "imovx")
3198     (set_attr "mode" "DI")])
3199
3200 ;; Extend to memory case when source register does die.
3201 (define_split 
3202   [(set (match_operand:DI 0 "memory_operand" "")
3203         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3204    (clobber (reg:CC FLAGS_REG))
3205    (clobber (match_operand:SI 2 "register_operand" ""))]
3206   "(reload_completed
3207     && dead_or_set_p (insn, operands[1])
3208     && !reg_mentioned_p (operands[1], operands[0]))"
3209   [(set (match_dup 3) (match_dup 1))
3210    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3211               (clobber (reg:CC FLAGS_REG))])
3212    (set (match_dup 4) (match_dup 1))]
3213   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214
3215 ;; Extend to memory case when source register does not die.
3216 (define_split 
3217   [(set (match_operand:DI 0 "memory_operand" "")
3218         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3219    (clobber (reg:CC FLAGS_REG))
3220    (clobber (match_operand:SI 2 "register_operand" ""))]
3221   "reload_completed"
3222   [(const_int 0)]
3223 {
3224   split_di (&operands[0], 1, &operands[3], &operands[4]);
3225
3226   emit_move_insn (operands[3], operands[1]);
3227
3228   /* Generate a cltd if possible and doing so it profitable.  */
3229   if (true_regnum (operands[1]) == 0
3230       && true_regnum (operands[2]) == 1
3231       && (optimize_size || TARGET_USE_CLTD))
3232     {
3233       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3234     }
3235   else
3236     {
3237       emit_move_insn (operands[2], operands[1]);
3238       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3239     }
3240   emit_move_insn (operands[4], operands[2]);
3241   DONE;
3242 })
3243
3244 ;; Extend to register case.  Optimize case where source and destination
3245 ;; registers match and cases where we can use cltd.
3246 (define_split 
3247   [(set (match_operand:DI 0 "register_operand" "")
3248         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3249    (clobber (reg:CC FLAGS_REG))
3250    (clobber (match_scratch:SI 2 ""))]
3251   "reload_completed"
3252   [(const_int 0)]
3253 {
3254   split_di (&operands[0], 1, &operands[3], &operands[4]);
3255
3256   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3257     emit_move_insn (operands[3], operands[1]);
3258
3259   /* Generate a cltd if possible and doing so it profitable.  */
3260   if (true_regnum (operands[3]) == 0
3261       && (optimize_size || TARGET_USE_CLTD))
3262     {
3263       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3264       DONE;
3265     }
3266
3267   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3268     emit_move_insn (operands[4], operands[1]);
3269
3270   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3271   DONE;
3272 })
3273
3274 (define_insn "extendhisi2"
3275   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3276         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3277   ""
3278 {
3279   switch (get_attr_prefix_0f (insn))
3280     {
3281     case 0:
3282       return "{cwtl|cwde}";
3283     default:
3284       return "movs{wl|x}\t{%1,%0|%0, %1}";
3285     }
3286 }
3287   [(set_attr "type" "imovx")
3288    (set_attr "mode" "SI")
3289    (set (attr "prefix_0f")
3290      ;; movsx is short decodable while cwtl is vector decoded.
3291      (if_then_else (and (eq_attr "cpu" "!k6")
3292                         (eq_attr "alternative" "0"))
3293         (const_string "0")
3294         (const_string "1")))
3295    (set (attr "modrm")
3296      (if_then_else (eq_attr "prefix_0f" "0")
3297         (const_string "0")
3298         (const_string "1")))])
3299
3300 (define_insn "*extendhisi2_zext"
3301   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3302         (zero_extend:DI
3303           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3304   "TARGET_64BIT"
3305 {
3306   switch (get_attr_prefix_0f (insn))
3307     {
3308     case 0:
3309       return "{cwtl|cwde}";
3310     default:
3311       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3312     }
3313 }
3314   [(set_attr "type" "imovx")
3315    (set_attr "mode" "SI")
3316    (set (attr "prefix_0f")
3317      ;; movsx is short decodable while cwtl is vector decoded.
3318      (if_then_else (and (eq_attr "cpu" "!k6")
3319                         (eq_attr "alternative" "0"))
3320         (const_string "0")
3321         (const_string "1")))
3322    (set (attr "modrm")
3323      (if_then_else (eq_attr "prefix_0f" "0")
3324         (const_string "0")
3325         (const_string "1")))])
3326
3327 (define_insn "extendqihi2"
3328   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3329         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3330   ""
3331 {
3332   switch (get_attr_prefix_0f (insn))
3333     {
3334     case 0:
3335       return "{cbtw|cbw}";
3336     default:
3337       return "movs{bw|x}\t{%1,%0|%0, %1}";
3338     }
3339 }
3340   [(set_attr "type" "imovx")
3341    (set_attr "mode" "HI")
3342    (set (attr "prefix_0f")
3343      ;; movsx is short decodable while cwtl is vector decoded.
3344      (if_then_else (and (eq_attr "cpu" "!k6")
3345                         (eq_attr "alternative" "0"))
3346         (const_string "0")
3347         (const_string "1")))
3348    (set (attr "modrm")
3349      (if_then_else (eq_attr "prefix_0f" "0")
3350         (const_string "0")
3351         (const_string "1")))])
3352
3353 (define_insn "extendqisi2"
3354   [(set (match_operand:SI 0 "register_operand" "=r")
3355         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3356   ""
3357   "movs{bl|x}\t{%1,%0|%0, %1}"
3358    [(set_attr "type" "imovx")
3359     (set_attr "mode" "SI")])
3360
3361 (define_insn "*extendqisi2_zext"
3362   [(set (match_operand:DI 0 "register_operand" "=r")
3363         (zero_extend:DI
3364           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3365   "TARGET_64BIT"
3366   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3367    [(set_attr "type" "imovx")
3368     (set_attr "mode" "SI")])
3369 \f
3370 ;; Conversions between float and double.
3371
3372 ;; These are all no-ops in the model used for the 80387.  So just
3373 ;; emit moves.
3374
3375 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3376 (define_insn "*dummy_extendsfdf2"
3377   [(set (match_operand:DF 0 "push_operand" "=<")
3378         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3379   "0"
3380   "#")
3381
3382 (define_split
3383   [(set (match_operand:DF 0 "push_operand" "")
3384         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3385   "!TARGET_64BIT"
3386   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3387    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3388
3389 (define_split
3390   [(set (match_operand:DF 0 "push_operand" "")
3391         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3392   "TARGET_64BIT"
3393   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3394    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3395
3396 (define_insn "*dummy_extendsfxf2"
3397   [(set (match_operand:XF 0 "push_operand" "=<")
3398         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3399   "0"
3400   "#")
3401
3402 (define_split
3403   [(set (match_operand:XF 0 "push_operand" "")
3404         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3405   ""
3406   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3407    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3408   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3409
3410 (define_split
3411   [(set (match_operand:XF 0 "push_operand" "")
3412         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3413   "TARGET_64BIT"
3414   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3415    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3416   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3417
3418 (define_split
3419   [(set (match_operand:XF 0 "push_operand" "")
3420         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3421   ""
3422   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3423    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3424   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3425
3426 (define_split
3427   [(set (match_operand:XF 0 "push_operand" "")
3428         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3429   "TARGET_64BIT"
3430   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3431    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3432   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3433
3434 (define_expand "extendsfdf2"
3435   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3436         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3437   "TARGET_80387 || TARGET_SSE2"
3438 {
3439   /* ??? Needed for compress_float_constant since all fp constants
3440      are LEGITIMATE_CONSTANT_P.  */
3441   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3442     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3443   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3444     operands[1] = force_reg (SFmode, operands[1]);
3445 })
3446
3447 (define_insn "*extendsfdf2_1"
3448   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3449         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3450   "(TARGET_80387 || TARGET_SSE2)
3451    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3452 {
3453   switch (which_alternative)
3454     {
3455     case 0:
3456       return output_387_reg_move (insn, operands);
3457
3458     case 1:
3459       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3460         return "fstp%z0\t%y0";
3461       else
3462         return "fst%z0\t%y0";
3463
3464     case 2:
3465       return "cvtss2sd\t{%1, %0|%0, %1}";
3466
3467     default:
3468       abort ();
3469     }
3470 }
3471   [(set_attr "type" "fmov,fmov,ssecvt")
3472    (set_attr "mode" "SF,XF,DF")])
3473
3474 (define_insn "*extendsfdf2_1_sse_only"
3475   [(set (match_operand:DF 0 "register_operand" "=Y")
3476         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3477   "!TARGET_80387 && TARGET_SSE2
3478    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3479   "cvtss2sd\t{%1, %0|%0, %1}"
3480   [(set_attr "type" "ssecvt")
3481    (set_attr "mode" "DF")])
3482
3483 (define_expand "extendsfxf2"
3484   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3485         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3486   "TARGET_80387"
3487 {
3488   /* ??? Needed for compress_float_constant since all fp constants
3489      are LEGITIMATE_CONSTANT_P.  */
3490   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3491     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3492   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3493     operands[1] = force_reg (SFmode, operands[1]);
3494 })
3495
3496 (define_insn "*extendsfxf2_1"
3497   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3498         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3499   "TARGET_80387
3500    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3501 {
3502   switch (which_alternative)
3503     {
3504     case 0:
3505       return output_387_reg_move (insn, operands);
3506
3507     case 1:
3508       /* There is no non-popping store to memory for XFmode.  So if
3509          we need one, follow the store with a load.  */
3510       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3511         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3512       else
3513         return "fstp%z0\t%y0";
3514
3515     default:
3516       abort ();
3517     }
3518 }
3519   [(set_attr "type" "fmov")
3520    (set_attr "mode" "SF,XF")])
3521
3522 (define_expand "extenddfxf2"
3523   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3524         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3525   "TARGET_80387"
3526 {
3527   /* ??? Needed for compress_float_constant since all fp constants
3528      are LEGITIMATE_CONSTANT_P.  */
3529   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3530     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3531   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3532     operands[1] = force_reg (DFmode, operands[1]);
3533 })
3534
3535 (define_insn "*extenddfxf2_1"
3536   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3537         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3538   "TARGET_80387
3539    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3540 {
3541   switch (which_alternative)
3542     {
3543     case 0:
3544       return output_387_reg_move (insn, operands);
3545
3546     case 1:
3547       /* There is no non-popping store to memory for XFmode.  So if
3548          we need one, follow the store with a load.  */
3549       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3550         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3551       else
3552         return "fstp%z0\t%y0";
3553
3554     default:
3555       abort ();
3556     }
3557 }
3558   [(set_attr "type" "fmov")
3559    (set_attr "mode" "DF,XF")])
3560
3561 ;; %%% This seems bad bad news.
3562 ;; This cannot output into an f-reg because there is no way to be sure
3563 ;; of truncating in that case.  Otherwise this is just like a simple move
3564 ;; insn.  So we pretend we can output to a reg in order to get better
3565 ;; register preferencing, but we really use a stack slot.
3566
3567 (define_expand "truncdfsf2"
3568   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3569                    (float_truncate:SF
3570                     (match_operand:DF 1 "register_operand" "")))
3571               (clobber (match_dup 2))])]
3572   "TARGET_80387 || TARGET_SSE2"
3573   "
3574    if (!TARGET_80387)
3575      {
3576         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3577         DONE;
3578      }
3579    else if (flag_unsafe_math_optimizations)
3580      {
3581         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3582         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3583         if (reg != operands[0])
3584           emit_move_insn (operands[0], reg);
3585         DONE;
3586      }
3587    else
3588      operands[2] = assign_386_stack_local (SFmode, 0);
3589 ")
3590
3591 (define_insn "truncdfsf2_noop"
3592   [(set (match_operand:SF 0 "register_operand" "=f")
3593         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3594   "TARGET_80387 && flag_unsafe_math_optimizations"
3595 {
3596   return output_387_reg_move (insn, operands);
3597 }
3598   [(set_attr "type" "fmov")
3599    (set_attr "mode" "SF")])
3600
3601 (define_insn "*truncdfsf2_1"
3602   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3603         (float_truncate:SF
3604          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3605    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3606   "TARGET_80387 && !TARGET_SSE2"
3607 {
3608   switch (which_alternative)
3609     {
3610     case 0:
3611       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3612         return "fstp%z0\t%y0";
3613       else
3614         return "fst%z0\t%y0";
3615     default:
3616       abort ();
3617     }
3618 }
3619   [(set_attr "type" "fmov,multi,multi,multi")
3620    (set_attr "mode" "SF,SF,SF,SF")])
3621
3622 (define_insn "*truncdfsf2_1_sse"
3623   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3624         (float_truncate:SF
3625          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3626    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3627   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3628 {
3629   switch (which_alternative)
3630     {
3631     case 0:
3632       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3633         return "fstp%z0\t%y0";
3634       else
3635         return "fst%z0\t%y0";
3636     case 4:
3637       return "#";
3638     default:
3639       abort ();
3640     }
3641 }
3642   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3643    (set_attr "mode" "SF,SF,SF,SF,DF")])
3644
3645 (define_insn "*truncdfsf2_1_sse_nooverlap"
3646   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3647         (float_truncate:SF
3648          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3649    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3650   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3651 {
3652   switch (which_alternative)
3653     {
3654     case 0:
3655       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3656         return "fstp%z0\t%y0";
3657       else
3658         return "fst%z0\t%y0";
3659     case 4:
3660       return "#";
3661     default:
3662       abort ();
3663     }
3664 }
3665   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3666    (set_attr "mode" "SF,SF,SF,SF,DF")])
3667
3668 (define_insn "*truncdfsf2_2"
3669   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3670         (float_truncate:SF
3671          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3672   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3673    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3674 {
3675   switch (which_alternative)
3676     {
3677     case 0:
3678     case 1:
3679       return "cvtsd2ss\t{%1, %0|%0, %1}";
3680     case 2:
3681       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3682         return "fstp%z0\t%y0";
3683       else
3684         return "fst%z0\t%y0";
3685     default:
3686       abort ();
3687     }
3688 }
3689   [(set_attr "type" "ssecvt,ssecvt,fmov")
3690    (set_attr "athlon_decode" "vector,double,*")
3691    (set_attr "mode" "SF,SF,SF")])
3692
3693 (define_insn "*truncdfsf2_2_nooverlap"
3694   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3695         (float_truncate:SF
3696          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3697   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3698    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3699 {
3700   switch (which_alternative)
3701     {
3702     case 0:
3703       return "#";
3704     case 1:
3705       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3706         return "fstp%z0\t%y0";
3707       else
3708         return "fst%z0\t%y0";
3709     default:
3710       abort ();
3711     }
3712 }
3713   [(set_attr "type" "ssecvt,fmov")
3714    (set_attr "mode" "DF,SF")])
3715
3716 (define_insn "*truncdfsf2_3"
3717   [(set (match_operand:SF 0 "memory_operand" "=m")
3718         (float_truncate:SF
3719          (match_operand:DF 1 "register_operand" "f")))]
3720   "TARGET_80387"
3721 {
3722   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3723     return "fstp%z0\t%y0";
3724   else
3725     return "fst%z0\t%y0";
3726 }
3727   [(set_attr "type" "fmov")
3728    (set_attr "mode" "SF")])
3729
3730 (define_insn "truncdfsf2_sse_only"
3731   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3732         (float_truncate:SF
3733          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3734   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3735   "cvtsd2ss\t{%1, %0|%0, %1}"
3736   [(set_attr "type" "ssecvt")
3737    (set_attr "athlon_decode" "vector,double")
3738    (set_attr "mode" "SF")])
3739
3740 (define_insn "*truncdfsf2_sse_only_nooverlap"
3741   [(set (match_operand:SF 0 "register_operand" "=&Y")
3742         (float_truncate:SF
3743          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3744   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3745   "#"
3746   [(set_attr "type" "ssecvt")
3747    (set_attr "mode" "DF")])
3748
3749 (define_split
3750   [(set (match_operand:SF 0 "memory_operand" "")
3751         (float_truncate:SF
3752          (match_operand:DF 1 "register_operand" "")))
3753    (clobber (match_operand:SF 2 "memory_operand" ""))]
3754   "TARGET_80387"
3755   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3756   "")
3757
3758 ; Avoid possible reformatting penalty on the destination by first
3759 ; zeroing it out
3760 (define_split
3761   [(set (match_operand:SF 0 "register_operand" "")
3762         (float_truncate:SF
3763          (match_operand:DF 1 "nonimmediate_operand" "")))
3764    (clobber (match_operand 2 "" ""))]
3765   "TARGET_80387 && reload_completed
3766    && SSE_REG_P (operands[0])
3767    && !STACK_REG_P (operands[1])"
3768   [(const_int 0)]
3769 {
3770   rtx src, dest;
3771   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3772     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3773   else
3774     {
3775       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3776       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3777       /* simplify_gen_subreg refuses to widen memory references.  */
3778       if (GET_CODE (src) == SUBREG)
3779         alter_subreg (&src);
3780       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3781         abort ();
3782       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3783       emit_insn (gen_cvtsd2ss (dest, dest, src));
3784     }
3785   DONE;
3786 })
3787
3788 (define_split
3789   [(set (match_operand:SF 0 "register_operand" "")
3790         (float_truncate:SF
3791          (match_operand:DF 1 "nonimmediate_operand" "")))]
3792   "TARGET_80387 && reload_completed
3793    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3794   [(const_int 0)]
3795 {
3796   rtx src, dest;
3797   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3798   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3799   /* simplify_gen_subreg refuses to widen memory references.  */
3800   if (GET_CODE (src) == SUBREG)
3801     alter_subreg (&src);
3802   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3803     abort ();
3804   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3805   emit_insn (gen_cvtsd2ss (dest, dest, src));
3806   DONE;
3807 })
3808
3809 (define_split
3810   [(set (match_operand:SF 0 "register_operand" "")
3811         (float_truncate:SF
3812          (match_operand:DF 1 "fp_register_operand" "")))
3813    (clobber (match_operand:SF 2 "memory_operand" ""))]
3814   "TARGET_80387 && reload_completed"
3815   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3816    (set (match_dup 0) (match_dup 2))]
3817   "")
3818
3819 (define_expand "truncxfsf2"
3820   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3821                    (float_truncate:SF
3822                     (match_operand:XF 1 "register_operand" "")))
3823               (clobber (match_dup 2))])]
3824   "TARGET_80387"
3825   "
3826   if (flag_unsafe_math_optimizations)
3827     {
3828       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3829       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3830       if (reg != operands[0])
3831         emit_move_insn (operands[0], reg);
3832       DONE;
3833     }
3834   else
3835     operands[2] = assign_386_stack_local (SFmode, 0);
3836   ")
3837
3838 (define_insn "truncxfsf2_noop"
3839   [(set (match_operand:SF 0 "register_operand" "=f")
3840         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3841   "TARGET_80387 && flag_unsafe_math_optimizations"
3842 {
3843   return output_387_reg_move (insn, operands);
3844 }
3845   [(set_attr "type" "fmov")
3846    (set_attr "mode" "SF")])
3847
3848 (define_insn "*truncxfsf2_1"
3849   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3850         (float_truncate:SF
3851          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3852    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3853   "TARGET_80387"
3854 {
3855   switch (which_alternative)
3856     {
3857     case 0:
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     default:
3863       abort();
3864     }
3865 }
3866   [(set_attr "type" "fmov,multi,multi,multi")
3867    (set_attr "mode" "SF")])
3868
3869 (define_insn "*truncxfsf2_2"
3870   [(set (match_operand:SF 0 "memory_operand" "=m")
3871         (float_truncate:SF
3872          (match_operand:XF 1 "register_operand" "f")))]
3873   "TARGET_80387"
3874 {
3875   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876     return "fstp%z0\t%y0";
3877   else
3878     return "fst%z0\t%y0";
3879 }
3880   [(set_attr "type" "fmov")
3881    (set_attr "mode" "SF")])
3882
3883 (define_split
3884   [(set (match_operand:SF 0 "memory_operand" "")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "")))
3887    (clobber (match_operand:SF 2 "memory_operand" ""))]
3888   "TARGET_80387"
3889   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3890   "")
3891
3892 (define_split
3893   [(set (match_operand:SF 0 "register_operand" "")
3894         (float_truncate:SF
3895          (match_operand:XF 1 "register_operand" "")))
3896    (clobber (match_operand:SF 2 "memory_operand" ""))]
3897   "TARGET_80387 && reload_completed"
3898   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3899    (set (match_dup 0) (match_dup 2))]
3900   "")
3901
3902 (define_expand "truncxfdf2"
3903   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3904                    (float_truncate:DF
3905                     (match_operand:XF 1 "register_operand" "")))
3906               (clobber (match_dup 2))])]
3907   "TARGET_80387"
3908   "
3909   if (flag_unsafe_math_optimizations)
3910     {
3911       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3912       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3913       if (reg != operands[0])
3914         emit_move_insn (operands[0], reg);
3915       DONE;
3916     }
3917   else
3918     operands[2] = assign_386_stack_local (DFmode, 0);
3919   ")
3920
3921 (define_insn "truncxfdf2_noop"
3922   [(set (match_operand:DF 0 "register_operand" "=f")
3923         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3924   "TARGET_80387 && flag_unsafe_math_optimizations"
3925 {
3926   return output_387_reg_move (insn, operands);
3927 }
3928   [(set_attr "type" "fmov")
3929    (set_attr "mode" "DF")])
3930
3931 (define_insn "*truncxfdf2_1"
3932   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3933         (float_truncate:DF
3934          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3935    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3936   "TARGET_80387"
3937 {
3938   switch (which_alternative)
3939     {
3940     case 0:
3941       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3942         return "fstp%z0\t%y0";
3943       else
3944         return "fst%z0\t%y0";
3945     default:
3946       abort();
3947     }
3948   abort ();
3949 }
3950   [(set_attr "type" "fmov,multi,multi,multi")
3951    (set_attr "mode" "DF")])
3952
3953 (define_insn "*truncxfdf2_2"
3954   [(set (match_operand:DF 0 "memory_operand" "=m")
3955         (float_truncate:DF
3956           (match_operand:XF 1 "register_operand" "f")))]
3957   "TARGET_80387"
3958 {
3959   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3960     return "fstp%z0\t%y0";
3961   else
3962     return "fst%z0\t%y0";
3963 }
3964   [(set_attr "type" "fmov")
3965    (set_attr "mode" "DF")])
3966
3967 (define_split
3968   [(set (match_operand:DF 0 "memory_operand" "")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "")))
3971    (clobber (match_operand:DF 2 "memory_operand" ""))]
3972   "TARGET_80387"
3973   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3974   "")
3975
3976 (define_split
3977   [(set (match_operand:DF 0 "register_operand" "")
3978         (float_truncate:DF
3979          (match_operand:XF 1 "register_operand" "")))
3980    (clobber (match_operand:DF 2 "memory_operand" ""))]
3981   "TARGET_80387 && reload_completed"
3982   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3983    (set (match_dup 0) (match_dup 2))]
3984   "")
3985
3986 \f
3987 ;; %%% Break up all these bad boys.
3988
3989 ;; Signed conversion to DImode.
3990
3991 (define_expand "fix_truncxfdi2"
3992   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3993                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3994               (clobber (reg:CC FLAGS_REG))])]
3995   "TARGET_80387"
3996   "")
3997
3998 (define_expand "fix_truncdfdi2"
3999   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4000                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4001               (clobber (reg:CC FLAGS_REG))])]
4002   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4003 {
4004   if (TARGET_64BIT && TARGET_SSE2)
4005    {
4006      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4007      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4008      if (out != operands[0])
4009         emit_move_insn (operands[0], out);
4010      DONE;
4011    }
4012 })
4013
4014 (define_expand "fix_truncsfdi2"
4015   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4016                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4017               (clobber (reg:CC FLAGS_REG))])] 
4018   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4019 {
4020   if (TARGET_SSE && TARGET_64BIT)
4021    {
4022      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4023      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4024      if (out != operands[0])
4025         emit_move_insn (operands[0], out);
4026      DONE;
4027    }
4028 })
4029
4030 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4031 ;; of the machinery.
4032 (define_insn_and_split "*fix_truncdi_1"
4033   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4034         (fix:DI (match_operand 1 "register_operand" "f,f")))
4035    (clobber (reg:CC FLAGS_REG))]
4036   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4037    && !reload_completed && !reload_in_progress
4038    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4039   "#"
4040   "&& 1"
4041   [(const_int 0)]
4042 {
4043   ix86_optimize_mode_switching = 1;
4044   operands[2] = assign_386_stack_local (HImode, 1);
4045   operands[3] = assign_386_stack_local (HImode, 2);
4046   if (memory_operand (operands[0], VOIDmode))
4047     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4048                                        operands[2], operands[3]));
4049   else
4050     {
4051       operands[4] = assign_386_stack_local (DImode, 0);
4052       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4053                                            operands[2], operands[3],
4054                                            operands[4]));
4055     }
4056   DONE;
4057 }
4058   [(set_attr "type" "fistp")
4059    (set_attr "i387_cw" "trunc")
4060    (set_attr "mode" "DI")])
4061
4062 (define_insn "fix_truncdi_nomemory"
4063   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4064         (fix:DI (match_operand 1 "register_operand" "f,f")))
4065    (use (match_operand:HI 2 "memory_operand" "m,m"))
4066    (use (match_operand:HI 3 "memory_operand" "m,m"))
4067    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4068    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4069   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4070    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4071   "#"
4072   [(set_attr "type" "fistp")
4073    (set_attr "i387_cw" "trunc")
4074    (set_attr "mode" "DI")])
4075
4076 (define_insn "fix_truncdi_memory"
4077   [(set (match_operand:DI 0 "memory_operand" "=m")
4078         (fix:DI (match_operand 1 "register_operand" "f")))
4079    (use (match_operand:HI 2 "memory_operand" "m"))
4080    (use (match_operand:HI 3 "memory_operand" "m"))
4081    (clobber (match_scratch:DF 4 "=&1f"))]
4082   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4083    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4084   "* return output_fix_trunc (insn, operands);"
4085   [(set_attr "type" "fistp")
4086    (set_attr "i387_cw" "trunc")
4087    (set_attr "mode" "DI")])
4088
4089 (define_split 
4090   [(set (match_operand:DI 0 "register_operand" "")
4091         (fix:DI (match_operand 1 "register_operand" "")))
4092    (use (match_operand:HI 2 "memory_operand" ""))
4093    (use (match_operand:HI 3 "memory_operand" ""))
4094    (clobber (match_operand:DI 4 "memory_operand" ""))
4095    (clobber (match_scratch 5 ""))]
4096   "reload_completed"
4097   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4098               (use (match_dup 2))
4099               (use (match_dup 3))
4100               (clobber (match_dup 5))])
4101    (set (match_dup 0) (match_dup 4))]
4102   "")
4103
4104 (define_split 
4105   [(set (match_operand:DI 0 "memory_operand" "")
4106         (fix:DI (match_operand 1 "register_operand" "")))
4107    (use (match_operand:HI 2 "memory_operand" ""))
4108    (use (match_operand:HI 3 "memory_operand" ""))
4109    (clobber (match_operand:DI 4 "memory_operand" ""))
4110    (clobber (match_scratch 5 ""))]
4111   "reload_completed"
4112   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4113               (use (match_dup 2))
4114               (use (match_dup 3))
4115               (clobber (match_dup 5))])]
4116   "")
4117
4118 ;; When SSE available, it is always faster to use it!
4119 (define_insn "fix_truncsfdi_sse"
4120   [(set (match_operand:DI 0 "register_operand" "=r,r")
4121         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4122   "TARGET_64BIT && TARGET_SSE"
4123   "cvttss2si{q}\t{%1, %0|%0, %1}"
4124   [(set_attr "type" "sseicvt")
4125    (set_attr "mode" "SF")
4126    (set_attr "athlon_decode" "double,vector")])
4127
4128 ;; Avoid vector decoded form of the instruction.
4129 (define_peephole2
4130   [(match_scratch:SF 2 "x")
4131    (set (match_operand:DI 0 "register_operand" "")
4132         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4133   "TARGET_K8 && !optimize_size"
4134   [(set (match_dup 2) (match_dup 1))
4135    (set (match_dup 0) (fix:DI (match_dup 2)))]
4136   "")
4137
4138 (define_insn "fix_truncdfdi_sse"
4139   [(set (match_operand:DI 0 "register_operand" "=r,r")
4140         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4141   "TARGET_64BIT && TARGET_SSE2"
4142   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4143   [(set_attr "type" "sseicvt,sseicvt")
4144    (set_attr "mode" "DF")
4145    (set_attr "athlon_decode" "double,vector")])
4146
4147 ;; Avoid vector decoded form of the instruction.
4148 (define_peephole2
4149   [(match_scratch:DF 2 "Y")
4150    (set (match_operand:DI 0 "register_operand" "")
4151         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4152   "TARGET_K8 && !optimize_size"
4153   [(set (match_dup 2) (match_dup 1))
4154    (set (match_dup 0) (fix:DI (match_dup 2)))]
4155   "")
4156
4157 ;; Signed conversion to SImode.
4158
4159 (define_expand "fix_truncxfsi2"
4160   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4161                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4162               (clobber (reg:CC FLAGS_REG))])]
4163   "TARGET_80387"
4164   "")
4165
4166 (define_expand "fix_truncdfsi2"
4167   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4168                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4169               (clobber (reg:CC FLAGS_REG))])]
4170   "TARGET_80387 || TARGET_SSE2"
4171 {
4172   if (TARGET_SSE2)
4173    {
4174      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4175      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4176      if (out != operands[0])
4177         emit_move_insn (operands[0], out);
4178      DONE;
4179    }
4180 })
4181
4182 (define_expand "fix_truncsfsi2"
4183   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4184                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4185               (clobber (reg:CC FLAGS_REG))])] 
4186   "TARGET_80387 || TARGET_SSE"
4187 {
4188   if (TARGET_SSE)
4189    {
4190      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4191      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4192      if (out != operands[0])
4193         emit_move_insn (operands[0], out);
4194      DONE;
4195    }
4196 })
4197
4198 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4199 ;; of the machinery.
4200 (define_insn_and_split "*fix_truncsi_1"
4201   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4202         (fix:SI (match_operand 1 "register_operand" "f,f")))
4203    (clobber (reg:CC FLAGS_REG))]
4204   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4205    && !reload_completed && !reload_in_progress
4206    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4207   "#"
4208   "&& 1"
4209   [(const_int 0)]
4210 {
4211   ix86_optimize_mode_switching = 1;
4212   operands[2] = assign_386_stack_local (HImode, 1);
4213   operands[3] = assign_386_stack_local (HImode, 2);
4214   if (memory_operand (operands[0], VOIDmode))
4215     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4216                                        operands[2], operands[3]));
4217   else
4218     {
4219       operands[4] = assign_386_stack_local (SImode, 0);
4220       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4221                                            operands[2], operands[3],
4222                                            operands[4]));
4223     }
4224   DONE;
4225 }
4226   [(set_attr "type" "fistp")
4227    (set_attr "i387_cw" "trunc")
4228    (set_attr "mode" "SI")])
4229
4230 (define_insn "fix_truncsi_nomemory"
4231   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4232         (fix:SI (match_operand 1 "register_operand" "f,f")))
4233    (use (match_operand:HI 2 "memory_operand" "m,m"))
4234    (use (match_operand:HI 3 "memory_operand" "m,m"))
4235    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4236   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4237    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4238   "#"
4239   [(set_attr "type" "fistp")
4240    (set_attr "i387_cw" "trunc")
4241    (set_attr "mode" "SI")])
4242
4243 (define_insn "fix_truncsi_memory"
4244   [(set (match_operand:SI 0 "memory_operand" "=m")
4245         (fix:SI (match_operand 1 "register_operand" "f")))
4246    (use (match_operand:HI 2 "memory_operand" "m"))
4247    (use (match_operand:HI 3 "memory_operand" "m"))]
4248   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4249    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4250   "* return output_fix_trunc (insn, operands);"
4251   [(set_attr "type" "fistp")
4252    (set_attr "i387_cw" "trunc")
4253    (set_attr "mode" "SI")])
4254
4255 ;; When SSE available, it is always faster to use it!
4256 (define_insn "fix_truncsfsi_sse"
4257   [(set (match_operand:SI 0 "register_operand" "=r,r")
4258         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4259   "TARGET_SSE"
4260   "cvttss2si\t{%1, %0|%0, %1}"
4261   [(set_attr "type" "sseicvt")
4262    (set_attr "mode" "DF")
4263    (set_attr "athlon_decode" "double,vector")])
4264
4265 ;; Avoid vector decoded form of the instruction.
4266 (define_peephole2
4267   [(match_scratch:SF 2 "x")
4268    (set (match_operand:SI 0 "register_operand" "")
4269         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4270   "TARGET_K8 && !optimize_size"
4271   [(set (match_dup 2) (match_dup 1))
4272    (set (match_dup 0) (fix:SI (match_dup 2)))]
4273   "")
4274
4275 (define_insn "fix_truncdfsi_sse"
4276   [(set (match_operand:SI 0 "register_operand" "=r,r")
4277         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4278   "TARGET_SSE2"
4279   "cvttsd2si\t{%1, %0|%0, %1}"
4280   [(set_attr "type" "sseicvt")
4281    (set_attr "mode" "DF")
4282    (set_attr "athlon_decode" "double,vector")])
4283
4284 ;; Avoid vector decoded form of the instruction.
4285 (define_peephole2
4286   [(match_scratch:DF 2 "Y")
4287    (set (match_operand:SI 0 "register_operand" "")
4288         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4289   "TARGET_K8 && !optimize_size"
4290   [(set (match_dup 2) (match_dup 1))
4291    (set (match_dup 0) (fix:SI (match_dup 2)))]
4292   "")
4293
4294 (define_split 
4295   [(set (match_operand:SI 0 "register_operand" "")
4296         (fix:SI (match_operand 1 "register_operand" "")))
4297    (use (match_operand:HI 2 "memory_operand" ""))
4298    (use (match_operand:HI 3 "memory_operand" ""))
4299    (clobber (match_operand:SI 4 "memory_operand" ""))]
4300   "reload_completed"
4301   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4302               (use (match_dup 2))
4303               (use (match_dup 3))])
4304    (set (match_dup 0) (match_dup 4))]
4305   "")
4306
4307 (define_split 
4308   [(set (match_operand:SI 0 "memory_operand" "")
4309         (fix:SI (match_operand 1 "register_operand" "")))
4310    (use (match_operand:HI 2 "memory_operand" ""))
4311    (use (match_operand:HI 3 "memory_operand" ""))
4312    (clobber (match_operand:SI 4 "memory_operand" ""))]
4313   "reload_completed"
4314   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4315               (use (match_dup 2))
4316               (use (match_dup 3))])]
4317   "")
4318
4319 ;; Signed conversion to HImode.
4320
4321 (define_expand "fix_truncxfhi2"
4322   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4323                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4324               (clobber (reg:CC FLAGS_REG))])] 
4325   "TARGET_80387"
4326   "")
4327
4328 (define_expand "fix_truncdfhi2"
4329   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4330                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4331               (clobber (reg:CC FLAGS_REG))])]
4332   "TARGET_80387 && !TARGET_SSE2"
4333   "")
4334
4335 (define_expand "fix_truncsfhi2"
4336   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4337                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4338                (clobber (reg:CC FLAGS_REG))])]
4339   "TARGET_80387 && !TARGET_SSE"
4340   "")
4341
4342 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4343 ;; of the machinery.
4344 (define_insn_and_split "*fix_trunchi_1"
4345   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4346         (fix:HI (match_operand 1 "register_operand" "f,f")))
4347    (clobber (reg:CC FLAGS_REG))]
4348   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4349    && !reload_completed && !reload_in_progress
4350    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4351   "#"
4352   "&& 1"
4353   [(const_int 0)]
4354 {
4355   ix86_optimize_mode_switching = 1;
4356   operands[2] = assign_386_stack_local (HImode, 1);
4357   operands[3] = assign_386_stack_local (HImode, 2);
4358   if (memory_operand (operands[0], VOIDmode))
4359     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4360                                        operands[2], operands[3]));
4361   else
4362     {
4363       operands[4] = assign_386_stack_local (HImode, 0);
4364       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4365                                            operands[2], operands[3],
4366                                            operands[4]));
4367     }
4368   DONE;
4369 }
4370   [(set_attr "type" "fistp")
4371    (set_attr "i387_cw" "trunc")
4372    (set_attr "mode" "HI")])
4373
4374 (define_insn "fix_trunchi_nomemory"
4375   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4376         (fix:HI (match_operand 1 "register_operand" "f,f")))
4377    (use (match_operand:HI 2 "memory_operand" "m,m"))
4378    (use (match_operand:HI 3 "memory_operand" "m,m"))
4379    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4380   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4381    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4382   "#"
4383   [(set_attr "type" "fistp")
4384    (set_attr "i387_cw" "trunc")
4385    (set_attr "mode" "HI")])
4386
4387 (define_insn "fix_trunchi_memory"
4388   [(set (match_operand:HI 0 "memory_operand" "=m")
4389         (fix:HI (match_operand 1 "register_operand" "f")))
4390    (use (match_operand:HI 2 "memory_operand" "m"))
4391    (use (match_operand:HI 3 "memory_operand" "m"))]
4392   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4393    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4394   "* return output_fix_trunc (insn, operands);"
4395   [(set_attr "type" "fistp")
4396    (set_attr "i387_cw" "trunc")
4397    (set_attr "mode" "HI")])
4398
4399 (define_split 
4400   [(set (match_operand:HI 0 "memory_operand" "")
4401         (fix:HI (match_operand 1 "register_operand" "")))
4402    (use (match_operand:HI 2 "memory_operand" ""))
4403    (use (match_operand:HI 3 "memory_operand" ""))
4404    (clobber (match_operand:HI 4 "memory_operand" ""))]
4405   "reload_completed"
4406   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4407               (use (match_dup 2))
4408               (use (match_dup 3))])]
4409   "")
4410
4411 (define_split 
4412   [(set (match_operand:HI 0 "register_operand" "")
4413         (fix:HI (match_operand 1 "register_operand" "")))
4414    (use (match_operand:HI 2 "memory_operand" ""))
4415    (use (match_operand:HI 3 "memory_operand" ""))
4416    (clobber (match_operand:HI 4 "memory_operand" ""))]
4417   "reload_completed"
4418   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4419               (use (match_dup 2))
4420               (use (match_dup 3))
4421               (clobber (match_dup 4))])
4422    (set (match_dup 0) (match_dup 4))]
4423   "")
4424
4425 (define_insn "x86_fnstcw_1"
4426   [(set (match_operand:HI 0 "memory_operand" "=m")
4427         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4428   "TARGET_80387"
4429   "fnstcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")])
4433
4434 (define_insn "x86_fldcw_1"
4435   [(set (reg:HI FPSR_REG)
4436         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4437   "TARGET_80387"
4438   "fldcw\t%0"
4439   [(set_attr "length" "2")
4440    (set_attr "mode" "HI")
4441    (set_attr "unit" "i387")
4442    (set_attr "athlon_decode" "vector")])
4443 \f
4444 ;; Conversion between fixed point and floating point.
4445
4446 ;; Even though we only accept memory inputs, the backend _really_
4447 ;; wants to be able to do this between registers.
4448
4449 (define_expand "floathisf2"
4450   [(set (match_operand:SF 0 "register_operand" "")
4451         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4452   "TARGET_80387 || TARGET_SSE_MATH"
4453 {
4454   if (TARGET_SSE_MATH)
4455     {
4456       emit_insn (gen_floatsisf2 (operands[0],
4457                                  convert_to_mode (SImode, operands[1], 0)));
4458       DONE;
4459     }
4460 })
4461
4462 (define_insn "*floathisf2_i387"
4463   [(set (match_operand:SF 0 "register_operand" "=f,f")
4464         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4465   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4466   "@
4467    fild%z1\t%1
4468    #"
4469   [(set_attr "type" "fmov,multi")
4470    (set_attr "mode" "SF")
4471    (set_attr "fp_int_src" "true")])
4472
4473 (define_expand "floatsisf2"
4474   [(set (match_operand:SF 0 "register_operand" "")
4475         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4476   "TARGET_80387 || TARGET_SSE_MATH"
4477   "")
4478
4479 (define_insn "*floatsisf2_mixed"
4480   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4481         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4482   "TARGET_MIX_SSE_I387"
4483   "@
4484    fild%z1\t%1
4485    #
4486    cvtsi2ss\t{%1, %0|%0, %1}
4487    cvtsi2ss\t{%1, %0|%0, %1}"
4488   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4489    (set_attr "mode" "SF")
4490    (set_attr "athlon_decode" "*,*,vector,double")
4491    (set_attr "fp_int_src" "true")])
4492
4493 (define_insn "*floatsisf2_sse"
4494   [(set (match_operand:SF 0 "register_operand" "=x,x")
4495         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4496   "TARGET_SSE_MATH"
4497   "cvtsi2ss\t{%1, %0|%0, %1}"
4498   [(set_attr "type" "sseicvt")
4499    (set_attr "mode" "SF")
4500    (set_attr "athlon_decode" "vector,double")
4501    (set_attr "fp_int_src" "true")])
4502
4503 ; Avoid possible reformatting penalty on the destination by first
4504 ; zeroing it out
4505 (define_split
4506   [(set (match_operand:SF 0 "register_operand" "")
4507         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4508   "reload_completed
4509    && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4510    && SSE_REG_P (operands[0])"
4511   [(const_int 0)]
4512 {
4513   rtx dest;
4514   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4515   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4516   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4517   DONE;
4518 })
4519
4520 (define_insn "*floatsisf2_i387"
4521   [(set (match_operand:SF 0 "register_operand" "=f,f")
4522         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4523   "TARGET_80387"
4524   "@
4525    fild%z1\t%1
4526    #"
4527   [(set_attr "type" "fmov,multi")
4528    (set_attr "mode" "SF")
4529    (set_attr "fp_int_src" "true")])
4530
4531 (define_expand "floatdisf2"
4532   [(set (match_operand:SF 0 "register_operand" "")
4533         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4534   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4535   "")
4536
4537 (define_insn "*floatdisf2_mixed"
4538   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4539         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4540   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4541   "@
4542    fild%z1\t%1
4543    #
4544    cvtsi2ss{q}\t{%1, %0|%0, %1}
4545    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4546   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4547    (set_attr "mode" "SF")
4548    (set_attr "athlon_decode" "*,*,vector,double")
4549    (set_attr "fp_int_src" "true")])
4550
4551 (define_insn "*floatdisf2_sse"
4552   [(set (match_operand:SF 0 "register_operand" "=x,x")
4553         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4554   "TARGET_64BIT && TARGET_SSE_MATH"
4555   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4556   [(set_attr "type" "sseicvt")
4557    (set_attr "mode" "SF")
4558    (set_attr "athlon_decode" "vector,double")
4559    (set_attr "fp_int_src" "true")])
4560
4561 ; Avoid possible reformatting penalty on the destination by first
4562 ; zeroing it out
4563 (define_split
4564   [(set (match_operand:SF 0 "register_operand" "")
4565         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4566   "reload_completed
4567    && TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4568    && SSE_REG_P (operands[0])"
4569   [(const_int 0)]
4570 {
4571   rtx dest;
4572   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4573   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4574   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4575   DONE;
4576 })
4577
4578 (define_insn "*floatdisf2_i387"
4579   [(set (match_operand:SF 0 "register_operand" "=f,f")
4580         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4581   "TARGET_80387"
4582   "@
4583    fild%z1\t%1
4584    #"
4585   [(set_attr "type" "fmov,multi")
4586    (set_attr "mode" "SF")
4587    (set_attr "fp_int_src" "true")])
4588
4589 (define_expand "floathidf2"
4590   [(set (match_operand:DF 0 "register_operand" "")
4591         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4592   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4593 {
4594   if (TARGET_SSE2 && TARGET_SSE_MATH)
4595     {
4596       emit_insn (gen_floatsidf2 (operands[0],
4597                                  convert_to_mode (SImode, operands[1], 0)));
4598       DONE;
4599     }
4600 })
4601
4602 (define_insn "*floathidf2_i387"
4603   [(set (match_operand:DF 0 "register_operand" "=f,f")
4604         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4605   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4606   "@
4607    fild%z1\t%1
4608    #"
4609   [(set_attr "type" "fmov,multi")
4610    (set_attr "mode" "DF")
4611    (set_attr "fp_int_src" "true")])
4612
4613 (define_expand "floatsidf2"
4614   [(set (match_operand:DF 0 "register_operand" "")
4615         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4616   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4617   "")
4618
4619 (define_insn "*floatsidf2_mixed"
4620   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4621         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4622   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4623   "@
4624    fild%z1\t%1
4625    #
4626    cvtsi2sd\t{%1, %0|%0, %1}
4627    cvtsi2sd\t{%1, %0|%0, %1}"
4628   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4629    (set_attr "mode" "DF")
4630    (set_attr "athlon_decode" "*,*,double,direct")
4631    (set_attr "fp_int_src" "true")])
4632
4633 (define_insn "*floatsidf2_sse"
4634   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4635         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4636   "TARGET_SSE2 && TARGET_SSE_MATH"
4637   "cvtsi2sd\t{%1, %0|%0, %1}"
4638   [(set_attr "type" "sseicvt")
4639    (set_attr "mode" "DF")
4640    (set_attr "athlon_decode" "double,direct")
4641    (set_attr "fp_int_src" "true")])
4642
4643 (define_insn "*floatsidf2_i387"
4644   [(set (match_operand:DF 0 "register_operand" "=f,f")
4645         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4646   "TARGET_80387"
4647   "@
4648    fild%z1\t%1
4649    #"
4650   [(set_attr "type" "fmov,multi")
4651    (set_attr "mode" "DF")
4652    (set_attr "fp_int_src" "true")])
4653
4654 (define_expand "floatdidf2"
4655   [(set (match_operand:DF 0 "register_operand" "")
4656         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4657   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4658   "")
4659
4660 (define_insn "*floatdidf2_mixed"
4661   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4662         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4663   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4664   "@
4665    fild%z1\t%1
4666    #
4667    cvtsi2sd{q}\t{%1, %0|%0, %1}
4668    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4669   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4670    (set_attr "mode" "DF")
4671    (set_attr "athlon_decode" "*,*,double,direct")
4672    (set_attr "fp_int_src" "true")])
4673
4674 (define_insn "*floatdidf2_sse"
4675   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4676         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4677   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4678   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4679   [(set_attr "type" "sseicvt")
4680    (set_attr "mode" "DF")
4681    (set_attr "athlon_decode" "double,direct")
4682    (set_attr "fp_int_src" "true")])
4683
4684 (define_insn "*floatdidf2_i387"
4685   [(set (match_operand:DF 0 "register_operand" "=f,f")
4686         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4687   "TARGET_80387"
4688   "@
4689    fild%z1\t%1
4690    #"
4691   [(set_attr "type" "fmov,multi")
4692    (set_attr "mode" "DF")
4693    (set_attr "fp_int_src" "true")])
4694
4695 (define_insn "floathixf2"
4696   [(set (match_operand:XF 0 "register_operand" "=f,f")
4697         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4698   "TARGET_80387"
4699   "@
4700    fild%z1\t%1
4701    #"
4702   [(set_attr "type" "fmov,multi")
4703    (set_attr "mode" "XF")
4704    (set_attr "fp_int_src" "true")])
4705
4706 (define_insn "floatsixf2"
4707   [(set (match_operand:XF 0 "register_operand" "=f,f")
4708         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4709   "TARGET_80387"
4710   "@
4711    fild%z1\t%1
4712    #"
4713   [(set_attr "type" "fmov,multi")
4714    (set_attr "mode" "XF")
4715    (set_attr "fp_int_src" "true")])
4716
4717 (define_insn "floatdixf2"
4718   [(set (match_operand:XF 0 "register_operand" "=f,f")
4719         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4720   "TARGET_80387"
4721   "@
4722    fild%z1\t%1
4723    #"
4724   [(set_attr "type" "fmov,multi")
4725    (set_attr "mode" "XF")
4726    (set_attr "fp_int_src" "true")])
4727
4728 ;; %%% Kill these when reload knows how to do it.
4729 (define_split
4730   [(set (match_operand 0 "fp_register_operand" "")
4731         (float (match_operand 1 "register_operand" "")))]
4732   "reload_completed
4733    && TARGET_80387
4734    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4735   [(const_int 0)]
4736 {
4737   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4738   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4739   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4740   ix86_free_from_memory (GET_MODE (operands[1]));
4741   DONE;
4742 })
4743
4744 (define_expand "floatunssisf2"
4745   [(use (match_operand:SF 0 "register_operand" ""))
4746    (use (match_operand:SI 1 "register_operand" ""))]
4747   "!TARGET_64BIT && TARGET_SSE_MATH"
4748   "x86_emit_floatuns (operands); DONE;")
4749
4750 (define_expand "floatunsdisf2"
4751   [(use (match_operand:SF 0 "register_operand" ""))
4752    (use (match_operand:DI 1 "register_operand" ""))]
4753   "TARGET_64BIT && TARGET_SSE_MATH"
4754   "x86_emit_floatuns (operands); DONE;")
4755
4756 (define_expand "floatunsdidf2"
4757   [(use (match_operand:DF 0 "register_operand" ""))
4758    (use (match_operand:DI 1 "register_operand" ""))]
4759   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4760   "x86_emit_floatuns (operands); DONE;")
4761 \f
4762 ;; SSE extract/set expanders
4763
4764 (define_expand "vec_setv2df"
4765   [(match_operand:V2DF 0 "register_operand" "")
4766    (match_operand:DF 1 "register_operand" "")
4767    (match_operand 2 "const_int_operand" "")]
4768   "TARGET_SSE2"
4769 {
4770   switch (INTVAL (operands[2]))
4771     {
4772     case 0:
4773       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4774                                  simplify_gen_subreg (V2DFmode, operands[1],
4775                                                       DFmode, 0)));
4776       break;
4777     case 1:
4778       {
4779         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4780
4781         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4782       }
4783       break;
4784     default:
4785       abort ();
4786     }
4787   DONE;
4788 })
4789
4790 (define_expand "vec_extractv2df"
4791   [(match_operand:DF 0 "register_operand" "")
4792    (match_operand:V2DF 1 "register_operand" "")
4793    (match_operand 2 "const_int_operand" "")]
4794   "TARGET_SSE2"
4795 {
4796   switch (INTVAL (operands[2]))
4797     {
4798     case 0:
4799       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4800       break;
4801     case 1:
4802       {
4803         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4804
4805         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4806       }
4807       break;
4808     default:
4809       abort ();
4810     }
4811   DONE;
4812 })
4813
4814 (define_expand "vec_initv2df"
4815   [(match_operand:V2DF 0 "register_operand" "")
4816    (match_operand 1 "" "")]
4817   "TARGET_SSE2"
4818 {
4819   ix86_expand_vector_init (operands[0], operands[1]);
4820   DONE;
4821 })
4822
4823 (define_expand "vec_setv4sf"
4824   [(match_operand:V4SF 0 "register_operand" "")
4825    (match_operand:SF 1 "register_operand" "")
4826    (match_operand 2 "const_int_operand" "")]
4827   "TARGET_SSE"
4828 {
4829   switch (INTVAL (operands[2]))
4830     {
4831     case 0:
4832       emit_insn (gen_sse_movss (operands[0], operands[0],
4833                                 simplify_gen_subreg (V4SFmode, operands[1],
4834                                                      SFmode, 0)));
4835       break;
4836     case 1:
4837       {
4838         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4839         rtx tmp = gen_reg_rtx (V4SFmode);
4840  
4841         emit_move_insn (tmp, operands[0]);
4842         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4843         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4844         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4845                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4846       }
4847       break;
4848     case 2:
4849       {
4850         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4851         rtx tmp = gen_reg_rtx (V4SFmode);
4852
4853         emit_move_insn (tmp, operands[0]);
4854         emit_insn (gen_sse_movss (tmp, tmp, op1));
4855         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4856                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4857       }
4858       break;
4859     case 3:
4860       {
4861         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4862         rtx tmp = gen_reg_rtx (V4SFmode);
4863
4864         emit_move_insn (tmp, operands[0]);
4865         emit_insn (gen_sse_movss (tmp, tmp, op1));
4866         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4867                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4868       }
4869       break;
4870     default:
4871       abort ();
4872     }
4873   DONE;
4874 })
4875
4876 (define_expand "vec_extractv4sf"
4877   [(match_operand:SF 0 "register_operand" "")
4878    (match_operand:V4SF 1 "register_operand" "")
4879    (match_operand 2 "const_int_operand" "")]
4880   "TARGET_SSE"
4881 {
4882   switch (INTVAL (operands[2]))
4883     {
4884     case 0:
4885       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4886       break;
4887     case 1:
4888       {
4889         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4890         rtx tmp = gen_reg_rtx (V4SFmode);
4891  
4892         emit_move_insn (tmp, operands[1]);
4893         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4894                                    const1_rtx));
4895       }
4896       break;
4897     case 2:
4898       {
4899         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4900         rtx tmp = gen_reg_rtx (V4SFmode);
4901  
4902         emit_move_insn (tmp, operands[1]);
4903         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4904       }
4905       break;
4906     case 3:
4907       {
4908         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4909         rtx tmp = gen_reg_rtx (V4SFmode);
4910  
4911         emit_move_insn (tmp, operands[1]);
4912         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4913                                    GEN_INT (3)));
4914       }
4915       break;
4916     default:
4917       abort ();
4918     }
4919   DONE;
4920 })
4921
4922 (define_expand "vec_initv4sf"
4923   [(match_operand:V4SF 0 "register_operand" "")
4924    (match_operand 1 "" "")]
4925   "TARGET_SSE"
4926 {
4927   ix86_expand_vector_init (operands[0], operands[1]);
4928   DONE;
4929 })
4930 \f
4931 ;; Add instructions
4932
4933 ;; %%% splits for addsidi3
4934 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4935 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4936 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4937
4938 (define_expand "adddi3"
4939   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4940         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4941                  (match_operand:DI 2 "x86_64_general_operand" "")))
4942    (clobber (reg:CC FLAGS_REG))]
4943   ""
4944   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4945
4946 (define_insn "*adddi3_1"
4947   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4948         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4949                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4950    (clobber (reg:CC FLAGS_REG))]
4951   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4952   "#")
4953
4954 (define_split
4955   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4956         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4957                  (match_operand:DI 2 "general_operand" "")))
4958    (clobber (reg:CC FLAGS_REG))]
4959   "!TARGET_64BIT && reload_completed"
4960   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4961                                           UNSPEC_ADD_CARRY))
4962               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4963    (parallel [(set (match_dup 3)
4964                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4965                                      (match_dup 4))
4966                             (match_dup 5)))
4967               (clobber (reg:CC FLAGS_REG))])]
4968   "split_di (operands+0, 1, operands+0, operands+3);
4969    split_di (operands+1, 1, operands+1, operands+4);
4970    split_di (operands+2, 1, operands+2, operands+5);")
4971
4972 (define_insn "adddi3_carry_rex64"
4973   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4974           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4975                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4976                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4977    (clobber (reg:CC FLAGS_REG))]
4978   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4979   "adc{q}\t{%2, %0|%0, %2}"
4980   [(set_attr "type" "alu")
4981    (set_attr "pent_pair" "pu")
4982    (set_attr "mode" "DI")])
4983
4984 (define_insn "*adddi3_cc_rex64"
4985   [(set (reg:CC FLAGS_REG)
4986         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4987                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4988                    UNSPEC_ADD_CARRY))
4989    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4990         (plus:DI (match_dup 1) (match_dup 2)))]
4991   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4992   "add{q}\t{%2, %0|%0, %2}"
4993   [(set_attr "type" "alu")
4994    (set_attr "mode" "DI")])
4995
4996 (define_insn "addqi3_carry"
4997   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4998           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4999                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5000                    (match_operand:QI 2 "general_operand" "qi,qm")))
5001    (clobber (reg:CC FLAGS_REG))]
5002   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5003   "adc{b}\t{%2, %0|%0, %2}"
5004   [(set_attr "type" "alu")
5005    (set_attr "pent_pair" "pu")
5006    (set_attr "mode" "QI")])
5007
5008 (define_insn "addhi3_carry"
5009   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5010           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5011                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5012                    (match_operand:HI 2 "general_operand" "ri,rm")))
5013    (clobber (reg:CC FLAGS_REG))]
5014   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5015   "adc{w}\t{%2, %0|%0, %2}"
5016   [(set_attr "type" "alu")
5017    (set_attr "pent_pair" "pu")
5018    (set_attr "mode" "HI")])
5019
5020 (define_insn "addsi3_carry"
5021   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5022           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5023                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5024                    (match_operand:SI 2 "general_operand" "ri,rm")))
5025    (clobber (reg:CC FLAGS_REG))]
5026   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5027   "adc{l}\t{%2, %0|%0, %2}"
5028   [(set_attr "type" "alu")
5029    (set_attr "pent_pair" "pu")
5030    (set_attr "mode" "SI")])
5031
5032 (define_insn "*addsi3_carry_zext"
5033   [(set (match_operand:DI 0 "register_operand" "=r")
5034           (zero_extend:DI 
5035             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5036                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5037                      (match_operand:SI 2 "general_operand" "rim"))))
5038    (clobber (reg:CC FLAGS_REG))]
5039   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5040   "adc{l}\t{%2, %k0|%k0, %2}"
5041   [(set_attr "type" "alu")
5042    (set_attr "pent_pair" "pu")
5043    (set_attr "mode" "SI")])
5044
5045 (define_insn "*addsi3_cc"
5046   [(set (reg:CC FLAGS_REG)
5047         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5048                     (match_operand:SI 2 "general_operand" "ri,rm")]
5049                    UNSPEC_ADD_CARRY))
5050    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5051         (plus:SI (match_dup 1) (match_dup 2)))]
5052   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5053   "add{l}\t{%2, %0|%0, %2}"
5054   [(set_attr "type" "alu")
5055    (set_attr "mode" "SI")])
5056
5057 (define_insn "addqi3_cc"
5058   [(set (reg:CC FLAGS_REG)
5059         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5060                     (match_operand:QI 2 "general_operand" "qi,qm")]
5061                    UNSPEC_ADD_CARRY))
5062    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5063         (plus:QI (match_dup 1) (match_dup 2)))]
5064   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5065   "add{b}\t{%2, %0|%0, %2}"
5066   [(set_attr "type" "alu")
5067    (set_attr "mode" "QI")])
5068
5069 (define_expand "addsi3"
5070   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5071                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5072                             (match_operand:SI 2 "general_operand" "")))
5073               (clobber (reg:CC FLAGS_REG))])]
5074   ""
5075   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5076
5077 (define_insn "*lea_1"
5078   [(set (match_operand:SI 0 "register_operand" "=r")
5079         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5080   "!TARGET_64BIT"
5081   "lea{l}\t{%a1, %0|%0, %a1}"
5082   [(set_attr "type" "lea")
5083    (set_attr "mode" "SI")])
5084
5085 (define_insn "*lea_1_rex64"
5086   [(set (match_operand:SI 0 "register_operand" "=r")
5087         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5088   "TARGET_64BIT"
5089   "lea{l}\t{%a1, %0|%0, %a1}"
5090   [(set_attr "type" "lea")
5091    (set_attr "mode" "SI")])
5092
5093 (define_insn "*lea_1_zext"
5094   [(set (match_operand:DI 0 "register_operand" "=r")
5095         (zero_extend:DI
5096          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5097   "TARGET_64BIT"
5098   "lea{l}\t{%a1, %k0|%k0, %a1}"
5099   [(set_attr "type" "lea")
5100    (set_attr "mode" "SI")])
5101
5102 (define_insn "*lea_2_rex64"
5103   [(set (match_operand:DI 0 "register_operand" "=r")
5104         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5105   "TARGET_64BIT"
5106   "lea{q}\t{%a1, %0|%0, %a1}"
5107   [(set_attr "type" "lea")
5108    (set_attr "mode" "DI")])
5109
5110 ;; The lea patterns for non-Pmodes needs to be matched by several
5111 ;; insns converted to real lea by splitters.
5112
5113 (define_insn_and_split "*lea_general_1"
5114   [(set (match_operand 0 "register_operand" "=r")
5115         (plus (plus (match_operand 1 "index_register_operand" "l")
5116                     (match_operand 2 "register_operand" "r"))
5117               (match_operand 3 "immediate_operand" "i")))]
5118   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5119     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5120    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5121    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5122    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5123    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5124        || GET_MODE (operands[3]) == VOIDmode)"
5125   "#"
5126   "&& reload_completed"
5127   [(const_int 0)]
5128 {
5129   rtx pat;
5130   operands[0] = gen_lowpart (SImode, operands[0]);
5131   operands[1] = gen_lowpart (Pmode, operands[1]);
5132   operands[2] = gen_lowpart (Pmode, operands[2]);
5133   operands[3] = gen_lowpart (Pmode, operands[3]);
5134   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5135                       operands[3]);
5136   if (Pmode != SImode)
5137     pat = gen_rtx_SUBREG (SImode, pat, 0);
5138   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5139   DONE;
5140 }
5141   [(set_attr "type" "lea")
5142    (set_attr "mode" "SI")])
5143
5144 (define_insn_and_split "*lea_general_1_zext"
5145   [(set (match_operand:DI 0 "register_operand" "=r")
5146         (zero_extend:DI
5147           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5148                             (match_operand:SI 2 "register_operand" "r"))
5149                    (match_operand:SI 3 "immediate_operand" "i"))))]
5150   "TARGET_64BIT"
5151   "#"
5152   "&& reload_completed"
5153   [(set (match_dup 0)
5154         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5155                                                      (match_dup 2))
5156                                             (match_dup 3)) 0)))]
5157 {
5158   operands[1] = gen_lowpart (Pmode, operands[1]);
5159   operands[2] = gen_lowpart (Pmode, operands[2]);
5160   operands[3] = gen_lowpart (Pmode, operands[3]);
5161 }
5162   [(set_attr "type" "lea")
5163    (set_attr "mode" "SI")])
5164
5165 (define_insn_and_split "*lea_general_2"
5166   [(set (match_operand 0 "register_operand" "=r")
5167         (plus (mult (match_operand 1 "index_register_operand" "l")
5168                     (match_operand 2 "const248_operand" "i"))
5169               (match_operand 3 "nonmemory_operand" "ri")))]
5170   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5171     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5172    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5173    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5174    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5175        || GET_MODE (operands[3]) == VOIDmode)"
5176   "#"
5177   "&& reload_completed"
5178   [(const_int 0)]
5179 {
5180   rtx pat;
5181   operands[0] = gen_lowpart (SImode, operands[0]);
5182   operands[1] = gen_lowpart (Pmode, operands[1]);
5183   operands[3] = gen_lowpart (Pmode, operands[3]);
5184   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5185                       operands[3]);
5186   if (Pmode != SImode)
5187     pat = gen_rtx_SUBREG (SImode, pat, 0);
5188   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5189   DONE;
5190 }
5191   [(set_attr "type" "lea")
5192    (set_attr "mode" "SI")])
5193
5194 (define_insn_and_split "*lea_general_2_zext"
5195   [(set (match_operand:DI 0 "register_operand" "=r")
5196         (zero_extend:DI
5197           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5198                             (match_operand:SI 2 "const248_operand" "n"))
5199                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5200   "TARGET_64BIT"
5201   "#"
5202   "&& reload_completed"
5203   [(set (match_dup 0)
5204         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5205                                                      (match_dup 2))
5206                                             (match_dup 3)) 0)))]
5207 {
5208   operands[1] = gen_lowpart (Pmode, operands[1]);
5209   operands[3] = gen_lowpart (Pmode, operands[3]);
5210 }
5211   [(set_attr "type" "lea")
5212    (set_attr "mode" "SI")])
5213
5214 (define_insn_and_split "*lea_general_3"
5215   [(set (match_operand 0 "register_operand" "=r")
5216         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5217                           (match_operand 2 "const248_operand" "i"))
5218                     (match_operand 3 "register_operand" "r"))
5219               (match_operand 4 "immediate_operand" "i")))]
5220   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5221     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5222    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5223    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5224    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5225   "#"
5226   "&& reload_completed"
5227   [(const_int 0)]
5228 {
5229   rtx pat;
5230   operands[0] = gen_lowpart (SImode, operands[0]);
5231   operands[1] = gen_lowpart (Pmode, operands[1]);
5232   operands[3] = gen_lowpart (Pmode, operands[3]);
5233   operands[4] = gen_lowpart (Pmode, operands[4]);
5234   pat = gen_rtx_PLUS (Pmode,
5235                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5236                                                          operands[2]),
5237                                     operands[3]),
5238                       operands[4]);
5239   if (Pmode != SImode)
5240     pat = gen_rtx_SUBREG (SImode, pat, 0);
5241   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5242   DONE;
5243 }
5244   [(set_attr "type" "lea")
5245    (set_attr "mode" "SI")])
5246
5247 (define_insn_and_split "*lea_general_3_zext"
5248   [(set (match_operand:DI 0 "register_operand" "=r")
5249         (zero_extend:DI
5250           (plus:SI (plus:SI (mult:SI
5251                               (match_operand:SI 1 "index_register_operand" "l")
5252                               (match_operand:SI 2 "const248_operand" "n"))
5253                             (match_operand:SI 3 "register_operand" "r"))
5254                    (match_operand:SI 4 "immediate_operand" "i"))))]
5255   "TARGET_64BIT"
5256   "#"
5257   "&& reload_completed"
5258   [(set (match_dup 0)
5259         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5260                                                               (match_dup 2))
5261                                                      (match_dup 3))
5262                                             (match_dup 4)) 0)))]
5263 {
5264   operands[1] = gen_lowpart (Pmode, operands[1]);
5265   operands[3] = gen_lowpart (Pmode, operands[3]);
5266   operands[4] = gen_lowpart (Pmode, operands[4]);
5267 }
5268   [(set_attr "type" "lea")
5269    (set_attr "mode" "SI")])
5270
5271 (define_insn "*adddi_1_rex64"
5272   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5273         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5274                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5275    (clobber (reg:CC FLAGS_REG))]
5276   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5277 {
5278   switch (get_attr_type (insn))
5279     {
5280     case TYPE_LEA:
5281       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5282       return "lea{q}\t{%a2, %0|%0, %a2}";
5283
5284     case TYPE_INCDEC:
5285       if (! rtx_equal_p (operands[0], operands[1]))
5286         abort ();
5287       if (operands[2] == const1_rtx)
5288         return "inc{q}\t%0";
5289       else if (operands[2] == constm1_rtx)
5290         return "dec{q}\t%0";
5291       else
5292         abort ();
5293
5294     default:
5295       if (! rtx_equal_p (operands[0], operands[1]))
5296         abort ();
5297
5298       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5299          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5300       if (GET_CODE (operands[2]) == CONST_INT
5301           /* Avoid overflows.  */
5302           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5303           && (INTVAL (operands[2]) == 128
5304               || (INTVAL (operands[2]) < 0
5305                   && INTVAL (operands[2]) != -128)))
5306         {
5307           operands[2] = GEN_INT (-INTVAL (operands[2]));
5308           return "sub{q}\t{%2, %0|%0, %2}";
5309         }
5310       return "add{q}\t{%2, %0|%0, %2}";
5311     }
5312 }
5313   [(set (attr "type")
5314      (cond [(eq_attr "alternative" "2")
5315               (const_string "lea")
5316             ; Current assemblers are broken and do not allow @GOTOFF in
5317             ; ought but a memory context.
5318             (match_operand:DI 2 "pic_symbolic_operand" "")
5319               (const_string "lea")
5320             (match_operand:DI 2 "incdec_operand" "")
5321               (const_string "incdec")
5322            ]
5323            (const_string "alu")))
5324    (set_attr "mode" "DI")])
5325
5326 ;; Convert lea to the lea pattern to avoid flags dependency.
5327 (define_split
5328   [(set (match_operand:DI 0 "register_operand" "")
5329         (plus:DI (match_operand:DI 1 "register_operand" "")
5330                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5331    (clobber (reg:CC FLAGS_REG))]
5332   "TARGET_64BIT && reload_completed
5333    && true_regnum (operands[0]) != true_regnum (operands[1])"
5334   [(set (match_dup 0)
5335         (plus:DI (match_dup 1)
5336                  (match_dup 2)))]
5337   "")
5338
5339 (define_insn "*adddi_2_rex64"
5340   [(set (reg FLAGS_REG)
5341         (compare
5342           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5343                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5344           (const_int 0)))                       
5345    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5346         (plus:DI (match_dup 1) (match_dup 2)))]
5347   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5348    && ix86_binary_operator_ok (PLUS, DImode, operands)
5349    /* Current assemblers are broken and do not allow @GOTOFF in
5350       ought but a memory context.  */
5351    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5352 {
5353   switch (get_attr_type (insn))
5354     {
5355     case TYPE_INCDEC:
5356       if (! rtx_equal_p (operands[0], operands[1]))
5357         abort ();
5358       if (operands[2] == const1_rtx)
5359         return "inc{q}\t%0";
5360       else if (operands[2] == constm1_rtx)
5361         return "dec{q}\t%0";
5362       else
5363         abort ();
5364
5365     default:
5366       if (! rtx_equal_p (operands[0], operands[1]))
5367         abort ();
5368       /* ???? We ought to handle there the 32bit case too
5369          - do we need new constraint?  */
5370       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5372       if (GET_CODE (operands[2]) == CONST_INT
5373           /* Avoid overflows.  */
5374           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5375           && (INTVAL (operands[2]) == 128
5376               || (INTVAL (operands[2]) < 0
5377                   && INTVAL (operands[2]) != -128)))
5378         {
5379           operands[2] = GEN_INT (-INTVAL (operands[2]));
5380           return "sub{q}\t{%2, %0|%0, %2}";
5381         }
5382       return "add{q}\t{%2, %0|%0, %2}";
5383     }
5384 }
5385   [(set (attr "type")
5386      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5387         (const_string "incdec")
5388         (const_string "alu")))
5389    (set_attr "mode" "DI")])
5390
5391 (define_insn "*adddi_3_rex64"
5392   [(set (reg FLAGS_REG)
5393         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5394                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5395    (clobber (match_scratch:DI 0 "=r"))]
5396   "TARGET_64BIT
5397    && ix86_match_ccmode (insn, CCZmode)
5398    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5399    /* Current assemblers are broken and do not allow @GOTOFF in
5400       ought but a memory context.  */
5401    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5402 {
5403   switch (get_attr_type (insn))
5404     {
5405     case TYPE_INCDEC:
5406       if (! rtx_equal_p (operands[0], operands[1]))
5407         abort ();
5408       if (operands[2] == const1_rtx)
5409         return "inc{q}\t%0";
5410       else if (operands[2] == constm1_rtx)
5411         return "dec{q}\t%0";
5412       else
5413         abort ();
5414
5415     default:
5416       if (! rtx_equal_p (operands[0], operands[1]))
5417         abort ();
5418       /* ???? We ought to handle there the 32bit case too
5419          - do we need new constraint?  */
5420       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5421          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5422       if (GET_CODE (operands[2]) == CONST_INT
5423           /* Avoid overflows.  */
5424           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5425           && (INTVAL (operands[2]) == 128
5426               || (INTVAL (operands[2]) < 0
5427                   && INTVAL (operands[2]) != -128)))
5428         {
5429           operands[2] = GEN_INT (-INTVAL (operands[2]));
5430           return "sub{q}\t{%2, %0|%0, %2}";
5431         }
5432       return "add{q}\t{%2, %0|%0, %2}";
5433     }
5434 }
5435   [(set (attr "type")
5436      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5437         (const_string "incdec")
5438         (const_string "alu")))
5439    (set_attr "mode" "DI")])
5440
5441 ; For comparisons against 1, -1 and 128, we may generate better code
5442 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5443 ; is matched then.  We can't accept general immediate, because for
5444 ; case of overflows,  the result is messed up.
5445 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5446 ; when negated.
5447 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5448 ; only for comparisons not depending on it.
5449 (define_insn "*adddi_4_rex64"
5450   [(set (reg FLAGS_REG)
5451         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5452                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5453    (clobber (match_scratch:DI 0 "=rm"))]
5454   "TARGET_64BIT
5455    &&  ix86_match_ccmode (insn, CCGCmode)"
5456 {
5457   switch (get_attr_type (insn))
5458     {
5459     case TYPE_INCDEC:
5460       if (operands[2] == constm1_rtx)
5461         return "inc{q}\t%0";
5462       else if (operands[2] == const1_rtx)
5463         return "dec{q}\t%0";
5464       else
5465         abort();
5466
5467     default:
5468       if (! rtx_equal_p (operands[0], operands[1]))
5469         abort ();
5470       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5471          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5472       if ((INTVAL (operands[2]) == -128
5473            || (INTVAL (operands[2]) > 0
5474                && INTVAL (operands[2]) != 128))
5475           /* Avoid overflows.  */
5476           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5477         return "sub{q}\t{%2, %0|%0, %2}";
5478       operands[2] = GEN_INT (-INTVAL (operands[2]));
5479       return "add{q}\t{%2, %0|%0, %2}";
5480     }
5481 }
5482   [(set (attr "type")
5483      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5484         (const_string "incdec")
5485         (const_string "alu")))
5486    (set_attr "mode" "DI")])
5487
5488 (define_insn "*adddi_5_rex64"
5489   [(set (reg FLAGS_REG)
5490         (compare
5491           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5492                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5493           (const_int 0)))                       
5494    (clobber (match_scratch:DI 0 "=r"))]
5495   "TARGET_64BIT
5496    && ix86_match_ccmode (insn, CCGOCmode)
5497    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5498    /* Current assemblers are broken and do not allow @GOTOFF in
5499       ought but a memory context.  */
5500    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5501 {
5502   switch (get_attr_type (insn))
5503     {
5504     case TYPE_INCDEC:
5505       if (! rtx_equal_p (operands[0], operands[1]))
5506         abort ();
5507       if (operands[2] == const1_rtx)
5508         return "inc{q}\t%0";
5509       else if (operands[2] == constm1_rtx)
5510         return "dec{q}\t%0";
5511       else
5512         abort();
5513
5514     default:
5515       if (! rtx_equal_p (operands[0], operands[1]))
5516         abort ();
5517       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5518          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5519       if (GET_CODE (operands[2]) == CONST_INT
5520           /* Avoid overflows.  */
5521           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5522           && (INTVAL (operands[2]) == 128
5523               || (INTVAL (operands[2]) < 0
5524                   && INTVAL (operands[2]) != -128)))
5525         {
5526           operands[2] = GEN_INT (-INTVAL (operands[2]));
5527           return "sub{q}\t{%2, %0|%0, %2}";
5528         }
5529       return "add{q}\t{%2, %0|%0, %2}";
5530     }
5531 }
5532   [(set (attr "type")
5533      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5534         (const_string "incdec")
5535         (const_string "alu")))
5536    (set_attr "mode" "DI")])
5537
5538
5539 (define_insn "*addsi_1"
5540   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5541         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5542                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5543    (clobber (reg:CC FLAGS_REG))]
5544   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5545 {
5546   switch (get_attr_type (insn))
5547     {
5548     case TYPE_LEA:
5549       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5550       return "lea{l}\t{%a2, %0|%0, %a2}";
5551
5552     case TYPE_INCDEC:
5553       if (! rtx_equal_p (operands[0], operands[1]))
5554         abort ();
5555       if (operands[2] == const1_rtx)
5556         return "inc{l}\t%0";
5557       else if (operands[2] == constm1_rtx)
5558         return "dec{l}\t%0";
5559       else
5560         abort();
5561
5562     default:
5563       if (! rtx_equal_p (operands[0], operands[1]))
5564         abort ();
5565
5566       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5567          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5568       if (GET_CODE (operands[2]) == CONST_INT
5569           && (INTVAL (operands[2]) == 128
5570               || (INTVAL (operands[2]) < 0
5571                   && INTVAL (operands[2]) != -128)))
5572         {
5573           operands[2] = GEN_INT (-INTVAL (operands[2]));
5574           return "sub{l}\t{%2, %0|%0, %2}";
5575         }
5576       return "add{l}\t{%2, %0|%0, %2}";
5577     }
5578 }
5579   [(set (attr "type")
5580      (cond [(eq_attr "alternative" "2")
5581               (const_string "lea")
5582             ; Current assemblers are broken and do not allow @GOTOFF in
5583             ; ought but a memory context.
5584             (match_operand:SI 2 "pic_symbolic_operand" "")
5585               (const_string "lea")
5586             (match_operand:SI 2 "incdec_operand" "")
5587               (const_string "incdec")
5588            ]
5589            (const_string "alu")))
5590    (set_attr "mode" "SI")])
5591
5592 ;; Convert lea to the lea pattern to avoid flags dependency.
5593 (define_split
5594   [(set (match_operand 0 "register_operand" "")
5595         (plus (match_operand 1 "register_operand" "")
5596               (match_operand 2 "nonmemory_operand" "")))
5597    (clobber (reg:CC FLAGS_REG))]
5598   "reload_completed
5599    && true_regnum (operands[0]) != true_regnum (operands[1])"
5600   [(const_int 0)]
5601 {
5602   rtx pat;
5603   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5604      may confuse gen_lowpart.  */
5605   if (GET_MODE (operands[0]) != Pmode)
5606     {
5607       operands[1] = gen_lowpart (Pmode, operands[1]);
5608       operands[2] = gen_lowpart (Pmode, operands[2]);
5609     }
5610   operands[0] = gen_lowpart (SImode, operands[0]);
5611   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5612   if (Pmode != SImode)
5613     pat = gen_rtx_SUBREG (SImode, pat, 0);
5614   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5615   DONE;
5616 })
5617
5618 ;; It may seem that nonimmediate operand is proper one for operand 1.
5619 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5620 ;; we take care in ix86_binary_operator_ok to not allow two memory
5621 ;; operands so proper swapping will be done in reload.  This allow
5622 ;; patterns constructed from addsi_1 to match.
5623 (define_insn "addsi_1_zext"
5624   [(set (match_operand:DI 0 "register_operand" "=r,r")
5625         (zero_extend:DI
5626           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5627                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5628    (clobber (reg:CC FLAGS_REG))]
5629   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5630 {
5631   switch (get_attr_type (insn))
5632     {
5633     case TYPE_LEA:
5634       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5635       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5636
5637     case TYPE_INCDEC:
5638       if (operands[2] == const1_rtx)
5639         return "inc{l}\t%k0";
5640       else if (operands[2] == constm1_rtx)
5641         return "dec{l}\t%k0";
5642       else
5643         abort();
5644
5645     default:
5646       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5647          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5648       if (GET_CODE (operands[2]) == CONST_INT
5649           && (INTVAL (operands[2]) == 128
5650               || (INTVAL (operands[2]) < 0
5651                   && INTVAL (operands[2]) != -128)))
5652         {
5653           operands[2] = GEN_INT (-INTVAL (operands[2]));
5654           return "sub{l}\t{%2, %k0|%k0, %2}";
5655         }
5656       return "add{l}\t{%2, %k0|%k0, %2}";
5657     }
5658 }
5659   [(set (attr "type")
5660      (cond [(eq_attr "alternative" "1")
5661               (const_string "lea")
5662             ; Current assemblers are broken and do not allow @GOTOFF in
5663             ; ought but a memory context.
5664             (match_operand:SI 2 "pic_symbolic_operand" "")
5665               (const_string "lea")
5666             (match_operand:SI 2 "incdec_operand" "")
5667               (const_string "incdec")
5668            ]
5669            (const_string "alu")))
5670    (set_attr "mode" "SI")])
5671
5672 ;; Convert lea to the lea pattern to avoid flags dependency.
5673 (define_split
5674   [(set (match_operand:DI 0 "register_operand" "")
5675         (zero_extend:DI
5676           (plus:SI (match_operand:SI 1 "register_operand" "")
5677                    (match_operand:SI 2 "nonmemory_operand" ""))))
5678    (clobber (reg:CC FLAGS_REG))]
5679   "TARGET_64BIT && reload_completed
5680    && true_regnum (operands[0]) != true_regnum (operands[1])"
5681   [(set (match_dup 0)
5682         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5683 {
5684   operands[1] = gen_lowpart (Pmode, operands[1]);
5685   operands[2] = gen_lowpart (Pmode, operands[2]);
5686 })
5687
5688 (define_insn "*addsi_2"
5689   [(set (reg FLAGS_REG)
5690         (compare
5691           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5692                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5693           (const_int 0)))                       
5694    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5695         (plus:SI (match_dup 1) (match_dup 2)))]
5696   "ix86_match_ccmode (insn, CCGOCmode)
5697    && ix86_binary_operator_ok (PLUS, SImode, operands)
5698    /* Current assemblers are broken and do not allow @GOTOFF in
5699       ought but a memory context.  */
5700    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5701 {
5702   switch (get_attr_type (insn))
5703     {
5704     case TYPE_INCDEC:
5705       if (! rtx_equal_p (operands[0], operands[1]))
5706         abort ();
5707       if (operands[2] == const1_rtx)
5708         return "inc{l}\t%0";
5709       else if (operands[2] == constm1_rtx)
5710         return "dec{l}\t%0";
5711       else
5712         abort();
5713
5714     default:
5715       if (! rtx_equal_p (operands[0], operands[1]))
5716         abort ();
5717       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5718          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5719       if (GET_CODE (operands[2]) == CONST_INT
5720           && (INTVAL (operands[2]) == 128
5721               || (INTVAL (operands[2]) < 0
5722                   && INTVAL (operands[2]) != -128)))
5723         {
5724           operands[2] = GEN_INT (-INTVAL (operands[2]));
5725           return "sub{l}\t{%2, %0|%0, %2}";
5726         }
5727       return "add{l}\t{%2, %0|%0, %2}";
5728     }
5729 }
5730   [(set (attr "type")
5731      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5732         (const_string "incdec")
5733         (const_string "alu")))
5734    (set_attr "mode" "SI")])
5735
5736 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5737 (define_insn "*addsi_2_zext"
5738   [(set (reg FLAGS_REG)
5739         (compare
5740           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5741                    (match_operand:SI 2 "general_operand" "rmni"))
5742           (const_int 0)))                       
5743    (set (match_operand:DI 0 "register_operand" "=r")
5744         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5745   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5746    && ix86_binary_operator_ok (PLUS, SImode, operands)
5747    /* Current assemblers are broken and do not allow @GOTOFF in
5748       ought but a memory context.  */
5749    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5750 {
5751   switch (get_attr_type (insn))
5752     {
5753     case TYPE_INCDEC:
5754       if (operands[2] == const1_rtx)
5755         return "inc{l}\t%k0";
5756       else if (operands[2] == constm1_rtx)
5757         return "dec{l}\t%k0";
5758       else
5759         abort();
5760
5761     default:
5762       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5763          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5764       if (GET_CODE (operands[2]) == CONST_INT
5765           && (INTVAL (operands[2]) == 128
5766               || (INTVAL (operands[2]) < 0
5767                   && INTVAL (operands[2]) != -128)))
5768         {
5769           operands[2] = GEN_INT (-INTVAL (operands[2]));
5770           return "sub{l}\t{%2, %k0|%k0, %2}";
5771         }
5772       return "add{l}\t{%2, %k0|%k0, %2}";
5773     }
5774 }
5775   [(set (attr "type")
5776      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5777         (const_string "incdec")
5778         (const_string "alu")))
5779    (set_attr "mode" "SI")])
5780
5781 (define_insn "*addsi_3"
5782   [(set (reg FLAGS_REG)
5783         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5784                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5785    (clobber (match_scratch:SI 0 "=r"))]
5786   "ix86_match_ccmode (insn, CCZmode)
5787    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5788    /* Current assemblers are broken and do not allow @GOTOFF in
5789       ought but a memory context.  */
5790    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5791 {
5792   switch (get_attr_type (insn))
5793     {
5794     case TYPE_INCDEC:
5795       if (! rtx_equal_p (operands[0], operands[1]))
5796         abort ();
5797       if (operands[2] == const1_rtx)
5798         return "inc{l}\t%0";
5799       else if (operands[2] == constm1_rtx)
5800         return "dec{l}\t%0";
5801       else
5802         abort();
5803
5804     default:
5805       if (! rtx_equal_p (operands[0], operands[1]))
5806         abort ();
5807       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5808          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5809       if (GET_CODE (operands[2]) == CONST_INT
5810           && (INTVAL (operands[2]) == 128
5811               || (INTVAL (operands[2]) < 0
5812                   && INTVAL (operands[2]) != -128)))
5813         {
5814           operands[2] = GEN_INT (-INTVAL (operands[2]));
5815           return "sub{l}\t{%2, %0|%0, %2}";
5816         }
5817       return "add{l}\t{%2, %0|%0, %2}";
5818     }
5819 }
5820   [(set (attr "type")
5821      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5822         (const_string "incdec")
5823         (const_string "alu")))
5824    (set_attr "mode" "SI")])
5825
5826 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5827 (define_insn "*addsi_3_zext"
5828   [(set (reg FLAGS_REG)
5829         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5830                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5831    (set (match_operand:DI 0 "register_operand" "=r")
5832         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5833   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5834    && ix86_binary_operator_ok (PLUS, SImode, operands)
5835    /* Current assemblers are broken and do not allow @GOTOFF in
5836       ought but a memory context.  */
5837    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5838 {
5839   switch (get_attr_type (insn))
5840     {
5841     case TYPE_INCDEC:
5842       if (operands[2] == const1_rtx)
5843         return "inc{l}\t%k0";
5844       else if (operands[2] == constm1_rtx)
5845         return "dec{l}\t%k0";
5846       else
5847         abort();
5848
5849     default:
5850       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5851          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5852       if (GET_CODE (operands[2]) == CONST_INT
5853           && (INTVAL (operands[2]) == 128
5854               || (INTVAL (operands[2]) < 0
5855                   && INTVAL (operands[2]) != -128)))
5856         {
5857           operands[2] = GEN_INT (-INTVAL (operands[2]));
5858           return "sub{l}\t{%2, %k0|%k0, %2}";
5859         }
5860       return "add{l}\t{%2, %k0|%k0, %2}";
5861     }
5862 }
5863   [(set (attr "type")
5864      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5865         (const_string "incdec")
5866         (const_string "alu")))
5867    (set_attr "mode" "SI")])
5868
5869 ; For comparisons against 1, -1 and 128, we may generate better code
5870 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5871 ; is matched then.  We can't accept general immediate, because for
5872 ; case of overflows,  the result is messed up.
5873 ; This pattern also don't hold of 0x80000000, since the value overflows
5874 ; when negated.
5875 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5876 ; only for comparisons not depending on it.
5877 (define_insn "*addsi_4"
5878   [(set (reg FLAGS_REG)
5879         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5880                  (match_operand:SI 2 "const_int_operand" "n")))
5881    (clobber (match_scratch:SI 0 "=rm"))]
5882   "ix86_match_ccmode (insn, CCGCmode)
5883    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5884 {
5885   switch (get_attr_type (insn))
5886     {
5887     case TYPE_INCDEC:
5888       if (operands[2] == constm1_rtx)
5889         return "inc{l}\t%0";
5890       else if (operands[2] == const1_rtx)
5891         return "dec{l}\t%0";
5892       else
5893         abort();
5894
5895     default:
5896       if (! rtx_equal_p (operands[0], operands[1]))
5897         abort ();
5898       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5899          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5900       if ((INTVAL (operands[2]) == -128
5901            || (INTVAL (operands[2]) > 0
5902                && INTVAL (operands[2]) != 128)))
5903         return "sub{l}\t{%2, %0|%0, %2}";
5904       operands[2] = GEN_INT (-INTVAL (operands[2]));
5905       return "add{l}\t{%2, %0|%0, %2}";
5906     }
5907 }
5908   [(set (attr "type")
5909      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5910         (const_string "incdec")
5911         (const_string "alu")))
5912    (set_attr "mode" "SI")])
5913
5914 (define_insn "*addsi_5"
5915   [(set (reg FLAGS_REG)
5916         (compare
5917           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5918                    (match_operand:SI 2 "general_operand" "rmni"))
5919           (const_int 0)))                       
5920    (clobber (match_scratch:SI 0 "=r"))]
5921   "ix86_match_ccmode (insn, CCGOCmode)
5922    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5923    /* Current assemblers are broken and do not allow @GOTOFF in
5924       ought but a memory context.  */
5925    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5926 {
5927   switch (get_attr_type (insn))
5928     {
5929     case TYPE_INCDEC:
5930       if (! rtx_equal_p (operands[0], operands[1]))
5931         abort ();
5932       if (operands[2] == const1_rtx)
5933         return "inc{l}\t%0";
5934       else if (operands[2] == constm1_rtx)
5935         return "dec{l}\t%0";
5936       else
5937         abort();
5938
5939     default:
5940       if (! rtx_equal_p (operands[0], operands[1]))
5941         abort ();
5942       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5943          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5944       if (GET_CODE (operands[2]) == CONST_INT
5945           && (INTVAL (operands[2]) == 128
5946               || (INTVAL (operands[2]) < 0
5947                   && INTVAL (operands[2]) != -128)))
5948         {
5949           operands[2] = GEN_INT (-INTVAL (operands[2]));
5950           return "sub{l}\t{%2, %0|%0, %2}";
5951         }
5952       return "add{l}\t{%2, %0|%0, %2}";
5953     }
5954 }
5955   [(set (attr "type")
5956      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5957         (const_string "incdec")
5958         (const_string "alu")))
5959    (set_attr "mode" "SI")])
5960
5961 (define_expand "addhi3"
5962   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5963                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5964                             (match_operand:HI 2 "general_operand" "")))
5965               (clobber (reg:CC FLAGS_REG))])]
5966   "TARGET_HIMODE_MATH"
5967   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5968
5969 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5970 ;; type optimizations enabled by define-splits.  This is not important
5971 ;; for PII, and in fact harmful because of partial register stalls.
5972
5973 (define_insn "*addhi_1_lea"
5974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5975         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5976                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5977    (clobber (reg:CC FLAGS_REG))]
5978   "!TARGET_PARTIAL_REG_STALL
5979    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5980 {
5981   switch (get_attr_type (insn))
5982     {
5983     case TYPE_LEA:
5984       return "#";
5985     case TYPE_INCDEC:
5986       if (operands[2] == const1_rtx)
5987         return "inc{w}\t%0";
5988       else if (operands[2] == constm1_rtx)
5989         return "dec{w}\t%0";
5990       abort();
5991
5992     default:
5993       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5994          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5995       if (GET_CODE (operands[2]) == CONST_INT
5996           && (INTVAL (operands[2]) == 128
5997               || (INTVAL (operands[2]) < 0
5998                   && INTVAL (operands[2]) != -128)))
5999         {
6000           operands[2] = GEN_INT (-INTVAL (operands[2]));
6001           return "sub{w}\t{%2, %0|%0, %2}";
6002         }
6003       return "add{w}\t{%2, %0|%0, %2}";
6004     }
6005 }
6006   [(set (attr "type")
6007      (if_then_else (eq_attr "alternative" "2")
6008         (const_string "lea")
6009         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6010            (const_string "incdec")
6011            (const_string "alu"))))
6012    (set_attr "mode" "HI,HI,SI")])
6013
6014 (define_insn "*addhi_1"
6015   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6016         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6017                  (match_operand:HI 2 "general_operand" "ri,rm")))
6018    (clobber (reg:CC FLAGS_REG))]
6019   "TARGET_PARTIAL_REG_STALL
6020    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6021 {
6022   switch (get_attr_type (insn))
6023     {
6024     case TYPE_INCDEC:
6025       if (operands[2] == const1_rtx)
6026         return "inc{w}\t%0";
6027       else if (operands[2] == constm1_rtx)
6028         return "dec{w}\t%0";
6029       abort();
6030
6031     default:
6032       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6033          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6034       if (GET_CODE (operands[2]) == CONST_INT
6035           && (INTVAL (operands[2]) == 128
6036               || (INTVAL (operands[2]) < 0
6037                   && INTVAL (operands[2]) != -128)))
6038         {
6039           operands[2] = GEN_INT (-INTVAL (operands[2]));
6040           return "sub{w}\t{%2, %0|%0, %2}";
6041         }
6042       return "add{w}\t{%2, %0|%0, %2}";
6043     }
6044 }
6045   [(set (attr "type")
6046      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047         (const_string "incdec")
6048         (const_string "alu")))
6049    (set_attr "mode" "HI")])
6050
6051 (define_insn "*addhi_2"
6052   [(set (reg FLAGS_REG)
6053         (compare
6054           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6055                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6056           (const_int 0)))                       
6057    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6058         (plus:HI (match_dup 1) (match_dup 2)))]
6059   "ix86_match_ccmode (insn, CCGOCmode)
6060    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6061 {
6062   switch (get_attr_type (insn))
6063     {
6064     case TYPE_INCDEC:
6065       if (operands[2] == const1_rtx)
6066         return "inc{w}\t%0";
6067       else if (operands[2] == constm1_rtx)
6068         return "dec{w}\t%0";
6069       abort();
6070
6071     default:
6072       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6073          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6074       if (GET_CODE (operands[2]) == CONST_INT
6075           && (INTVAL (operands[2]) == 128
6076               || (INTVAL (operands[2]) < 0
6077                   && INTVAL (operands[2]) != -128)))
6078         {
6079           operands[2] = GEN_INT (-INTVAL (operands[2]));
6080           return "sub{w}\t{%2, %0|%0, %2}";
6081         }
6082       return "add{w}\t{%2, %0|%0, %2}";
6083     }
6084 }
6085   [(set (attr "type")
6086      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6087         (const_string "incdec")
6088         (const_string "alu")))
6089    (set_attr "mode" "HI")])
6090
6091 (define_insn "*addhi_3"
6092   [(set (reg FLAGS_REG)
6093         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6094                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6095    (clobber (match_scratch:HI 0 "=r"))]
6096   "ix86_match_ccmode (insn, CCZmode)
6097    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6098 {
6099   switch (get_attr_type (insn))
6100     {
6101     case TYPE_INCDEC:
6102       if (operands[2] == const1_rtx)
6103         return "inc{w}\t%0";
6104       else if (operands[2] == constm1_rtx)
6105         return "dec{w}\t%0";
6106       abort();
6107
6108     default:
6109       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6110          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6111       if (GET_CODE (operands[2]) == CONST_INT
6112           && (INTVAL (operands[2]) == 128
6113               || (INTVAL (operands[2]) < 0
6114                   && INTVAL (operands[2]) != -128)))
6115         {
6116           operands[2] = GEN_INT (-INTVAL (operands[2]));
6117           return "sub{w}\t{%2, %0|%0, %2}";
6118         }
6119       return "add{w}\t{%2, %0|%0, %2}";
6120     }
6121 }
6122   [(set (attr "type")
6123      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6124         (const_string "incdec")
6125         (const_string "alu")))
6126    (set_attr "mode" "HI")])
6127
6128 ; See comments above addsi_3_imm for details.
6129 (define_insn "*addhi_4"
6130   [(set (reg FLAGS_REG)
6131         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6132                  (match_operand:HI 2 "const_int_operand" "n")))
6133    (clobber (match_scratch:HI 0 "=rm"))]
6134   "ix86_match_ccmode (insn, CCGCmode)
6135    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6136 {
6137   switch (get_attr_type (insn))
6138     {
6139     case TYPE_INCDEC:
6140       if (operands[2] == constm1_rtx)
6141         return "inc{w}\t%0";
6142       else if (operands[2] == const1_rtx)
6143         return "dec{w}\t%0";
6144       else
6145         abort();
6146
6147     default:
6148       if (! rtx_equal_p (operands[0], operands[1]))
6149         abort ();
6150       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6151          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6152       if ((INTVAL (operands[2]) == -128
6153            || (INTVAL (operands[2]) > 0
6154                && INTVAL (operands[2]) != 128)))
6155         return "sub{w}\t{%2, %0|%0, %2}";
6156       operands[2] = GEN_INT (-INTVAL (operands[2]));
6157       return "add{w}\t{%2, %0|%0, %2}";
6158     }
6159 }
6160   [(set (attr "type")
6161      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6162         (const_string "incdec")
6163         (const_string "alu")))
6164    (set_attr "mode" "SI")])
6165
6166
6167 (define_insn "*addhi_5"
6168   [(set (reg FLAGS_REG)
6169         (compare
6170           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6171                    (match_operand:HI 2 "general_operand" "rmni"))
6172           (const_int 0)))                       
6173    (clobber (match_scratch:HI 0 "=r"))]
6174   "ix86_match_ccmode (insn, CCGOCmode)
6175    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6176 {
6177   switch (get_attr_type (insn))
6178     {
6179     case TYPE_INCDEC:
6180       if (operands[2] == const1_rtx)
6181         return "inc{w}\t%0";
6182       else if (operands[2] == constm1_rtx)
6183         return "dec{w}\t%0";
6184       abort();
6185
6186     default:
6187       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6188          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6189       if (GET_CODE (operands[2]) == CONST_INT
6190           && (INTVAL (operands[2]) == 128
6191               || (INTVAL (operands[2]) < 0
6192                   && INTVAL (operands[2]) != -128)))
6193         {
6194           operands[2] = GEN_INT (-INTVAL (operands[2]));
6195           return "sub{w}\t{%2, %0|%0, %2}";
6196         }
6197       return "add{w}\t{%2, %0|%0, %2}";
6198     }
6199 }
6200   [(set (attr "type")
6201      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6202         (const_string "incdec")
6203         (const_string "alu")))
6204    (set_attr "mode" "HI")])
6205
6206 (define_expand "addqi3"
6207   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6208                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6209                             (match_operand:QI 2 "general_operand" "")))
6210               (clobber (reg:CC FLAGS_REG))])]
6211   "TARGET_QIMODE_MATH"
6212   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6213
6214 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6215 (define_insn "*addqi_1_lea"
6216   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6217         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6218                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6219    (clobber (reg:CC FLAGS_REG))]
6220   "!TARGET_PARTIAL_REG_STALL
6221    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6222 {
6223   int widen = (which_alternative == 2);
6224   switch (get_attr_type (insn))
6225     {
6226     case TYPE_LEA:
6227       return "#";
6228     case TYPE_INCDEC:
6229       if (operands[2] == const1_rtx)
6230         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6231       else if (operands[2] == constm1_rtx)
6232         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6233       abort();
6234
6235     default:
6236       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6237          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6238       if (GET_CODE (operands[2]) == CONST_INT
6239           && (INTVAL (operands[2]) == 128
6240               || (INTVAL (operands[2]) < 0
6241                   && INTVAL (operands[2]) != -128)))
6242         {
6243           operands[2] = GEN_INT (-INTVAL (operands[2]));
6244           if (widen)
6245             return "sub{l}\t{%2, %k0|%k0, %2}";
6246           else
6247             return "sub{b}\t{%2, %0|%0, %2}";
6248         }
6249       if (widen)
6250         return "add{l}\t{%k2, %k0|%k0, %k2}";
6251       else
6252         return "add{b}\t{%2, %0|%0, %2}";
6253     }
6254 }
6255   [(set (attr "type")
6256      (if_then_else (eq_attr "alternative" "3")
6257         (const_string "lea")
6258         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6259            (const_string "incdec")
6260            (const_string "alu"))))
6261    (set_attr "mode" "QI,QI,SI,SI")])
6262
6263 (define_insn "*addqi_1"
6264   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6265         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6266                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6267    (clobber (reg:CC FLAGS_REG))]
6268   "TARGET_PARTIAL_REG_STALL
6269    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6270 {
6271   int widen = (which_alternative == 2);
6272   switch (get_attr_type (insn))
6273     {
6274     case TYPE_INCDEC:
6275       if (operands[2] == const1_rtx)
6276         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6277       else if (operands[2] == constm1_rtx)
6278         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6279       abort();
6280
6281     default:
6282       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6283          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6284       if (GET_CODE (operands[2]) == CONST_INT
6285           && (INTVAL (operands[2]) == 128
6286               || (INTVAL (operands[2]) < 0
6287                   && INTVAL (operands[2]) != -128)))
6288         {
6289           operands[2] = GEN_INT (-INTVAL (operands[2]));
6290           if (widen)
6291             return "sub{l}\t{%2, %k0|%k0, %2}";
6292           else
6293             return "sub{b}\t{%2, %0|%0, %2}";
6294         }
6295       if (widen)
6296         return "add{l}\t{%k2, %k0|%k0, %k2}";
6297       else
6298         return "add{b}\t{%2, %0|%0, %2}";
6299     }
6300 }
6301   [(set (attr "type")
6302      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6303         (const_string "incdec")
6304         (const_string "alu")))
6305    (set_attr "mode" "QI,QI,SI")])
6306
6307 (define_insn "*addqi_1_slp"
6308   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6309         (plus:QI (match_dup 0)
6310                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6311    (clobber (reg:CC FLAGS_REG))]
6312   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6313    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6314 {
6315   switch (get_attr_type (insn))
6316     {
6317     case TYPE_INCDEC:
6318       if (operands[1] == const1_rtx)
6319         return "inc{b}\t%0";
6320       else if (operands[1] == constm1_rtx)
6321         return "dec{b}\t%0";
6322       abort();
6323
6324     default:
6325       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6326       if (GET_CODE (operands[1]) == CONST_INT
6327           && INTVAL (operands[1]) < 0)
6328         {
6329           operands[1] = GEN_INT (-INTVAL (operands[1]));
6330           return "sub{b}\t{%1, %0|%0, %1}";
6331         }
6332       return "add{b}\t{%1, %0|%0, %1}";
6333     }
6334 }
6335   [(set (attr "type")
6336      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6337         (const_string "incdec")
6338         (const_string "alu1")))
6339    (set_attr "mode" "QI")])
6340
6341 (define_insn "*addqi_2"
6342   [(set (reg FLAGS_REG)
6343         (compare
6344           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6345                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6346           (const_int 0)))
6347    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6348         (plus:QI (match_dup 1) (match_dup 2)))]
6349   "ix86_match_ccmode (insn, CCGOCmode)
6350    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6351 {
6352   switch (get_attr_type (insn))
6353     {
6354     case TYPE_INCDEC:
6355       if (operands[2] == const1_rtx)
6356         return "inc{b}\t%0";
6357       else if (operands[2] == constm1_rtx
6358                || (GET_CODE (operands[2]) == CONST_INT
6359                    && INTVAL (operands[2]) == 255))
6360         return "dec{b}\t%0";
6361       abort();
6362
6363     default:
6364       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6365       if (GET_CODE (operands[2]) == CONST_INT
6366           && INTVAL (operands[2]) < 0)
6367         {
6368           operands[2] = GEN_INT (-INTVAL (operands[2]));
6369           return "sub{b}\t{%2, %0|%0, %2}";
6370         }
6371       return "add{b}\t{%2, %0|%0, %2}";
6372     }
6373 }
6374   [(set (attr "type")
6375      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6376         (const_string "incdec")
6377         (const_string "alu")))
6378    (set_attr "mode" "QI")])
6379
6380 (define_insn "*addqi_3"
6381   [(set (reg FLAGS_REG)
6382         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6383                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6384    (clobber (match_scratch:QI 0 "=q"))]
6385   "ix86_match_ccmode (insn, CCZmode)
6386    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6387 {
6388   switch (get_attr_type (insn))
6389     {
6390     case TYPE_INCDEC:
6391       if (operands[2] == const1_rtx)
6392         return "inc{b}\t%0";
6393       else if (operands[2] == constm1_rtx
6394                || (GET_CODE (operands[2]) == CONST_INT
6395                    && INTVAL (operands[2]) == 255))
6396         return "dec{b}\t%0";
6397       abort();
6398
6399     default:
6400       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6401       if (GET_CODE (operands[2]) == CONST_INT
6402           && INTVAL (operands[2]) < 0)
6403         {
6404           operands[2] = GEN_INT (-INTVAL (operands[2]));
6405           return "sub{b}\t{%2, %0|%0, %2}";
6406         }
6407       return "add{b}\t{%2, %0|%0, %2}";
6408     }
6409 }
6410   [(set (attr "type")
6411      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6412         (const_string "incdec")
6413         (const_string "alu")))
6414    (set_attr "mode" "QI")])
6415
6416 ; See comments above addsi_3_imm for details.
6417 (define_insn "*addqi_4"
6418   [(set (reg FLAGS_REG)
6419         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6420                  (match_operand:QI 2 "const_int_operand" "n")))
6421    (clobber (match_scratch:QI 0 "=qm"))]
6422   "ix86_match_ccmode (insn, CCGCmode)
6423    && (INTVAL (operands[2]) & 0xff) != 0x80"
6424 {
6425   switch (get_attr_type (insn))
6426     {
6427     case TYPE_INCDEC:
6428       if (operands[2] == constm1_rtx
6429           || (GET_CODE (operands[2]) == CONST_INT
6430               && INTVAL (operands[2]) == 255))
6431         return "inc{b}\t%0";
6432       else if (operands[2] == const1_rtx)
6433         return "dec{b}\t%0";
6434       else
6435         abort();
6436
6437     default:
6438       if (! rtx_equal_p (operands[0], operands[1]))
6439         abort ();
6440       if (INTVAL (operands[2]) < 0)
6441         {
6442           operands[2] = GEN_INT (-INTVAL (operands[2]));
6443           return "add{b}\t{%2, %0|%0, %2}";
6444         }
6445       return "sub{b}\t{%2, %0|%0, %2}";
6446     }
6447 }
6448   [(set (attr "type")
6449      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6450         (const_string "incdec")
6451         (const_string "alu")))
6452    (set_attr "mode" "QI")])
6453
6454
6455 (define_insn "*addqi_5"
6456   [(set (reg FLAGS_REG)
6457         (compare
6458           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6459                    (match_operand:QI 2 "general_operand" "qmni"))
6460           (const_int 0)))
6461    (clobber (match_scratch:QI 0 "=q"))]
6462   "ix86_match_ccmode (insn, CCGOCmode)
6463    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6464 {
6465   switch (get_attr_type (insn))
6466     {
6467     case TYPE_INCDEC:
6468       if (operands[2] == const1_rtx)
6469         return "inc{b}\t%0";
6470       else if (operands[2] == constm1_rtx
6471                || (GET_CODE (operands[2]) == CONST_INT
6472                    && INTVAL (operands[2]) == 255))
6473         return "dec{b}\t%0";
6474       abort();
6475
6476     default:
6477       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6478       if (GET_CODE (operands[2]) == CONST_INT
6479           && INTVAL (operands[2]) < 0)
6480         {
6481           operands[2] = GEN_INT (-INTVAL (operands[2]));
6482           return "sub{b}\t{%2, %0|%0, %2}";
6483         }
6484       return "add{b}\t{%2, %0|%0, %2}";
6485     }
6486 }
6487   [(set (attr "type")
6488      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6489         (const_string "incdec")
6490         (const_string "alu")))
6491    (set_attr "mode" "QI")])
6492
6493
6494 (define_insn "addqi_ext_1"
6495   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6496                          (const_int 8)
6497                          (const_int 8))
6498         (plus:SI
6499           (zero_extract:SI
6500             (match_operand 1 "ext_register_operand" "0")
6501             (const_int 8)
6502             (const_int 8))
6503           (match_operand:QI 2 "general_operand" "Qmn")))
6504    (clobber (reg:CC FLAGS_REG))]
6505   "!TARGET_64BIT"
6506 {
6507   switch (get_attr_type (insn))
6508     {
6509     case TYPE_INCDEC:
6510       if (operands[2] == const1_rtx)
6511         return "inc{b}\t%h0";
6512       else if (operands[2] == constm1_rtx
6513                || (GET_CODE (operands[2]) == CONST_INT
6514                    && INTVAL (operands[2]) == 255))
6515         return "dec{b}\t%h0";
6516       abort();
6517
6518     default:
6519       return "add{b}\t{%2, %h0|%h0, %2}";
6520     }
6521 }
6522   [(set (attr "type")
6523      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6524         (const_string "incdec")
6525         (const_string "alu")))
6526    (set_attr "mode" "QI")])
6527
6528 (define_insn "*addqi_ext_1_rex64"
6529   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6530                          (const_int 8)
6531                          (const_int 8))
6532         (plus:SI
6533           (zero_extract:SI
6534             (match_operand 1 "ext_register_operand" "0")
6535             (const_int 8)
6536             (const_int 8))
6537           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6538    (clobber (reg:CC FLAGS_REG))]
6539   "TARGET_64BIT"
6540 {
6541   switch (get_attr_type (insn))
6542     {
6543     case TYPE_INCDEC:
6544       if (operands[2] == const1_rtx)
6545         return "inc{b}\t%h0";
6546       else if (operands[2] == constm1_rtx
6547                || (GET_CODE (operands[2]) == CONST_INT
6548                    && INTVAL (operands[2]) == 255))
6549         return "dec{b}\t%h0";
6550       abort();
6551
6552     default:
6553       return "add{b}\t{%2, %h0|%h0, %2}";
6554     }
6555 }
6556   [(set (attr "type")
6557      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6558         (const_string "incdec")
6559         (const_string "alu")))
6560    (set_attr "mode" "QI")])
6561
6562 (define_insn "*addqi_ext_2"
6563   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6564                          (const_int 8)
6565                          (const_int 8))
6566         (plus:SI
6567           (zero_extract:SI
6568             (match_operand 1 "ext_register_operand" "%0")
6569             (const_int 8)
6570             (const_int 8))
6571           (zero_extract:SI
6572             (match_operand 2 "ext_register_operand" "Q")
6573             (const_int 8)
6574             (const_int 8))))
6575    (clobber (reg:CC FLAGS_REG))]
6576   ""
6577   "add{b}\t{%h2, %h0|%h0, %h2}"
6578   [(set_attr "type" "alu")
6579    (set_attr "mode" "QI")])
6580
6581 ;; The patterns that match these are at the end of this file.
6582
6583 (define_expand "addxf3"
6584   [(set (match_operand:XF 0 "register_operand" "")
6585         (plus:XF (match_operand:XF 1 "register_operand" "")
6586                  (match_operand:XF 2 "register_operand" "")))]
6587   "TARGET_80387"
6588   "")
6589
6590 (define_expand "adddf3"
6591   [(set (match_operand:DF 0 "register_operand" "")
6592         (plus:DF (match_operand:DF 1 "register_operand" "")
6593                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6594   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6595   "")
6596
6597 (define_expand "addsf3"
6598   [(set (match_operand:SF 0 "register_operand" "")
6599         (plus:SF (match_operand:SF 1 "register_operand" "")
6600                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6601   "TARGET_80387 || TARGET_SSE_MATH"
6602   "")
6603 \f
6604 ;; Subtract instructions
6605
6606 ;; %%% splits for subsidi3
6607
6608 (define_expand "subdi3"
6609   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6610                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6611                              (match_operand:DI 2 "x86_64_general_operand" "")))
6612               (clobber (reg:CC FLAGS_REG))])]
6613   ""
6614   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6615
6616 (define_insn "*subdi3_1"
6617   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6618         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6619                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6622   "#")
6623
6624 (define_split
6625   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6626         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6627                   (match_operand:DI 2 "general_operand" "")))
6628    (clobber (reg:CC FLAGS_REG))]
6629   "!TARGET_64BIT && reload_completed"
6630   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6631               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6632    (parallel [(set (match_dup 3)
6633                    (minus:SI (match_dup 4)
6634                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6635                                       (match_dup 5))))
6636               (clobber (reg:CC FLAGS_REG))])]
6637   "split_di (operands+0, 1, operands+0, operands+3);
6638    split_di (operands+1, 1, operands+1, operands+4);
6639    split_di (operands+2, 1, operands+2, operands+5);")
6640
6641 (define_insn "subdi3_carry_rex64"
6642   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6643           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6644             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6645                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6646    (clobber (reg:CC FLAGS_REG))]
6647   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6648   "sbb{q}\t{%2, %0|%0, %2}"
6649   [(set_attr "type" "alu")
6650    (set_attr "pent_pair" "pu")
6651    (set_attr "mode" "DI")])
6652
6653 (define_insn "*subdi_1_rex64"
6654   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6655         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6656                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6659   "sub{q}\t{%2, %0|%0, %2}"
6660   [(set_attr "type" "alu")
6661    (set_attr "mode" "DI")])
6662
6663 (define_insn "*subdi_2_rex64"
6664   [(set (reg FLAGS_REG)
6665         (compare
6666           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6667                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6668           (const_int 0)))
6669    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6670         (minus:DI (match_dup 1) (match_dup 2)))]
6671   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6672    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6673   "sub{q}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "mode" "DI")])
6676
6677 (define_insn "*subdi_3_rex63"
6678   [(set (reg FLAGS_REG)
6679         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6680                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6681    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6682         (minus:DI (match_dup 1) (match_dup 2)))]
6683   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6684    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6685   "sub{q}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "mode" "DI")])
6688
6689 (define_insn "subqi3_carry"
6690   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6691           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6692             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6693                (match_operand:QI 2 "general_operand" "qi,qm"))))
6694    (clobber (reg:CC FLAGS_REG))]
6695   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6696   "sbb{b}\t{%2, %0|%0, %2}"
6697   [(set_attr "type" "alu")
6698    (set_attr "pent_pair" "pu")
6699    (set_attr "mode" "QI")])
6700
6701 (define_insn "subhi3_carry"
6702   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6703           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6704             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6705                (match_operand:HI 2 "general_operand" "ri,rm"))))
6706    (clobber (reg:CC FLAGS_REG))]
6707   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6708   "sbb{w}\t{%2, %0|%0, %2}"
6709   [(set_attr "type" "alu")
6710    (set_attr "pent_pair" "pu")
6711    (set_attr "mode" "HI")])
6712
6713 (define_insn "subsi3_carry"
6714   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6715           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6716             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6717                (match_operand:SI 2 "general_operand" "ri,rm"))))
6718    (clobber (reg:CC FLAGS_REG))]
6719   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6720   "sbb{l}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "pent_pair" "pu")
6723    (set_attr "mode" "SI")])
6724
6725 (define_insn "subsi3_carry_zext"
6726   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6727           (zero_extend:DI
6728             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6729               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6730                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6731    (clobber (reg:CC FLAGS_REG))]
6732   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6733   "sbb{l}\t{%2, %k0|%k0, %2}"
6734   [(set_attr "type" "alu")
6735    (set_attr "pent_pair" "pu")
6736    (set_attr "mode" "SI")])
6737
6738 (define_expand "subsi3"
6739   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6740                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6741                              (match_operand:SI 2 "general_operand" "")))
6742               (clobber (reg:CC FLAGS_REG))])]
6743   ""
6744   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6745
6746 (define_insn "*subsi_1"
6747   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6748         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6749                   (match_operand:SI 2 "general_operand" "ri,rm")))
6750    (clobber (reg:CC FLAGS_REG))]
6751   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6752   "sub{l}\t{%2, %0|%0, %2}"
6753   [(set_attr "type" "alu")
6754    (set_attr "mode" "SI")])
6755
6756 (define_insn "*subsi_1_zext"
6757   [(set (match_operand:DI 0 "register_operand" "=r")
6758         (zero_extend:DI
6759           (minus:SI (match_operand:SI 1 "register_operand" "0")
6760                     (match_operand:SI 2 "general_operand" "rim"))))
6761    (clobber (reg:CC FLAGS_REG))]
6762   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763   "sub{l}\t{%2, %k0|%k0, %2}"
6764   [(set_attr "type" "alu")
6765    (set_attr "mode" "SI")])
6766
6767 (define_insn "*subsi_2"
6768   [(set (reg FLAGS_REG)
6769         (compare
6770           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6771                     (match_operand:SI 2 "general_operand" "ri,rm"))
6772           (const_int 0)))
6773    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6774         (minus:SI (match_dup 1) (match_dup 2)))]
6775   "ix86_match_ccmode (insn, CCGOCmode)
6776    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777   "sub{l}\t{%2, %0|%0, %2}"
6778   [(set_attr "type" "alu")
6779    (set_attr "mode" "SI")])
6780
6781 (define_insn "*subsi_2_zext"
6782   [(set (reg FLAGS_REG)
6783         (compare
6784           (minus:SI (match_operand:SI 1 "register_operand" "0")
6785                     (match_operand:SI 2 "general_operand" "rim"))
6786           (const_int 0)))
6787    (set (match_operand:DI 0 "register_operand" "=r")
6788         (zero_extend:DI
6789           (minus:SI (match_dup 1)
6790                     (match_dup 2))))]
6791   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6792    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6793   "sub{l}\t{%2, %k0|%k0, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "mode" "SI")])
6796
6797 (define_insn "*subsi_3"
6798   [(set (reg FLAGS_REG)
6799         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6800                  (match_operand:SI 2 "general_operand" "ri,rm")))
6801    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6802         (minus:SI (match_dup 1) (match_dup 2)))]
6803   "ix86_match_ccmode (insn, CCmode)
6804    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805   "sub{l}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "SI")])
6808
6809 (define_insn "*subsi_3_zext"
6810   [(set (reg FLAGS_REG)
6811         (compare (match_operand:SI 1 "register_operand" "0")
6812                  (match_operand:SI 2 "general_operand" "rim")))
6813    (set (match_operand:DI 0 "register_operand" "=r")
6814         (zero_extend:DI
6815           (minus:SI (match_dup 1)
6816                     (match_dup 2))))]
6817   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6818    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6819   "sub{q}\t{%2, %0|%0, %2}"
6820   [(set_attr "type" "alu")
6821    (set_attr "mode" "DI")])
6822
6823 (define_expand "subhi3"
6824   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6825                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6826                              (match_operand:HI 2 "general_operand" "")))
6827               (clobber (reg:CC FLAGS_REG))])]
6828   "TARGET_HIMODE_MATH"
6829   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6830
6831 (define_insn "*subhi_1"
6832   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6833         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6834                   (match_operand:HI 2 "general_operand" "ri,rm")))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6837   "sub{w}\t{%2, %0|%0, %2}"
6838   [(set_attr "type" "alu")
6839    (set_attr "mode" "HI")])
6840
6841 (define_insn "*subhi_2"
6842   [(set (reg FLAGS_REG)
6843         (compare
6844           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6845                     (match_operand:HI 2 "general_operand" "ri,rm"))
6846           (const_int 0)))
6847    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6848         (minus:HI (match_dup 1) (match_dup 2)))]
6849   "ix86_match_ccmode (insn, CCGOCmode)
6850    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6851   "sub{w}\t{%2, %0|%0, %2}"
6852   [(set_attr "type" "alu")
6853    (set_attr "mode" "HI")])
6854
6855 (define_insn "*subhi_3"
6856   [(set (reg FLAGS_REG)
6857         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6858                  (match_operand:HI 2 "general_operand" "ri,rm")))
6859    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6860         (minus:HI (match_dup 1) (match_dup 2)))]
6861   "ix86_match_ccmode (insn, CCmode)
6862    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6863   "sub{w}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "mode" "HI")])
6866
6867 (define_expand "subqi3"
6868   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6869                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6870                              (match_operand:QI 2 "general_operand" "")))
6871               (clobber (reg:CC FLAGS_REG))])]
6872   "TARGET_QIMODE_MATH"
6873   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6874
6875 (define_insn "*subqi_1"
6876   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6877         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6879    (clobber (reg:CC FLAGS_REG))]
6880   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6881   "sub{b}\t{%2, %0|%0, %2}"
6882   [(set_attr "type" "alu")
6883    (set_attr "mode" "QI")])
6884
6885 (define_insn "*subqi_1_slp"
6886   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6887         (minus:QI (match_dup 0)
6888                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6889    (clobber (reg:CC FLAGS_REG))]
6890   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6891    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6892   "sub{b}\t{%1, %0|%0, %1}"
6893   [(set_attr "type" "alu1")
6894    (set_attr "mode" "QI")])
6895
6896 (define_insn "*subqi_2"
6897   [(set (reg FLAGS_REG)
6898         (compare
6899           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6900                     (match_operand:QI 2 "general_operand" "qi,qm"))
6901           (const_int 0)))
6902    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6903         (minus:HI (match_dup 1) (match_dup 2)))]
6904   "ix86_match_ccmode (insn, CCGOCmode)
6905    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6906   "sub{b}\t{%2, %0|%0, %2}"
6907   [(set_attr "type" "alu")
6908    (set_attr "mode" "QI")])
6909
6910 (define_insn "*subqi_3"
6911   [(set (reg FLAGS_REG)
6912         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6913                  (match_operand:QI 2 "general_operand" "qi,qm")))
6914    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6915         (minus:HI (match_dup 1) (match_dup 2)))]
6916   "ix86_match_ccmode (insn, CCmode)
6917    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6918   "sub{b}\t{%2, %0|%0, %2}"
6919   [(set_attr "type" "alu")
6920    (set_attr "mode" "QI")])
6921
6922 ;; The patterns that match these are at the end of this file.
6923
6924 (define_expand "subxf3"
6925   [(set (match_operand:XF 0 "register_operand" "")
6926         (minus:XF (match_operand:XF 1 "register_operand" "")
6927                   (match_operand:XF 2 "register_operand" "")))]
6928   "TARGET_80387"
6929   "")
6930
6931 (define_expand "subdf3"
6932   [(set (match_operand:DF 0 "register_operand" "")
6933         (minus:DF (match_operand:DF 1 "register_operand" "")
6934                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6935   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6936   "")
6937
6938 (define_expand "subsf3"
6939   [(set (match_operand:SF 0 "register_operand" "")
6940         (minus:SF (match_operand:SF 1 "register_operand" "")
6941                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6942   "TARGET_80387 || TARGET_SSE_MATH"
6943   "")
6944 \f
6945 ;; Multiply instructions
6946
6947 (define_expand "muldi3"
6948   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6949                    (mult:DI (match_operand:DI 1 "register_operand" "")
6950                             (match_operand:DI 2 "x86_64_general_operand" "")))
6951               (clobber (reg:CC FLAGS_REG))])]
6952   "TARGET_64BIT"
6953   "")
6954
6955 (define_insn "*muldi3_1_rex64"
6956   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6957         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6958                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6959    (clobber (reg:CC FLAGS_REG))]
6960   "TARGET_64BIT
6961    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6962   "@
6963    imul{q}\t{%2, %1, %0|%0, %1, %2}
6964    imul{q}\t{%2, %1, %0|%0, %1, %2}
6965    imul{q}\t{%2, %0|%0, %2}"
6966   [(set_attr "type" "imul")
6967    (set_attr "prefix_0f" "0,0,1")
6968    (set (attr "athlon_decode")
6969         (cond [(eq_attr "cpu" "athlon")
6970                   (const_string "vector")
6971                (eq_attr "alternative" "1")
6972                   (const_string "vector")
6973                (and (eq_attr "alternative" "2")
6974                     (match_operand 1 "memory_operand" ""))
6975                   (const_string "vector")]
6976               (const_string "direct")))
6977    (set_attr "mode" "DI")])
6978
6979 (define_expand "mulsi3"
6980   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6981                    (mult:SI (match_operand:SI 1 "register_operand" "")
6982                             (match_operand:SI 2 "general_operand" "")))
6983               (clobber (reg:CC FLAGS_REG))])]
6984   ""
6985   "")
6986
6987 (define_insn "*mulsi3_1"
6988   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6989         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6990                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6991    (clobber (reg:CC FLAGS_REG))]
6992   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6993   "@
6994    imul{l}\t{%2, %1, %0|%0, %1, %2}
6995    imul{l}\t{%2, %1, %0|%0, %1, %2}
6996    imul{l}\t{%2, %0|%0, %2}"
6997   [(set_attr "type" "imul")
6998    (set_attr "prefix_0f" "0,0,1")
6999    (set (attr "athlon_decode")
7000         (cond [(eq_attr "cpu" "athlon")
7001                   (const_string "vector")
7002                (eq_attr "alternative" "1")
7003                   (const_string "vector")
7004                (and (eq_attr "alternative" "2")
7005                     (match_operand 1 "memory_operand" ""))
7006                   (const_string "vector")]
7007               (const_string "direct")))
7008    (set_attr "mode" "SI")])
7009
7010 (define_insn "*mulsi3_1_zext"
7011   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7012         (zero_extend:DI
7013           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7014                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7015    (clobber (reg:CC FLAGS_REG))]
7016   "TARGET_64BIT
7017    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7018   "@
7019    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7020    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7021    imul{l}\t{%2, %k0|%k0, %2}"
7022   [(set_attr "type" "imul")
7023    (set_attr "prefix_0f" "0,0,1")
7024    (set (attr "athlon_decode")
7025         (cond [(eq_attr "cpu" "athlon")
7026                   (const_string "vector")
7027                (eq_attr "alternative" "1")
7028                   (const_string "vector")
7029                (and (eq_attr "alternative" "2")
7030                     (match_operand 1 "memory_operand" ""))
7031                   (const_string "vector")]
7032               (const_string "direct")))
7033    (set_attr "mode" "SI")])
7034
7035 (define_expand "mulhi3"
7036   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7037                    (mult:HI (match_operand:HI 1 "register_operand" "")
7038                             (match_operand:HI 2 "general_operand" "")))
7039               (clobber (reg:CC FLAGS_REG))])]
7040   "TARGET_HIMODE_MATH"
7041   "")
7042
7043 (define_insn "*mulhi3_1"
7044   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7045         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7046                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7047    (clobber (reg:CC FLAGS_REG))]
7048   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7049   "@
7050    imul{w}\t{%2, %1, %0|%0, %1, %2}
7051    imul{w}\t{%2, %1, %0|%0, %1, %2}
7052    imul{w}\t{%2, %0|%0, %2}"
7053   [(set_attr "type" "imul")
7054    (set_attr "prefix_0f" "0,0,1")
7055    (set (attr "athlon_decode")
7056         (cond [(eq_attr "cpu" "athlon")
7057                   (const_string "vector")
7058                (eq_attr "alternative" "1,2")
7059                   (const_string "vector")]
7060               (const_string "direct")))
7061    (set_attr "mode" "HI")])
7062
7063 (define_expand "mulqi3"
7064   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7065                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7066                             (match_operand:QI 2 "register_operand" "")))
7067               (clobber (reg:CC FLAGS_REG))])]
7068   "TARGET_QIMODE_MATH"
7069   "")
7070
7071 (define_insn "*mulqi3_1"
7072   [(set (match_operand:QI 0 "register_operand" "=a")
7073         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7074                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7075    (clobber (reg:CC FLAGS_REG))]
7076   "TARGET_QIMODE_MATH
7077    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7078   "mul{b}\t%2"
7079   [(set_attr "type" "imul")
7080    (set_attr "length_immediate" "0")
7081    (set (attr "athlon_decode")
7082      (if_then_else (eq_attr "cpu" "athlon")
7083         (const_string "vector")
7084         (const_string "direct")))
7085    (set_attr "mode" "QI")])
7086
7087 (define_expand "umulqihi3"
7088   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7089                    (mult:HI (zero_extend:HI
7090                               (match_operand:QI 1 "nonimmediate_operand" ""))
7091                             (zero_extend:HI
7092                               (match_operand:QI 2 "register_operand" ""))))
7093               (clobber (reg:CC FLAGS_REG))])]
7094   "TARGET_QIMODE_MATH"
7095   "")
7096
7097 (define_insn "*umulqihi3_1"
7098   [(set (match_operand:HI 0 "register_operand" "=a")
7099         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7100                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7101    (clobber (reg:CC FLAGS_REG))]
7102   "TARGET_QIMODE_MATH
7103    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7104   "mul{b}\t%2"
7105   [(set_attr "type" "imul")
7106    (set_attr "length_immediate" "0")
7107    (set (attr "athlon_decode")
7108      (if_then_else (eq_attr "cpu" "athlon")
7109         (const_string "vector")
7110         (const_string "direct")))
7111    (set_attr "mode" "QI")])
7112
7113 (define_expand "mulqihi3"
7114   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7115                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7116                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7117               (clobber (reg:CC FLAGS_REG))])]
7118   "TARGET_QIMODE_MATH"
7119   "")
7120
7121 (define_insn "*mulqihi3_insn"
7122   [(set (match_operand:HI 0 "register_operand" "=a")
7123         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7124                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7125    (clobber (reg:CC FLAGS_REG))]
7126   "TARGET_QIMODE_MATH
7127    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7128   "imul{b}\t%2"
7129   [(set_attr "type" "imul")
7130    (set_attr "length_immediate" "0")
7131    (set (attr "athlon_decode")
7132      (if_then_else (eq_attr "cpu" "athlon")
7133         (const_string "vector")
7134         (const_string "direct")))
7135    (set_attr "mode" "QI")])
7136
7137 (define_expand "umulditi3"
7138   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7139                    (mult:TI (zero_extend:TI
7140                               (match_operand:DI 1 "nonimmediate_operand" ""))
7141                             (zero_extend:TI
7142                               (match_operand:DI 2 "register_operand" ""))))
7143               (clobber (reg:CC FLAGS_REG))])]
7144   "TARGET_64BIT"
7145   "")
7146
7147 (define_insn "*umulditi3_insn"
7148   [(set (match_operand:TI 0 "register_operand" "=A")
7149         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7150                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7151    (clobber (reg:CC FLAGS_REG))]
7152   "TARGET_64BIT
7153    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7154   "mul{q}\t%2"
7155   [(set_attr "type" "imul")
7156    (set_attr "length_immediate" "0")
7157    (set (attr "athlon_decode")
7158      (if_then_else (eq_attr "cpu" "athlon")
7159         (const_string "vector")
7160         (const_string "double")))
7161    (set_attr "mode" "DI")])
7162
7163 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7164 (define_expand "umulsidi3"
7165   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7166                    (mult:DI (zero_extend:DI
7167                               (match_operand:SI 1 "nonimmediate_operand" ""))
7168                             (zero_extend:DI
7169                               (match_operand:SI 2 "register_operand" ""))))
7170               (clobber (reg:CC FLAGS_REG))])]
7171   "!TARGET_64BIT"
7172   "")
7173
7174 (define_insn "*umulsidi3_insn"
7175   [(set (match_operand:DI 0 "register_operand" "=A")
7176         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7177                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7178    (clobber (reg:CC FLAGS_REG))]
7179   "!TARGET_64BIT
7180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7181   "mul{l}\t%2"
7182   [(set_attr "type" "imul")
7183    (set_attr "length_immediate" "0")
7184    (set (attr "athlon_decode")
7185      (if_then_else (eq_attr "cpu" "athlon")
7186         (const_string "vector")
7187         (const_string "double")))
7188    (set_attr "mode" "SI")])
7189
7190 (define_expand "mulditi3"
7191   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7192                    (mult:TI (sign_extend:TI
7193                               (match_operand:DI 1 "nonimmediate_operand" ""))
7194                             (sign_extend:TI
7195                               (match_operand:DI 2 "register_operand" ""))))
7196               (clobber (reg:CC FLAGS_REG))])]
7197   "TARGET_64BIT"
7198   "")
7199
7200 (define_insn "*mulditi3_insn"
7201   [(set (match_operand:TI 0 "register_operand" "=A")
7202         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7203                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7204    (clobber (reg:CC FLAGS_REG))]
7205   "TARGET_64BIT
7206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7207   "imul{q}\t%2"
7208   [(set_attr "type" "imul")
7209    (set_attr "length_immediate" "0")
7210    (set (attr "athlon_decode")
7211      (if_then_else (eq_attr "cpu" "athlon")
7212         (const_string "vector")
7213         (const_string "double")))
7214    (set_attr "mode" "DI")])
7215
7216 (define_expand "mulsidi3"
7217   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7218                    (mult:DI (sign_extend:DI
7219                               (match_operand:SI 1 "nonimmediate_operand" ""))
7220                             (sign_extend:DI
7221                               (match_operand:SI 2 "register_operand" ""))))
7222               (clobber (reg:CC FLAGS_REG))])]
7223   "!TARGET_64BIT"
7224   "")
7225
7226 (define_insn "*mulsidi3_insn"
7227   [(set (match_operand:DI 0 "register_operand" "=A")
7228         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7229                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7230    (clobber (reg:CC FLAGS_REG))]
7231   "!TARGET_64BIT
7232    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7233   "imul{l}\t%2"
7234   [(set_attr "type" "imul")
7235    (set_attr "length_immediate" "0")
7236    (set (attr "athlon_decode")
7237      (if_then_else (eq_attr "cpu" "athlon")
7238         (const_string "vector")
7239         (const_string "double")))
7240    (set_attr "mode" "SI")])
7241
7242 (define_expand "umuldi3_highpart"
7243   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7244                    (truncate:DI
7245                      (lshiftrt:TI
7246                        (mult:TI (zero_extend:TI
7247                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7248                                 (zero_extend:TI
7249                                   (match_operand:DI 2 "register_operand" "")))
7250                        (const_int 64))))
7251               (clobber (match_scratch:DI 3 ""))
7252               (clobber (reg:CC FLAGS_REG))])]
7253   "TARGET_64BIT"
7254   "")
7255
7256 (define_insn "*umuldi3_highpart_rex64"
7257   [(set (match_operand:DI 0 "register_operand" "=d")
7258         (truncate:DI
7259           (lshiftrt:TI
7260             (mult:TI (zero_extend:TI
7261                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7262                      (zero_extend:TI
7263                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7264             (const_int 64))))
7265    (clobber (match_scratch:DI 3 "=1"))
7266    (clobber (reg:CC FLAGS_REG))]
7267   "TARGET_64BIT
7268    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7269   "mul{q}\t%2"
7270   [(set_attr "type" "imul")
7271    (set_attr "length_immediate" "0")
7272    (set (attr "athlon_decode")
7273      (if_then_else (eq_attr "cpu" "athlon")
7274         (const_string "vector")
7275         (const_string "double")))
7276    (set_attr "mode" "DI")])
7277
7278 (define_expand "umulsi3_highpart"
7279   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7280                    (truncate:SI
7281                      (lshiftrt:DI
7282                        (mult:DI (zero_extend:DI
7283                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7284                                 (zero_extend:DI
7285                                   (match_operand:SI 2 "register_operand" "")))
7286                        (const_int 32))))
7287               (clobber (match_scratch:SI 3 ""))
7288               (clobber (reg:CC FLAGS_REG))])]
7289   ""
7290   "")
7291
7292 (define_insn "*umulsi3_highpart_insn"
7293   [(set (match_operand:SI 0 "register_operand" "=d")
7294         (truncate:SI
7295           (lshiftrt:DI
7296             (mult:DI (zero_extend:DI
7297                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7298                      (zero_extend:DI
7299                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300             (const_int 32))))
7301    (clobber (match_scratch:SI 3 "=1"))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7304   "mul{l}\t%2"
7305   [(set_attr "type" "imul")
7306    (set_attr "length_immediate" "0")
7307    (set (attr "athlon_decode")
7308      (if_then_else (eq_attr "cpu" "athlon")
7309         (const_string "vector")
7310         (const_string "double")))
7311    (set_attr "mode" "SI")])
7312
7313 (define_insn "*umulsi3_highpart_zext"
7314   [(set (match_operand:DI 0 "register_operand" "=d")
7315         (zero_extend:DI (truncate:SI
7316           (lshiftrt:DI
7317             (mult:DI (zero_extend:DI
7318                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7319                      (zero_extend:DI
7320                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7321             (const_int 32)))))
7322    (clobber (match_scratch:SI 3 "=1"))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_64BIT
7325    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7326   "mul{l}\t%2"
7327   [(set_attr "type" "imul")
7328    (set_attr "length_immediate" "0")
7329    (set (attr "athlon_decode")
7330      (if_then_else (eq_attr "cpu" "athlon")
7331         (const_string "vector")
7332         (const_string "double")))
7333    (set_attr "mode" "SI")])
7334
7335 (define_expand "smuldi3_highpart"
7336   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7337                    (truncate:DI
7338                      (lshiftrt:TI
7339                        (mult:TI (sign_extend:TI
7340                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7341                                 (sign_extend:TI
7342                                   (match_operand:DI 2 "register_operand" "")))
7343                        (const_int 64))))
7344               (clobber (match_scratch:DI 3 ""))
7345               (clobber (reg:CC FLAGS_REG))])]
7346   "TARGET_64BIT"
7347   "")
7348
7349 (define_insn "*smuldi3_highpart_rex64"
7350   [(set (match_operand:DI 0 "register_operand" "=d")
7351         (truncate:DI
7352           (lshiftrt:TI
7353             (mult:TI (sign_extend:TI
7354                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7355                      (sign_extend:TI
7356                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7357             (const_int 64))))
7358    (clobber (match_scratch:DI 3 "=1"))
7359    (clobber (reg:CC FLAGS_REG))]
7360   "TARGET_64BIT
7361    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7362   "imul{q}\t%2"
7363   [(set_attr "type" "imul")
7364    (set (attr "athlon_decode")
7365      (if_then_else (eq_attr "cpu" "athlon")
7366         (const_string "vector")
7367         (const_string "double")))
7368    (set_attr "mode" "DI")])
7369
7370 (define_expand "smulsi3_highpart"
7371   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7372                    (truncate:SI
7373                      (lshiftrt:DI
7374                        (mult:DI (sign_extend:DI
7375                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7376                                 (sign_extend:DI
7377                                   (match_operand:SI 2 "register_operand" "")))
7378                        (const_int 32))))
7379               (clobber (match_scratch:SI 3 ""))
7380               (clobber (reg:CC FLAGS_REG))])]
7381   ""
7382   "")
7383
7384 (define_insn "*smulsi3_highpart_insn"
7385   [(set (match_operand:SI 0 "register_operand" "=d")
7386         (truncate:SI
7387           (lshiftrt:DI
7388             (mult:DI (sign_extend:DI
7389                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7390                      (sign_extend:DI
7391                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7392             (const_int 32))))
7393    (clobber (match_scratch:SI 3 "=1"))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7396   "imul{l}\t%2"
7397   [(set_attr "type" "imul")
7398    (set (attr "athlon_decode")
7399      (if_then_else (eq_attr "cpu" "athlon")
7400         (const_string "vector")
7401         (const_string "double")))
7402    (set_attr "mode" "SI")])
7403
7404 (define_insn "*smulsi3_highpart_zext"
7405   [(set (match_operand:DI 0 "register_operand" "=d")
7406         (zero_extend:DI (truncate:SI
7407           (lshiftrt:DI
7408             (mult:DI (sign_extend:DI
7409                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7410                      (sign_extend:DI
7411                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7412             (const_int 32)))))
7413    (clobber (match_scratch:SI 3 "=1"))
7414    (clobber (reg:CC FLAGS_REG))]
7415   "TARGET_64BIT
7416    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7417   "imul{l}\t%2"
7418   [(set_attr "type" "imul")
7419    (set (attr "athlon_decode")
7420      (if_then_else (eq_attr "cpu" "athlon")
7421         (const_string "vector")
7422         (const_string "double")))
7423    (set_attr "mode" "SI")])
7424
7425 ;; The patterns that match these are at the end of this file.
7426
7427 (define_expand "mulxf3"
7428   [(set (match_operand:XF 0 "register_operand" "")
7429         (mult:XF (match_operand:XF 1 "register_operand" "")
7430                  (match_operand:XF 2 "register_operand" "")))]
7431   "TARGET_80387"
7432   "")
7433
7434 (define_expand "muldf3"
7435   [(set (match_operand:DF 0 "register_operand" "")
7436         (mult:DF (match_operand:DF 1 "register_operand" "")
7437                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7438   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7439   "")
7440
7441 (define_expand "mulsf3"
7442   [(set (match_operand:SF 0 "register_operand" "")
7443         (mult:SF (match_operand:SF 1 "register_operand" "")
7444                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7445   "TARGET_80387 || TARGET_SSE_MATH"
7446   "")
7447 \f
7448 ;; Divide instructions
7449
7450 (define_insn "divqi3"
7451   [(set (match_operand:QI 0 "register_operand" "=a")
7452         (div:QI (match_operand:HI 1 "register_operand" "0")
7453                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7454    (clobber (reg:CC FLAGS_REG))]
7455   "TARGET_QIMODE_MATH"
7456   "idiv{b}\t%2"
7457   [(set_attr "type" "idiv")
7458    (set_attr "mode" "QI")])
7459
7460 (define_insn "udivqi3"
7461   [(set (match_operand:QI 0 "register_operand" "=a")
7462         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7463                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "TARGET_QIMODE_MATH"
7466   "div{b}\t%2"
7467   [(set_attr "type" "idiv")
7468    (set_attr "mode" "QI")])
7469
7470 ;; The patterns that match these are at the end of this file.
7471
7472 (define_expand "divxf3"
7473   [(set (match_operand:XF 0 "register_operand" "")
7474         (div:XF (match_operand:XF 1 "register_operand" "")
7475                 (match_operand:XF 2 "register_operand" "")))]
7476   "TARGET_80387"
7477   "")
7478
7479 (define_expand "divdf3"
7480   [(set (match_operand:DF 0 "register_operand" "")
7481         (div:DF (match_operand:DF 1 "register_operand" "")
7482                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7483    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7484    "")
7485  
7486 (define_expand "divsf3"
7487   [(set (match_operand:SF 0 "register_operand" "")
7488         (div:SF (match_operand:SF 1 "register_operand" "")
7489                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7490   "TARGET_80387 || TARGET_SSE_MATH"
7491   "")
7492 \f
7493 ;; Remainder instructions.
7494
7495 (define_expand "divmoddi4"
7496   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7497                    (div:DI (match_operand:DI 1 "register_operand" "")
7498                            (match_operand:DI 2 "nonimmediate_operand" "")))
7499               (set (match_operand:DI 3 "register_operand" "")
7500                    (mod:DI (match_dup 1) (match_dup 2)))
7501               (clobber (reg:CC FLAGS_REG))])]
7502   "TARGET_64BIT"
7503   "")
7504
7505 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7506 ;; Penalize eax case slightly because it results in worse scheduling
7507 ;; of code.
7508 (define_insn "*divmoddi4_nocltd_rex64"
7509   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7510         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7511                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7512    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7513         (mod:DI (match_dup 2) (match_dup 3)))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7516   "#"
7517   [(set_attr "type" "multi")])
7518
7519 (define_insn "*divmoddi4_cltd_rex64"
7520   [(set (match_operand:DI 0 "register_operand" "=a")
7521         (div:DI (match_operand:DI 2 "register_operand" "a")
7522                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7523    (set (match_operand:DI 1 "register_operand" "=&d")
7524         (mod:DI (match_dup 2) (match_dup 3)))
7525    (clobber (reg:CC FLAGS_REG))]
7526   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7527   "#"
7528   [(set_attr "type" "multi")])
7529
7530 (define_insn "*divmoddi_noext_rex64"
7531   [(set (match_operand:DI 0 "register_operand" "=a")
7532         (div:DI (match_operand:DI 1 "register_operand" "0")
7533                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7534    (set (match_operand:DI 3 "register_operand" "=d")
7535         (mod:DI (match_dup 1) (match_dup 2)))
7536    (use (match_operand:DI 4 "register_operand" "3"))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "TARGET_64BIT"
7539   "idiv{q}\t%2"
7540   [(set_attr "type" "idiv")
7541    (set_attr "mode" "DI")])
7542
7543 (define_split
7544   [(set (match_operand:DI 0 "register_operand" "")
7545         (div:DI (match_operand:DI 1 "register_operand" "")
7546                 (match_operand:DI 2 "nonimmediate_operand" "")))
7547    (set (match_operand:DI 3 "register_operand" "")
7548         (mod:DI (match_dup 1) (match_dup 2)))
7549    (clobber (reg:CC FLAGS_REG))]
7550   "TARGET_64BIT && reload_completed"
7551   [(parallel [(set (match_dup 3)
7552                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7553               (clobber (reg:CC FLAGS_REG))])
7554    (parallel [(set (match_dup 0)
7555                    (div:DI (reg:DI 0) (match_dup 2)))
7556               (set (match_dup 3)
7557                    (mod:DI (reg:DI 0) (match_dup 2)))
7558               (use (match_dup 3))
7559               (clobber (reg:CC FLAGS_REG))])]
7560 {
7561   /* Avoid use of cltd in favor of a mov+shift.  */
7562   if (!TARGET_USE_CLTD && !optimize_size)
7563     {
7564       if (true_regnum (operands[1]))
7565         emit_move_insn (operands[0], operands[1]);
7566       else
7567         emit_move_insn (operands[3], operands[1]);
7568       operands[4] = operands[3];
7569     }
7570   else
7571     {
7572       if (true_regnum (operands[1]))
7573         abort();
7574       operands[4] = operands[1];
7575     }
7576 })
7577
7578
7579 (define_expand "divmodsi4"
7580   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7581                    (div:SI (match_operand:SI 1 "register_operand" "")
7582                            (match_operand:SI 2 "nonimmediate_operand" "")))
7583               (set (match_operand:SI 3 "register_operand" "")
7584                    (mod:SI (match_dup 1) (match_dup 2)))
7585               (clobber (reg:CC FLAGS_REG))])]
7586   ""
7587   "")
7588
7589 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7590 ;; Penalize eax case slightly because it results in worse scheduling
7591 ;; of code.
7592 (define_insn "*divmodsi4_nocltd"
7593   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7594         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7595                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7596    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7597         (mod:SI (match_dup 2) (match_dup 3)))
7598    (clobber (reg:CC FLAGS_REG))]
7599   "!optimize_size && !TARGET_USE_CLTD"
7600   "#"
7601   [(set_attr "type" "multi")])
7602
7603 (define_insn "*divmodsi4_cltd"
7604   [(set (match_operand:SI 0 "register_operand" "=a")
7605         (div:SI (match_operand:SI 2 "register_operand" "a")
7606                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7607    (set (match_operand:SI 1 "register_operand" "=&d")
7608         (mod:SI (match_dup 2) (match_dup 3)))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "optimize_size || TARGET_USE_CLTD"
7611   "#"
7612   [(set_attr "type" "multi")])
7613
7614 (define_insn "*divmodsi_noext"
7615   [(set (match_operand:SI 0 "register_operand" "=a")
7616         (div:SI (match_operand:SI 1 "register_operand" "0")
7617                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7618    (set (match_operand:SI 3 "register_operand" "=d")
7619         (mod:SI (match_dup 1) (match_dup 2)))
7620    (use (match_operand:SI 4 "register_operand" "3"))
7621    (clobber (reg:CC FLAGS_REG))]
7622   ""
7623   "idiv{l}\t%2"
7624   [(set_attr "type" "idiv")
7625    (set_attr "mode" "SI")])
7626
7627 (define_split
7628   [(set (match_operand:SI 0 "register_operand" "")
7629         (div:SI (match_operand:SI 1 "register_operand" "")
7630                 (match_operand:SI 2 "nonimmediate_operand" "")))
7631    (set (match_operand:SI 3 "register_operand" "")
7632         (mod:SI (match_dup 1) (match_dup 2)))
7633    (clobber (reg:CC FLAGS_REG))]
7634   "reload_completed"
7635   [(parallel [(set (match_dup 3)
7636                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7637               (clobber (reg:CC FLAGS_REG))])
7638    (parallel [(set (match_dup 0)
7639                    (div:SI (reg:SI 0) (match_dup 2)))
7640               (set (match_dup 3)
7641                    (mod:SI (reg:SI 0) (match_dup 2)))
7642               (use (match_dup 3))
7643               (clobber (reg:CC FLAGS_REG))])]
7644 {
7645   /* Avoid use of cltd in favor of a mov+shift.  */
7646   if (!TARGET_USE_CLTD && !optimize_size)
7647     {
7648       if (true_regnum (operands[1]))
7649         emit_move_insn (operands[0], operands[1]);
7650       else
7651         emit_move_insn (operands[3], operands[1]);
7652       operands[4] = operands[3];
7653     }
7654   else
7655     {
7656       if (true_regnum (operands[1]))
7657         abort();
7658       operands[4] = operands[1];
7659     }
7660 })
7661 ;; %%% Split me.
7662 (define_insn "divmodhi4"
7663   [(set (match_operand:HI 0 "register_operand" "=a")
7664         (div:HI (match_operand:HI 1 "register_operand" "0")
7665                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7666    (set (match_operand:HI 3 "register_operand" "=&d")
7667         (mod:HI (match_dup 1) (match_dup 2)))
7668    (clobber (reg:CC FLAGS_REG))]
7669   "TARGET_HIMODE_MATH"
7670   "cwtd\;idiv{w}\t%2"
7671   [(set_attr "type" "multi")
7672    (set_attr "length_immediate" "0")
7673    (set_attr "mode" "SI")])
7674
7675 (define_insn "udivmoddi4"
7676   [(set (match_operand:DI 0 "register_operand" "=a")
7677         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7678                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7679    (set (match_operand:DI 3 "register_operand" "=&d")
7680         (umod:DI (match_dup 1) (match_dup 2)))
7681    (clobber (reg:CC FLAGS_REG))]
7682   "TARGET_64BIT"
7683   "xor{q}\t%3, %3\;div{q}\t%2"
7684   [(set_attr "type" "multi")
7685    (set_attr "length_immediate" "0")
7686    (set_attr "mode" "DI")])
7687
7688 (define_insn "*udivmoddi4_noext"
7689   [(set (match_operand:DI 0 "register_operand" "=a")
7690         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7691                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7692    (set (match_operand:DI 3 "register_operand" "=d")
7693         (umod:DI (match_dup 1) (match_dup 2)))
7694    (use (match_dup 3))
7695    (clobber (reg:CC FLAGS_REG))]
7696   "TARGET_64BIT"
7697   "div{q}\t%2"
7698   [(set_attr "type" "idiv")
7699    (set_attr "mode" "DI")])
7700
7701 (define_split
7702   [(set (match_operand:DI 0 "register_operand" "")
7703         (udiv:DI (match_operand:DI 1 "register_operand" "")
7704                  (match_operand:DI 2 "nonimmediate_operand" "")))
7705    (set (match_operand:DI 3 "register_operand" "")
7706         (umod:DI (match_dup 1) (match_dup 2)))
7707    (clobber (reg:CC FLAGS_REG))]
7708   "TARGET_64BIT && reload_completed"
7709   [(set (match_dup 3) (const_int 0))
7710    (parallel [(set (match_dup 0)
7711                    (udiv:DI (match_dup 1) (match_dup 2)))
7712               (set (match_dup 3)
7713                    (umod:DI (match_dup 1) (match_dup 2)))
7714               (use (match_dup 3))
7715               (clobber (reg:CC FLAGS_REG))])]
7716   "")
7717
7718 (define_insn "udivmodsi4"
7719   [(set (match_operand:SI 0 "register_operand" "=a")
7720         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7721                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7722    (set (match_operand:SI 3 "register_operand" "=&d")
7723         (umod:SI (match_dup 1) (match_dup 2)))
7724    (clobber (reg:CC FLAGS_REG))]
7725   ""
7726   "xor{l}\t%3, %3\;div{l}\t%2"
7727   [(set_attr "type" "multi")
7728    (set_attr "length_immediate" "0")
7729    (set_attr "mode" "SI")])
7730
7731 (define_insn "*udivmodsi4_noext"
7732   [(set (match_operand:SI 0 "register_operand" "=a")
7733         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7734                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7735    (set (match_operand:SI 3 "register_operand" "=d")
7736         (umod:SI (match_dup 1) (match_dup 2)))
7737    (use (match_dup 3))
7738    (clobber (reg:CC FLAGS_REG))]
7739   ""
7740   "div{l}\t%2"
7741   [(set_attr "type" "idiv")
7742    (set_attr "mode" "SI")])
7743
7744 (define_split
7745   [(set (match_operand:SI 0 "register_operand" "")
7746         (udiv:SI (match_operand:SI 1 "register_operand" "")
7747                  (match_operand:SI 2 "nonimmediate_operand" "")))
7748    (set (match_operand:SI 3 "register_operand" "")
7749         (umod:SI (match_dup 1) (match_dup 2)))
7750    (clobber (reg:CC FLAGS_REG))]
7751   "reload_completed"
7752   [(set (match_dup 3) (const_int 0))
7753    (parallel [(set (match_dup 0)
7754                    (udiv:SI (match_dup 1) (match_dup 2)))
7755               (set (match_dup 3)
7756                    (umod:SI (match_dup 1) (match_dup 2)))
7757               (use (match_dup 3))
7758               (clobber (reg:CC FLAGS_REG))])]
7759   "")
7760
7761 (define_expand "udivmodhi4"
7762   [(set (match_dup 4) (const_int 0))
7763    (parallel [(set (match_operand:HI 0 "register_operand" "")
7764                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7765                             (match_operand:HI 2 "nonimmediate_operand" "")))
7766               (set (match_operand:HI 3 "register_operand" "")
7767                    (umod:HI (match_dup 1) (match_dup 2)))
7768               (use (match_dup 4))
7769               (clobber (reg:CC FLAGS_REG))])]
7770   "TARGET_HIMODE_MATH"
7771   "operands[4] = gen_reg_rtx (HImode);")
7772
7773 (define_insn "*udivmodhi_noext"
7774   [(set (match_operand:HI 0 "register_operand" "=a")
7775         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7776                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7777    (set (match_operand:HI 3 "register_operand" "=d")
7778         (umod:HI (match_dup 1) (match_dup 2)))
7779    (use (match_operand:HI 4 "register_operand" "3"))
7780    (clobber (reg:CC FLAGS_REG))]
7781   ""
7782   "div{w}\t%2"
7783   [(set_attr "type" "idiv")
7784    (set_attr "mode" "HI")])
7785
7786 ;; We cannot use div/idiv for double division, because it causes
7787 ;; "division by zero" on the overflow and that's not what we expect
7788 ;; from truncate.  Because true (non truncating) double division is
7789 ;; never generated, we can't create this insn anyway.
7790 ;
7791 ;(define_insn ""
7792 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7793 ;       (truncate:SI
7794 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7795 ;                  (zero_extend:DI
7796 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7797 ;   (set (match_operand:SI 3 "register_operand" "=d")
7798 ;       (truncate:SI
7799 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7800 ;   (clobber (reg:CC FLAGS_REG))]
7801 ;  ""
7802 ;  "div{l}\t{%2, %0|%0, %2}"
7803 ;  [(set_attr "type" "idiv")])
7804 \f
7805 ;;- Logical AND instructions
7806
7807 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7808 ;; Note that this excludes ah.
7809
7810 (define_insn "*testdi_1_rex64"
7811   [(set (reg FLAGS_REG)
7812         (compare
7813           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7814                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7815           (const_int 0)))]
7816   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7817    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7818   "@
7819    test{l}\t{%k1, %k0|%k0, %k1}
7820    test{l}\t{%k1, %k0|%k0, %k1}
7821    test{q}\t{%1, %0|%0, %1}
7822    test{q}\t{%1, %0|%0, %1}
7823    test{q}\t{%1, %0|%0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "modrm" "0,1,0,1,1")
7826    (set_attr "mode" "SI,SI,DI,DI,DI")
7827    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7828
7829 (define_insn "testsi_1"
7830   [(set (reg FLAGS_REG)
7831         (compare
7832           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7833                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7834           (const_int 0)))]
7835   "ix86_match_ccmode (insn, CCNOmode)
7836    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7837   "test{l}\t{%1, %0|%0, %1}"
7838   [(set_attr "type" "test")
7839    (set_attr "modrm" "0,1,1")
7840    (set_attr "mode" "SI")
7841    (set_attr "pent_pair" "uv,np,uv")])
7842
7843 (define_expand "testsi_ccno_1"
7844   [(set (reg:CCNO FLAGS_REG)
7845         (compare:CCNO
7846           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7847                   (match_operand:SI 1 "nonmemory_operand" ""))
7848           (const_int 0)))]
7849   ""
7850   "")
7851
7852 (define_insn "*testhi_1"
7853   [(set (reg FLAGS_REG)
7854         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7855                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7856                  (const_int 0)))]
7857   "ix86_match_ccmode (insn, CCNOmode)
7858    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7859   "test{w}\t{%1, %0|%0, %1}"
7860   [(set_attr "type" "test")
7861    (set_attr "modrm" "0,1,1")
7862    (set_attr "mode" "HI")
7863    (set_attr "pent_pair" "uv,np,uv")])
7864
7865 (define_expand "testqi_ccz_1"
7866   [(set (reg:CCZ FLAGS_REG)
7867         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7868                              (match_operand:QI 1 "nonmemory_operand" ""))
7869                  (const_int 0)))]
7870   ""
7871   "")
7872
7873 (define_insn "*testqi_1_maybe_si"
7874   [(set (reg FLAGS_REG)
7875         (compare
7876           (and:QI
7877             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7878             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7879           (const_int 0)))]
7880    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7881     && ix86_match_ccmode (insn,
7882                          GET_CODE (operands[1]) == CONST_INT
7883                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7884 {
7885   if (which_alternative == 3)
7886     {
7887       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7888         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7889       return "test{l}\t{%1, %k0|%k0, %1}";
7890     }
7891   return "test{b}\t{%1, %0|%0, %1}";
7892 }
7893   [(set_attr "type" "test")
7894    (set_attr "modrm" "0,1,1,1")
7895    (set_attr "mode" "QI,QI,QI,SI")
7896    (set_attr "pent_pair" "uv,np,uv,np")])
7897
7898 (define_insn "*testqi_1"
7899   [(set (reg FLAGS_REG)
7900         (compare
7901           (and:QI
7902             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7903             (match_operand:QI 1 "general_operand" "n,n,qn"))
7904           (const_int 0)))]
7905   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7906    && ix86_match_ccmode (insn, CCNOmode)"
7907   "test{b}\t{%1, %0|%0, %1}"
7908   [(set_attr "type" "test")
7909    (set_attr "modrm" "0,1,1")
7910    (set_attr "mode" "QI")
7911    (set_attr "pent_pair" "uv,np,uv")])
7912
7913 (define_expand "testqi_ext_ccno_0"
7914   [(set (reg:CCNO FLAGS_REG)
7915         (compare:CCNO
7916           (and:SI
7917             (zero_extract:SI
7918               (match_operand 0 "ext_register_operand" "")
7919               (const_int 8)
7920               (const_int 8))
7921             (match_operand 1 "const_int_operand" ""))
7922           (const_int 0)))]
7923   ""
7924   "")
7925
7926 (define_insn "*testqi_ext_0"
7927   [(set (reg FLAGS_REG)
7928         (compare
7929           (and:SI
7930             (zero_extract:SI
7931               (match_operand 0 "ext_register_operand" "Q")
7932               (const_int 8)
7933               (const_int 8))
7934             (match_operand 1 "const_int_operand" "n"))
7935           (const_int 0)))]
7936   "ix86_match_ccmode (insn, CCNOmode)"
7937   "test{b}\t{%1, %h0|%h0, %1}"
7938   [(set_attr "type" "test")
7939    (set_attr "mode" "QI")
7940    (set_attr "length_immediate" "1")
7941    (set_attr "pent_pair" "np")])
7942
7943 (define_insn "*testqi_ext_1"
7944   [(set (reg FLAGS_REG)
7945         (compare
7946           (and:SI
7947             (zero_extract:SI
7948               (match_operand 0 "ext_register_operand" "Q")
7949               (const_int 8)
7950               (const_int 8))
7951             (zero_extend:SI
7952               (match_operand:QI 1 "general_operand" "Qm")))
7953           (const_int 0)))]
7954   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7955    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7956   "test{b}\t{%1, %h0|%h0, %1}"
7957   [(set_attr "type" "test")
7958    (set_attr "mode" "QI")])
7959
7960 (define_insn "*testqi_ext_1_rex64"
7961   [(set (reg FLAGS_REG)
7962         (compare
7963           (and:SI
7964             (zero_extract:SI
7965               (match_operand 0 "ext_register_operand" "Q")
7966               (const_int 8)
7967               (const_int 8))
7968             (zero_extend:SI
7969               (match_operand:QI 1 "register_operand" "Q")))
7970           (const_int 0)))]
7971   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7972   "test{b}\t{%1, %h0|%h0, %1}"
7973   [(set_attr "type" "test")
7974    (set_attr "mode" "QI")])
7975
7976 (define_insn "*testqi_ext_2"
7977   [(set (reg FLAGS_REG)
7978         (compare
7979           (and:SI
7980             (zero_extract:SI
7981               (match_operand 0 "ext_register_operand" "Q")
7982               (const_int 8)
7983               (const_int 8))
7984             (zero_extract:SI
7985               (match_operand 1 "ext_register_operand" "Q")
7986               (const_int 8)
7987               (const_int 8)))
7988           (const_int 0)))]
7989   "ix86_match_ccmode (insn, CCNOmode)"
7990   "test{b}\t{%h1, %h0|%h0, %h1}"
7991   [(set_attr "type" "test")
7992    (set_attr "mode" "QI")])
7993
7994 ;; Combine likes to form bit extractions for some tests.  Humor it.
7995 (define_insn "*testqi_ext_3"
7996   [(set (reg FLAGS_REG)
7997         (compare (zero_extract:SI
7998                    (match_operand 0 "nonimmediate_operand" "rm")
7999                    (match_operand:SI 1 "const_int_operand" "")
8000                    (match_operand:SI 2 "const_int_operand" ""))
8001                  (const_int 0)))]
8002   "ix86_match_ccmode (insn, CCNOmode)
8003    && (GET_MODE (operands[0]) == SImode
8004        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8005        || GET_MODE (operands[0]) == HImode
8006        || GET_MODE (operands[0]) == QImode)"
8007   "#")
8008
8009 (define_insn "*testqi_ext_3_rex64"
8010   [(set (reg FLAGS_REG)
8011         (compare (zero_extract:DI
8012                    (match_operand 0 "nonimmediate_operand" "rm")
8013                    (match_operand:DI 1 "const_int_operand" "")
8014                    (match_operand:DI 2 "const_int_operand" ""))
8015                  (const_int 0)))]
8016   "TARGET_64BIT
8017    && ix86_match_ccmode (insn, CCNOmode)
8018    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8019    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8020    /* Ensure that resulting mask is zero or sign extended operand.  */
8021    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8022        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8023            && INTVAL (operands[1]) > 32))
8024    && (GET_MODE (operands[0]) == SImode
8025        || GET_MODE (operands[0]) == DImode
8026        || GET_MODE (operands[0]) == HImode
8027        || GET_MODE (operands[0]) == QImode)"
8028   "#")
8029
8030 (define_split
8031   [(set (match_operand 0 "flags_reg_operand" "")
8032         (match_operator 1 "compare_operator"
8033           [(zero_extract
8034              (match_operand 2 "nonimmediate_operand" "")
8035              (match_operand 3 "const_int_operand" "")
8036              (match_operand 4 "const_int_operand" ""))
8037            (const_int 0)]))]
8038   "ix86_match_ccmode (insn, CCNOmode)"
8039   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8040 {
8041   rtx val = operands[2];
8042   HOST_WIDE_INT len = INTVAL (operands[3]);
8043   HOST_WIDE_INT pos = INTVAL (operands[4]);
8044   HOST_WIDE_INT mask;
8045   enum machine_mode mode, submode;
8046
8047   mode = GET_MODE (val);
8048   if (GET_CODE (val) == MEM)
8049     {
8050       /* ??? Combine likes to put non-volatile mem extractions in QImode
8051          no matter the size of the test.  So find a mode that works.  */
8052       if (! MEM_VOLATILE_P (val))
8053         {
8054           mode = smallest_mode_for_size (pos + len, MODE_INT);
8055           val = adjust_address (val, mode, 0);
8056         }
8057     }
8058   else if (GET_CODE (val) == SUBREG
8059            && (submode = GET_MODE (SUBREG_REG (val)),
8060                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8061            && pos + len <= GET_MODE_BITSIZE (submode))
8062     {
8063       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8064       mode = submode;
8065       val = SUBREG_REG (val);
8066     }
8067   else if (mode == HImode && pos + len <= 8)
8068     {
8069       /* Small HImode tests can be converted to QImode.  */
8070       mode = QImode;
8071       val = gen_lowpart (QImode, val);
8072     }
8073
8074   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8075   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8076
8077   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8078 })
8079
8080 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8081 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8082 ;; this is relatively important trick.
8083 ;; Do the conversion only post-reload to avoid limiting of the register class
8084 ;; to QI regs.
8085 (define_split
8086   [(set (match_operand 0 "flags_reg_operand" "")
8087         (match_operator 1 "compare_operator"
8088           [(and (match_operand 2 "register_operand" "")
8089                 (match_operand 3 "const_int_operand" ""))
8090            (const_int 0)]))]
8091    "reload_completed
8092     && QI_REG_P (operands[2])
8093     && GET_MODE (operands[2]) != QImode
8094     && ((ix86_match_ccmode (insn, CCZmode)
8095          && !(INTVAL (operands[3]) & ~(255 << 8)))
8096         || (ix86_match_ccmode (insn, CCNOmode)
8097             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8098   [(set (match_dup 0)
8099         (match_op_dup 1
8100           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8101                    (match_dup 3))
8102            (const_int 0)]))]
8103   "operands[2] = gen_lowpart (SImode, operands[2]);
8104    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8105
8106 (define_split
8107   [(set (match_operand 0 "flags_reg_operand" "")
8108         (match_operator 1 "compare_operator"
8109           [(and (match_operand 2 "nonimmediate_operand" "")
8110                 (match_operand 3 "const_int_operand" ""))
8111            (const_int 0)]))]
8112    "reload_completed
8113     && GET_MODE (operands[2]) != QImode
8114     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8115     && ((ix86_match_ccmode (insn, CCZmode)
8116          && !(INTVAL (operands[3]) & ~255))
8117         || (ix86_match_ccmode (insn, CCNOmode)
8118             && !(INTVAL (operands[3]) & ~127)))"
8119   [(set (match_dup 0)
8120         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8121                          (const_int 0)]))]
8122   "operands[2] = gen_lowpart (QImode, operands[2]);
8123    operands[3] = gen_lowpart (QImode, operands[3]);")
8124
8125
8126 ;; %%% This used to optimize known byte-wide and operations to memory,
8127 ;; and sometimes to QImode registers.  If this is considered useful,
8128 ;; it should be done with splitters.
8129
8130 (define_expand "anddi3"
8131   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8132         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8133                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "TARGET_64BIT"
8136   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8137
8138 (define_insn "*anddi_1_rex64"
8139   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8140         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8141                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8142    (clobber (reg:CC FLAGS_REG))]
8143   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8144 {
8145   switch (get_attr_type (insn))
8146     {
8147     case TYPE_IMOVX:
8148       {
8149         enum machine_mode mode;
8150
8151         if (GET_CODE (operands[2]) != CONST_INT)
8152           abort ();
8153         if (INTVAL (operands[2]) == 0xff)
8154           mode = QImode;
8155         else if (INTVAL (operands[2]) == 0xffff)
8156           mode = HImode;
8157         else
8158           abort ();
8159         
8160         operands[1] = gen_lowpart (mode, operands[1]);
8161         if (mode == QImode)
8162           return "movz{bq|x}\t{%1,%0|%0, %1}";
8163         else
8164           return "movz{wq|x}\t{%1,%0|%0, %1}";
8165       }
8166
8167     default:
8168       if (! rtx_equal_p (operands[0], operands[1]))
8169         abort ();
8170       if (get_attr_mode (insn) == MODE_SI)
8171         return "and{l}\t{%k2, %k0|%k0, %k2}";
8172       else
8173         return "and{q}\t{%2, %0|%0, %2}";
8174     }
8175 }
8176   [(set_attr "type" "alu,alu,alu,imovx")
8177    (set_attr "length_immediate" "*,*,*,0")
8178    (set_attr "mode" "SI,DI,DI,DI")])
8179
8180 (define_insn "*anddi_2"
8181   [(set (reg FLAGS_REG)
8182         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8183                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8184                  (const_int 0)))
8185    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8186         (and:DI (match_dup 1) (match_dup 2)))]
8187   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8188    && ix86_binary_operator_ok (AND, DImode, operands)"
8189   "@
8190    and{l}\t{%k2, %k0|%k0, %k2}
8191    and{q}\t{%2, %0|%0, %2}
8192    and{q}\t{%2, %0|%0, %2}"
8193   [(set_attr "type" "alu")
8194    (set_attr "mode" "SI,DI,DI")])
8195
8196 (define_expand "andsi3"
8197   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8198         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8199                 (match_operand:SI 2 "general_operand" "")))
8200    (clobber (reg:CC FLAGS_REG))]
8201   ""
8202   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8203
8204 (define_insn "*andsi_1"
8205   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8206         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8207                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8208    (clobber (reg:CC FLAGS_REG))]
8209   "ix86_binary_operator_ok (AND, SImode, operands)"
8210 {
8211   switch (get_attr_type (insn))
8212     {
8213     case TYPE_IMOVX:
8214       {
8215         enum machine_mode mode;
8216
8217         if (GET_CODE (operands[2]) != CONST_INT)
8218           abort ();
8219         if (INTVAL (operands[2]) == 0xff)
8220           mode = QImode;
8221         else if (INTVAL (operands[2]) == 0xffff)
8222           mode = HImode;
8223         else
8224           abort ();
8225         
8226         operands[1] = gen_lowpart (mode, operands[1]);
8227         if (mode == QImode)
8228           return "movz{bl|x}\t{%1,%0|%0, %1}";
8229         else
8230           return "movz{wl|x}\t{%1,%0|%0, %1}";
8231       }
8232
8233     default:
8234       if (! rtx_equal_p (operands[0], operands[1]))
8235         abort ();
8236       return "and{l}\t{%2, %0|%0, %2}";
8237     }
8238 }
8239   [(set_attr "type" "alu,alu,imovx")
8240    (set_attr "length_immediate" "*,*,0")
8241    (set_attr "mode" "SI")])
8242
8243 (define_split
8244   [(set (match_operand 0 "register_operand" "")
8245         (and (match_dup 0)
8246              (const_int -65536)))
8247    (clobber (reg:CC FLAGS_REG))]
8248   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8249   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8250   "operands[1] = gen_lowpart (HImode, operands[0]);")
8251
8252 (define_split
8253   [(set (match_operand 0 "ext_register_operand" "")
8254         (and (match_dup 0)
8255              (const_int -256)))
8256    (clobber (reg:CC FLAGS_REG))]
8257   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8258   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8259   "operands[1] = gen_lowpart (QImode, operands[0]);")
8260
8261 (define_split
8262   [(set (match_operand 0 "ext_register_operand" "")
8263         (and (match_dup 0)
8264              (const_int -65281)))
8265    (clobber (reg:CC FLAGS_REG))]
8266   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8267   [(parallel [(set (zero_extract:SI (match_dup 0)
8268                                     (const_int 8)
8269                                     (const_int 8))
8270                    (xor:SI 
8271                      (zero_extract:SI (match_dup 0)
8272                                       (const_int 8)
8273                                       (const_int 8))
8274                      (zero_extract:SI (match_dup 0)
8275                                       (const_int 8)
8276                                       (const_int 8))))
8277               (clobber (reg:CC FLAGS_REG))])]
8278   "operands[0] = gen_lowpart (SImode, operands[0]);")
8279
8280 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8281 (define_insn "*andsi_1_zext"
8282   [(set (match_operand:DI 0 "register_operand" "=r")
8283         (zero_extend:DI
8284           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8285                   (match_operand:SI 2 "general_operand" "rim"))))
8286    (clobber (reg:CC FLAGS_REG))]
8287   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8288   "and{l}\t{%2, %k0|%k0, %2}"
8289   [(set_attr "type" "alu")
8290    (set_attr "mode" "SI")])
8291
8292 (define_insn "*andsi_2"
8293   [(set (reg FLAGS_REG)
8294         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8295                          (match_operand:SI 2 "general_operand" "rim,ri"))
8296                  (const_int 0)))
8297    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8298         (and:SI (match_dup 1) (match_dup 2)))]
8299   "ix86_match_ccmode (insn, CCNOmode)
8300    && ix86_binary_operator_ok (AND, SImode, operands)"
8301   "and{l}\t{%2, %0|%0, %2}"
8302   [(set_attr "type" "alu")
8303    (set_attr "mode" "SI")])
8304
8305 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8306 (define_insn "*andsi_2_zext"
8307   [(set (reg FLAGS_REG)
8308         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8309                          (match_operand:SI 2 "general_operand" "rim"))
8310                  (const_int 0)))
8311    (set (match_operand:DI 0 "register_operand" "=r")
8312         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8313   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8314    && ix86_binary_operator_ok (AND, SImode, operands)"
8315   "and{l}\t{%2, %k0|%k0, %2}"
8316   [(set_attr "type" "alu")
8317    (set_attr "mode" "SI")])
8318
8319 (define_expand "andhi3"
8320   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8321         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8322                 (match_operand:HI 2 "general_operand" "")))
8323    (clobber (reg:CC FLAGS_REG))]
8324   "TARGET_HIMODE_MATH"
8325   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8326
8327 (define_insn "*andhi_1"
8328   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8329         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8330                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8331    (clobber (reg:CC FLAGS_REG))]
8332   "ix86_binary_operator_ok (AND, HImode, operands)"
8333 {
8334   switch (get_attr_type (insn))
8335     {
8336     case TYPE_IMOVX:
8337       if (GET_CODE (operands[2]) != CONST_INT)
8338         abort ();
8339       if (INTVAL (operands[2]) == 0xff)
8340         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8341       abort ();
8342
8343     default:
8344       if (! rtx_equal_p (operands[0], operands[1]))
8345         abort ();
8346
8347       return "and{w}\t{%2, %0|%0, %2}";
8348     }
8349 }
8350   [(set_attr "type" "alu,alu,imovx")
8351    (set_attr "length_immediate" "*,*,0")
8352    (set_attr "mode" "HI,HI,SI")])
8353
8354 (define_insn "*andhi_2"
8355   [(set (reg FLAGS_REG)
8356         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8357                          (match_operand:HI 2 "general_operand" "rim,ri"))
8358                  (const_int 0)))
8359    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8360         (and:HI (match_dup 1) (match_dup 2)))]
8361   "ix86_match_ccmode (insn, CCNOmode)
8362    && ix86_binary_operator_ok (AND, HImode, operands)"
8363   "and{w}\t{%2, %0|%0, %2}"
8364   [(set_attr "type" "alu")
8365    (set_attr "mode" "HI")])
8366
8367 (define_expand "andqi3"
8368   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8369         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8370                 (match_operand:QI 2 "general_operand" "")))
8371    (clobber (reg:CC FLAGS_REG))]
8372   "TARGET_QIMODE_MATH"
8373   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8374
8375 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8376 (define_insn "*andqi_1"
8377   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8378         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8379                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8380    (clobber (reg:CC FLAGS_REG))]
8381   "ix86_binary_operator_ok (AND, QImode, operands)"
8382   "@
8383    and{b}\t{%2, %0|%0, %2}
8384    and{b}\t{%2, %0|%0, %2}
8385    and{l}\t{%k2, %k0|%k0, %k2}"
8386   [(set_attr "type" "alu")
8387    (set_attr "mode" "QI,QI,SI")])
8388
8389 (define_insn "*andqi_1_slp"
8390   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8391         (and:QI (match_dup 0)
8392                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8395    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8396   "and{b}\t{%1, %0|%0, %1}"
8397   [(set_attr "type" "alu1")
8398    (set_attr "mode" "QI")])
8399
8400 (define_insn "*andqi_2_maybe_si"
8401   [(set (reg FLAGS_REG)
8402         (compare (and:QI
8403                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8404                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8405                  (const_int 0)))
8406    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8407         (and:QI (match_dup 1) (match_dup 2)))]
8408   "ix86_binary_operator_ok (AND, QImode, operands)
8409    && ix86_match_ccmode (insn,
8410                          GET_CODE (operands[2]) == CONST_INT
8411                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8412 {
8413   if (which_alternative == 2)
8414     {
8415       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8416         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8417       return "and{l}\t{%2, %k0|%k0, %2}";
8418     }
8419   return "and{b}\t{%2, %0|%0, %2}";
8420 }
8421   [(set_attr "type" "alu")
8422    (set_attr "mode" "QI,QI,SI")])
8423
8424 (define_insn "*andqi_2"
8425   [(set (reg FLAGS_REG)
8426         (compare (and:QI
8427                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8428                    (match_operand:QI 2 "general_operand" "qim,qi"))
8429                  (const_int 0)))
8430    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8431         (and:QI (match_dup 1) (match_dup 2)))]
8432   "ix86_match_ccmode (insn, CCNOmode)
8433    && ix86_binary_operator_ok (AND, QImode, operands)"
8434   "and{b}\t{%2, %0|%0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "mode" "QI")])
8437
8438 (define_insn "*andqi_2_slp"
8439   [(set (reg FLAGS_REG)
8440         (compare (and:QI
8441                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8442                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8443                  (const_int 0)))
8444    (set (strict_low_part (match_dup 0))
8445         (and:QI (match_dup 0) (match_dup 1)))]
8446   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8447    && ix86_match_ccmode (insn, CCNOmode)
8448    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8449   "and{b}\t{%1, %0|%0, %1}"
8450   [(set_attr "type" "alu1")
8451    (set_attr "mode" "QI")])
8452
8453 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8454 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8455 ;; for a QImode operand, which of course failed.
8456
8457 (define_insn "andqi_ext_0"
8458   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459                          (const_int 8)
8460                          (const_int 8))
8461         (and:SI 
8462           (zero_extract:SI
8463             (match_operand 1 "ext_register_operand" "0")
8464             (const_int 8)
8465             (const_int 8))
8466           (match_operand 2 "const_int_operand" "n")))
8467    (clobber (reg:CC FLAGS_REG))]
8468   ""
8469   "and{b}\t{%2, %h0|%h0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "length_immediate" "1")
8472    (set_attr "mode" "QI")])
8473
8474 ;; Generated by peephole translating test to and.  This shows up
8475 ;; often in fp comparisons.
8476
8477 (define_insn "*andqi_ext_0_cc"
8478   [(set (reg FLAGS_REG)
8479         (compare
8480           (and:SI
8481             (zero_extract:SI
8482               (match_operand 1 "ext_register_operand" "0")
8483               (const_int 8)
8484               (const_int 8))
8485             (match_operand 2 "const_int_operand" "n"))
8486           (const_int 0)))
8487    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8488                          (const_int 8)
8489                          (const_int 8))
8490         (and:SI 
8491           (zero_extract:SI
8492             (match_dup 1)
8493             (const_int 8)
8494             (const_int 8))
8495           (match_dup 2)))]
8496   "ix86_match_ccmode (insn, CCNOmode)"
8497   "and{b}\t{%2, %h0|%h0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "length_immediate" "1")
8500    (set_attr "mode" "QI")])
8501
8502 (define_insn "*andqi_ext_1"
8503   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504                          (const_int 8)
8505                          (const_int 8))
8506         (and:SI 
8507           (zero_extract:SI
8508             (match_operand 1 "ext_register_operand" "0")
8509             (const_int 8)
8510             (const_int 8))
8511           (zero_extend:SI
8512             (match_operand:QI 2 "general_operand" "Qm"))))
8513    (clobber (reg:CC FLAGS_REG))]
8514   "!TARGET_64BIT"
8515   "and{b}\t{%2, %h0|%h0, %2}"
8516   [(set_attr "type" "alu")
8517    (set_attr "length_immediate" "0")
8518    (set_attr "mode" "QI")])
8519
8520 (define_insn "*andqi_ext_1_rex64"
8521   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8522                          (const_int 8)
8523                          (const_int 8))
8524         (and:SI 
8525           (zero_extract:SI
8526             (match_operand 1 "ext_register_operand" "0")
8527             (const_int 8)
8528             (const_int 8))
8529           (zero_extend:SI
8530             (match_operand 2 "ext_register_operand" "Q"))))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "TARGET_64BIT"
8533   "and{b}\t{%2, %h0|%h0, %2}"
8534   [(set_attr "type" "alu")
8535    (set_attr "length_immediate" "0")
8536    (set_attr "mode" "QI")])
8537
8538 (define_insn "*andqi_ext_2"
8539   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8540                          (const_int 8)
8541                          (const_int 8))
8542         (and:SI
8543           (zero_extract:SI
8544             (match_operand 1 "ext_register_operand" "%0")
8545             (const_int 8)
8546             (const_int 8))
8547           (zero_extract:SI
8548             (match_operand 2 "ext_register_operand" "Q")
8549             (const_int 8)
8550             (const_int 8))))
8551    (clobber (reg:CC FLAGS_REG))]
8552   ""
8553   "and{b}\t{%h2, %h0|%h0, %h2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "length_immediate" "0")
8556    (set_attr "mode" "QI")])
8557
8558 ;; Convert wide AND instructions with immediate operand to shorter QImode
8559 ;; equivalents when possible.
8560 ;; Don't do the splitting with memory operands, since it introduces risk
8561 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8562 ;; for size, but that can (should?) be handled by generic code instead.
8563 (define_split
8564   [(set (match_operand 0 "register_operand" "")
8565         (and (match_operand 1 "register_operand" "")
8566              (match_operand 2 "const_int_operand" "")))
8567    (clobber (reg:CC FLAGS_REG))]
8568    "reload_completed
8569     && QI_REG_P (operands[0])
8570     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571     && !(~INTVAL (operands[2]) & ~(255 << 8))
8572     && GET_MODE (operands[0]) != QImode"
8573   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8574                    (and:SI (zero_extract:SI (match_dup 1)
8575                                             (const_int 8) (const_int 8))
8576                            (match_dup 2)))
8577               (clobber (reg:CC FLAGS_REG))])]
8578   "operands[0] = gen_lowpart (SImode, operands[0]);
8579    operands[1] = gen_lowpart (SImode, operands[1]);
8580    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8581
8582 ;; Since AND can be encoded with sign extended immediate, this is only
8583 ;; profitable when 7th bit is not set.
8584 (define_split
8585   [(set (match_operand 0 "register_operand" "")
8586         (and (match_operand 1 "general_operand" "")
8587              (match_operand 2 "const_int_operand" "")))
8588    (clobber (reg:CC FLAGS_REG))]
8589    "reload_completed
8590     && ANY_QI_REG_P (operands[0])
8591     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8592     && !(~INTVAL (operands[2]) & ~255)
8593     && !(INTVAL (operands[2]) & 128)
8594     && GET_MODE (operands[0]) != QImode"
8595   [(parallel [(set (strict_low_part (match_dup 0))
8596                    (and:QI (match_dup 1)
8597                            (match_dup 2)))
8598               (clobber (reg:CC FLAGS_REG))])]
8599   "operands[0] = gen_lowpart (QImode, operands[0]);
8600    operands[1] = gen_lowpart (QImode, operands[1]);
8601    operands[2] = gen_lowpart (QImode, operands[2]);")
8602 \f
8603 ;; Logical inclusive OR instructions
8604
8605 ;; %%% This used to optimize known byte-wide and operations to memory.
8606 ;; If this is considered useful, it should be done with splitters.
8607
8608 (define_expand "iordi3"
8609   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8610         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8611                 (match_operand:DI 2 "x86_64_general_operand" "")))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "TARGET_64BIT"
8614   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8615
8616 (define_insn "*iordi_1_rex64"
8617   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8618         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8619                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8620    (clobber (reg:CC FLAGS_REG))]
8621   "TARGET_64BIT
8622    && ix86_binary_operator_ok (IOR, DImode, operands)"
8623   "or{q}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "DI")])
8626
8627 (define_insn "*iordi_2_rex64"
8628   [(set (reg FLAGS_REG)
8629         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8630                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8631                  (const_int 0)))
8632    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8633         (ior:DI (match_dup 1) (match_dup 2)))]
8634   "TARGET_64BIT
8635    && ix86_match_ccmode (insn, CCNOmode)
8636    && ix86_binary_operator_ok (IOR, DImode, operands)"
8637   "or{q}\t{%2, %0|%0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "DI")])
8640
8641 (define_insn "*iordi_3_rex64"
8642   [(set (reg FLAGS_REG)
8643         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8644                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8645                  (const_int 0)))
8646    (clobber (match_scratch:DI 0 "=r"))]
8647   "TARGET_64BIT
8648    && ix86_match_ccmode (insn, CCNOmode)
8649    && ix86_binary_operator_ok (IOR, DImode, operands)"
8650   "or{q}\t{%2, %0|%0, %2}"
8651   [(set_attr "type" "alu")
8652    (set_attr "mode" "DI")])
8653
8654
8655 (define_expand "iorsi3"
8656   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8657         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8658                 (match_operand:SI 2 "general_operand" "")))
8659    (clobber (reg:CC FLAGS_REG))]
8660   ""
8661   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8662
8663 (define_insn "*iorsi_1"
8664   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8665         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8666                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8667    (clobber (reg:CC FLAGS_REG))]
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 (define_insn "*iorsi_1_zext"
8675   [(set (match_operand:DI 0 "register_operand" "=rm")
8676         (zero_extend:DI
8677           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678                   (match_operand:SI 2 "general_operand" "rim"))))
8679    (clobber (reg:CC FLAGS_REG))]
8680   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8681   "or{l}\t{%2, %k0|%k0, %2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "mode" "SI")])
8684
8685 (define_insn "*iorsi_1_zext_imm"
8686   [(set (match_operand:DI 0 "register_operand" "=rm")
8687         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8688                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8689    (clobber (reg:CC FLAGS_REG))]
8690   "TARGET_64BIT"
8691   "or{l}\t{%2, %k0|%k0, %2}"
8692   [(set_attr "type" "alu")
8693    (set_attr "mode" "SI")])
8694
8695 (define_insn "*iorsi_2"
8696   [(set (reg FLAGS_REG)
8697         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8698                          (match_operand:SI 2 "general_operand" "rim,ri"))
8699                  (const_int 0)))
8700    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8701         (ior:SI (match_dup 1) (match_dup 2)))]
8702   "ix86_match_ccmode (insn, CCNOmode)
8703    && ix86_binary_operator_ok (IOR, SImode, operands)"
8704   "or{l}\t{%2, %0|%0, %2}"
8705   [(set_attr "type" "alu")
8706    (set_attr "mode" "SI")])
8707
8708 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8709 ;; ??? Special case for immediate operand is missing - it is tricky.
8710 (define_insn "*iorsi_2_zext"
8711   [(set (reg FLAGS_REG)
8712         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8713                          (match_operand:SI 2 "general_operand" "rim"))
8714                  (const_int 0)))
8715    (set (match_operand:DI 0 "register_operand" "=r")
8716         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8717   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8718    && ix86_binary_operator_ok (IOR, SImode, operands)"
8719   "or{l}\t{%2, %k0|%k0, %2}"
8720   [(set_attr "type" "alu")
8721    (set_attr "mode" "SI")])
8722
8723 (define_insn "*iorsi_2_zext_imm"
8724   [(set (reg FLAGS_REG)
8725         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8726                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8727                  (const_int 0)))
8728    (set (match_operand:DI 0 "register_operand" "=r")
8729         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8730   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8731    && ix86_binary_operator_ok (IOR, SImode, operands)"
8732   "or{l}\t{%2, %k0|%k0, %2}"
8733   [(set_attr "type" "alu")
8734    (set_attr "mode" "SI")])
8735
8736 (define_insn "*iorsi_3"
8737   [(set (reg FLAGS_REG)
8738         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8739                          (match_operand:SI 2 "general_operand" "rim"))
8740                  (const_int 0)))
8741    (clobber (match_scratch:SI 0 "=r"))]
8742   "ix86_match_ccmode (insn, CCNOmode)
8743    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8744   "or{l}\t{%2, %0|%0, %2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "mode" "SI")])
8747
8748 (define_expand "iorhi3"
8749   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8750         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8751                 (match_operand:HI 2 "general_operand" "")))
8752    (clobber (reg:CC FLAGS_REG))]
8753   "TARGET_HIMODE_MATH"
8754   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8755
8756 (define_insn "*iorhi_1"
8757   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8758         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8759                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "ix86_binary_operator_ok (IOR, HImode, operands)"
8762   "or{w}\t{%2, %0|%0, %2}"
8763   [(set_attr "type" "alu")
8764    (set_attr "mode" "HI")])
8765
8766 (define_insn "*iorhi_2"
8767   [(set (reg FLAGS_REG)
8768         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8769                          (match_operand:HI 2 "general_operand" "rim,ri"))
8770                  (const_int 0)))
8771    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8772         (ior:HI (match_dup 1) (match_dup 2)))]
8773   "ix86_match_ccmode (insn, CCNOmode)
8774    && ix86_binary_operator_ok (IOR, HImode, operands)"
8775   "or{w}\t{%2, %0|%0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "mode" "HI")])
8778
8779 (define_insn "*iorhi_3"
8780   [(set (reg FLAGS_REG)
8781         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8782                          (match_operand:HI 2 "general_operand" "rim"))
8783                  (const_int 0)))
8784    (clobber (match_scratch:HI 0 "=r"))]
8785   "ix86_match_ccmode (insn, CCNOmode)
8786    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8787   "or{w}\t{%2, %0|%0, %2}"
8788   [(set_attr "type" "alu")
8789    (set_attr "mode" "HI")])
8790
8791 (define_expand "iorqi3"
8792   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8793         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8794                 (match_operand:QI 2 "general_operand" "")))
8795    (clobber (reg:CC FLAGS_REG))]
8796   "TARGET_QIMODE_MATH"
8797   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8798
8799 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8800 (define_insn "*iorqi_1"
8801   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8802         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8803                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8804    (clobber (reg:CC FLAGS_REG))]
8805   "ix86_binary_operator_ok (IOR, QImode, operands)"
8806   "@
8807    or{b}\t{%2, %0|%0, %2}
8808    or{b}\t{%2, %0|%0, %2}
8809    or{l}\t{%k2, %k0|%k0, %k2}"
8810   [(set_attr "type" "alu")
8811    (set_attr "mode" "QI,QI,SI")])
8812
8813 (define_insn "*iorqi_1_slp"
8814   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8815         (ior:QI (match_dup 0)
8816                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8817    (clobber (reg:CC FLAGS_REG))]
8818   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8820   "or{b}\t{%1, %0|%0, %1}"
8821   [(set_attr "type" "alu1")
8822    (set_attr "mode" "QI")])
8823
8824 (define_insn "*iorqi_2"
8825   [(set (reg FLAGS_REG)
8826         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8827                          (match_operand:QI 2 "general_operand" "qim,qi"))
8828                  (const_int 0)))
8829    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8830         (ior:QI (match_dup 1) (match_dup 2)))]
8831   "ix86_match_ccmode (insn, CCNOmode)
8832    && ix86_binary_operator_ok (IOR, QImode, operands)"
8833   "or{b}\t{%2, %0|%0, %2}"
8834   [(set_attr "type" "alu")
8835    (set_attr "mode" "QI")])
8836
8837 (define_insn "*iorqi_2_slp"
8838   [(set (reg FLAGS_REG)
8839         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8840                          (match_operand:QI 1 "general_operand" "qim,qi"))
8841                  (const_int 0)))
8842    (set (strict_low_part (match_dup 0))
8843         (ior:QI (match_dup 0) (match_dup 1)))]
8844   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8845    && ix86_match_ccmode (insn, CCNOmode)
8846    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8847   "or{b}\t{%1, %0|%0, %1}"
8848   [(set_attr "type" "alu1")
8849    (set_attr "mode" "QI")])
8850
8851 (define_insn "*iorqi_3"
8852   [(set (reg FLAGS_REG)
8853         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8854                          (match_operand:QI 2 "general_operand" "qim"))
8855                  (const_int 0)))
8856    (clobber (match_scratch:QI 0 "=q"))]
8857   "ix86_match_ccmode (insn, CCNOmode)
8858    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8859   "or{b}\t{%2, %0|%0, %2}"
8860   [(set_attr "type" "alu")
8861    (set_attr "mode" "QI")])
8862
8863 (define_insn "iorqi_ext_0"
8864   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8865                          (const_int 8)
8866                          (const_int 8))
8867         (ior:SI 
8868           (zero_extract:SI
8869             (match_operand 1 "ext_register_operand" "0")
8870             (const_int 8)
8871             (const_int 8))
8872           (match_operand 2 "const_int_operand" "n")))
8873    (clobber (reg:CC FLAGS_REG))]
8874   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8875   "or{b}\t{%2, %h0|%h0, %2}"
8876   [(set_attr "type" "alu")
8877    (set_attr "length_immediate" "1")
8878    (set_attr "mode" "QI")])
8879
8880 (define_insn "*iorqi_ext_1"
8881   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8882                          (const_int 8)
8883                          (const_int 8))
8884         (ior:SI 
8885           (zero_extract:SI
8886             (match_operand 1 "ext_register_operand" "0")
8887             (const_int 8)
8888             (const_int 8))
8889           (zero_extend:SI
8890             (match_operand:QI 2 "general_operand" "Qm"))))
8891    (clobber (reg:CC FLAGS_REG))]
8892   "!TARGET_64BIT
8893    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8894   "or{b}\t{%2, %h0|%h0, %2}"
8895   [(set_attr "type" "alu")
8896    (set_attr "length_immediate" "0")
8897    (set_attr "mode" "QI")])
8898
8899 (define_insn "*iorqi_ext_1_rex64"
8900   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8901                          (const_int 8)
8902                          (const_int 8))
8903         (ior:SI 
8904           (zero_extract:SI
8905             (match_operand 1 "ext_register_operand" "0")
8906             (const_int 8)
8907             (const_int 8))
8908           (zero_extend:SI
8909             (match_operand 2 "ext_register_operand" "Q"))))
8910    (clobber (reg:CC FLAGS_REG))]
8911   "TARGET_64BIT
8912    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8913   "or{b}\t{%2, %h0|%h0, %2}"
8914   [(set_attr "type" "alu")
8915    (set_attr "length_immediate" "0")
8916    (set_attr "mode" "QI")])
8917
8918 (define_insn "*iorqi_ext_2"
8919   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8920                          (const_int 8)
8921                          (const_int 8))
8922         (ior:SI 
8923           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8924                            (const_int 8)
8925                            (const_int 8))
8926           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8927                            (const_int 8)
8928                            (const_int 8))))
8929    (clobber (reg:CC FLAGS_REG))]
8930   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8931   "ior{b}\t{%h2, %h0|%h0, %h2}"
8932   [(set_attr "type" "alu")
8933    (set_attr "length_immediate" "0")
8934    (set_attr "mode" "QI")])
8935
8936 (define_split
8937   [(set (match_operand 0 "register_operand" "")
8938         (ior (match_operand 1 "register_operand" "")
8939              (match_operand 2 "const_int_operand" "")))
8940    (clobber (reg:CC FLAGS_REG))]
8941    "reload_completed
8942     && QI_REG_P (operands[0])
8943     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944     && !(INTVAL (operands[2]) & ~(255 << 8))
8945     && GET_MODE (operands[0]) != QImode"
8946   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8947                    (ior:SI (zero_extract:SI (match_dup 1)
8948                                             (const_int 8) (const_int 8))
8949                            (match_dup 2)))
8950               (clobber (reg:CC FLAGS_REG))])]
8951   "operands[0] = gen_lowpart (SImode, operands[0]);
8952    operands[1] = gen_lowpart (SImode, operands[1]);
8953    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8954
8955 ;; Since OR can be encoded with sign extended immediate, this is only
8956 ;; profitable when 7th bit is set.
8957 (define_split
8958   [(set (match_operand 0 "register_operand" "")
8959         (ior (match_operand 1 "general_operand" "")
8960              (match_operand 2 "const_int_operand" "")))
8961    (clobber (reg:CC FLAGS_REG))]
8962    "reload_completed
8963     && ANY_QI_REG_P (operands[0])
8964     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8965     && !(INTVAL (operands[2]) & ~255)
8966     && (INTVAL (operands[2]) & 128)
8967     && GET_MODE (operands[0]) != QImode"
8968   [(parallel [(set (strict_low_part (match_dup 0))
8969                    (ior:QI (match_dup 1)
8970                            (match_dup 2)))
8971               (clobber (reg:CC FLAGS_REG))])]
8972   "operands[0] = gen_lowpart (QImode, operands[0]);
8973    operands[1] = gen_lowpart (QImode, operands[1]);
8974    operands[2] = gen_lowpart (QImode, operands[2]);")
8975 \f
8976 ;; Logical XOR instructions
8977
8978 ;; %%% This used to optimize known byte-wide and operations to memory.
8979 ;; If this is considered useful, it should be done with splitters.
8980
8981 (define_expand "xordi3"
8982   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8983         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8984                 (match_operand:DI 2 "x86_64_general_operand" "")))
8985    (clobber (reg:CC FLAGS_REG))]
8986   "TARGET_64BIT"
8987   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8988
8989 (define_insn "*xordi_1_rex64"
8990   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8991         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8992                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8993    (clobber (reg:CC FLAGS_REG))]
8994   "TARGET_64BIT
8995    && ix86_binary_operator_ok (XOR, DImode, operands)"
8996   "@
8997    xor{q}\t{%2, %0|%0, %2}
8998    xor{q}\t{%2, %0|%0, %2}"
8999   [(set_attr "type" "alu")
9000    (set_attr "mode" "DI,DI")])
9001
9002 (define_insn "*xordi_2_rex64"
9003   [(set (reg FLAGS_REG)
9004         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9005                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9006                  (const_int 0)))
9007    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9008         (xor:DI (match_dup 1) (match_dup 2)))]
9009   "TARGET_64BIT
9010    && ix86_match_ccmode (insn, CCNOmode)
9011    && ix86_binary_operator_ok (XOR, DImode, operands)"
9012   "@
9013    xor{q}\t{%2, %0|%0, %2}
9014    xor{q}\t{%2, %0|%0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "DI,DI")])
9017
9018 (define_insn "*xordi_3_rex64"
9019   [(set (reg FLAGS_REG)
9020         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9021                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9022                  (const_int 0)))
9023    (clobber (match_scratch:DI 0 "=r"))]
9024   "TARGET_64BIT
9025    && ix86_match_ccmode (insn, CCNOmode)
9026    && ix86_binary_operator_ok (XOR, DImode, operands)"
9027   "xor{q}\t{%2, %0|%0, %2}"
9028   [(set_attr "type" "alu")
9029    (set_attr "mode" "DI")])
9030
9031 (define_expand "xorsi3"
9032   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9033         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9034                 (match_operand:SI 2 "general_operand" "")))
9035    (clobber (reg:CC FLAGS_REG))]
9036   ""
9037   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9038
9039 (define_insn "*xorsi_1"
9040   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9041         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042                 (match_operand:SI 2 "general_operand" "ri,rm")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "ix86_binary_operator_ok (XOR, SImode, operands)"
9045   "xor{l}\t{%2, %0|%0, %2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "mode" "SI")])
9048
9049 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9050 ;; Add speccase for immediates
9051 (define_insn "*xorsi_1_zext"
9052   [(set (match_operand:DI 0 "register_operand" "=r")
9053         (zero_extend:DI
9054           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055                   (match_operand:SI 2 "general_operand" "rim"))))
9056    (clobber (reg:CC FLAGS_REG))]
9057   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9058   "xor{l}\t{%2, %k0|%k0, %2}"
9059   [(set_attr "type" "alu")
9060    (set_attr "mode" "SI")])
9061
9062 (define_insn "*xorsi_1_zext_imm"
9063   [(set (match_operand:DI 0 "register_operand" "=r")
9064         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9065                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9066    (clobber (reg:CC FLAGS_REG))]
9067   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9068   "xor{l}\t{%2, %k0|%k0, %2}"
9069   [(set_attr "type" "alu")
9070    (set_attr "mode" "SI")])
9071
9072 (define_insn "*xorsi_2"
9073   [(set (reg FLAGS_REG)
9074         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9075                          (match_operand:SI 2 "general_operand" "rim,ri"))
9076                  (const_int 0)))
9077    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9078         (xor:SI (match_dup 1) (match_dup 2)))]
9079   "ix86_match_ccmode (insn, CCNOmode)
9080    && ix86_binary_operator_ok (XOR, SImode, operands)"
9081   "xor{l}\t{%2, %0|%0, %2}"
9082   [(set_attr "type" "alu")
9083    (set_attr "mode" "SI")])
9084
9085 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9086 ;; ??? Special case for immediate operand is missing - it is tricky.
9087 (define_insn "*xorsi_2_zext"
9088   [(set (reg FLAGS_REG)
9089         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9090                          (match_operand:SI 2 "general_operand" "rim"))
9091                  (const_int 0)))
9092    (set (match_operand:DI 0 "register_operand" "=r")
9093         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9094   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9095    && ix86_binary_operator_ok (XOR, SImode, operands)"
9096   "xor{l}\t{%2, %k0|%k0, %2}"
9097   [(set_attr "type" "alu")
9098    (set_attr "mode" "SI")])
9099
9100 (define_insn "*xorsi_2_zext_imm"
9101   [(set (reg FLAGS_REG)
9102         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9103                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9104                  (const_int 0)))
9105    (set (match_operand:DI 0 "register_operand" "=r")
9106         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9107   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9108    && ix86_binary_operator_ok (XOR, SImode, operands)"
9109   "xor{l}\t{%2, %k0|%k0, %2}"
9110   [(set_attr "type" "alu")
9111    (set_attr "mode" "SI")])
9112
9113 (define_insn "*xorsi_3"
9114   [(set (reg FLAGS_REG)
9115         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9116                          (match_operand:SI 2 "general_operand" "rim"))
9117                  (const_int 0)))
9118    (clobber (match_scratch:SI 0 "=r"))]
9119   "ix86_match_ccmode (insn, CCNOmode)
9120    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9121   "xor{l}\t{%2, %0|%0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "mode" "SI")])
9124
9125 (define_expand "xorhi3"
9126   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9127         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9128                 (match_operand:HI 2 "general_operand" "")))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "TARGET_HIMODE_MATH"
9131   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9132
9133 (define_insn "*xorhi_1"
9134   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9135         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9136                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "ix86_binary_operator_ok (XOR, HImode, operands)"
9139   "xor{w}\t{%2, %0|%0, %2}"
9140   [(set_attr "type" "alu")
9141    (set_attr "mode" "HI")])
9142
9143 (define_insn "*xorhi_2"
9144   [(set (reg FLAGS_REG)
9145         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9146                          (match_operand:HI 2 "general_operand" "rim,ri"))
9147                  (const_int 0)))
9148    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9149         (xor:HI (match_dup 1) (match_dup 2)))]
9150   "ix86_match_ccmode (insn, CCNOmode)
9151    && ix86_binary_operator_ok (XOR, HImode, operands)"
9152   "xor{w}\t{%2, %0|%0, %2}"
9153   [(set_attr "type" "alu")
9154    (set_attr "mode" "HI")])
9155
9156 (define_insn "*xorhi_3"
9157   [(set (reg FLAGS_REG)
9158         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9159                          (match_operand:HI 2 "general_operand" "rim"))
9160                  (const_int 0)))
9161    (clobber (match_scratch:HI 0 "=r"))]
9162   "ix86_match_ccmode (insn, CCNOmode)
9163    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9164   "xor{w}\t{%2, %0|%0, %2}"
9165   [(set_attr "type" "alu")
9166    (set_attr "mode" "HI")])
9167
9168 (define_expand "xorqi3"
9169   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9170         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9171                 (match_operand:QI 2 "general_operand" "")))
9172    (clobber (reg:CC FLAGS_REG))]
9173   "TARGET_QIMODE_MATH"
9174   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9175
9176 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9177 (define_insn "*xorqi_1"
9178   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9179         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9180                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9181    (clobber (reg:CC FLAGS_REG))]
9182   "ix86_binary_operator_ok (XOR, QImode, operands)"
9183   "@
9184    xor{b}\t{%2, %0|%0, %2}
9185    xor{b}\t{%2, %0|%0, %2}
9186    xor{l}\t{%k2, %k0|%k0, %k2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "mode" "QI,QI,SI")])
9189
9190 (define_insn "*xorqi_1_slp"
9191   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9192         (xor:QI (match_dup 0)
9193                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9194    (clobber (reg:CC FLAGS_REG))]
9195   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9196    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9197   "xor{b}\t{%1, %0|%0, %1}"
9198   [(set_attr "type" "alu1")
9199    (set_attr "mode" "QI")])
9200
9201 (define_insn "xorqi_ext_0"
9202   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203                          (const_int 8)
9204                          (const_int 8))
9205         (xor:SI 
9206           (zero_extract:SI
9207             (match_operand 1 "ext_register_operand" "0")
9208             (const_int 8)
9209             (const_int 8))
9210           (match_operand 2 "const_int_operand" "n")))
9211    (clobber (reg:CC FLAGS_REG))]
9212   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9213   "xor{b}\t{%2, %h0|%h0, %2}"
9214   [(set_attr "type" "alu")
9215    (set_attr "length_immediate" "1")
9216    (set_attr "mode" "QI")])
9217
9218 (define_insn "*xorqi_ext_1"
9219   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9220                          (const_int 8)
9221                          (const_int 8))
9222         (xor:SI 
9223           (zero_extract:SI
9224             (match_operand 1 "ext_register_operand" "0")
9225             (const_int 8)
9226             (const_int 8))
9227           (zero_extend:SI
9228             (match_operand:QI 2 "general_operand" "Qm"))))
9229    (clobber (reg:CC FLAGS_REG))]
9230   "!TARGET_64BIT
9231    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9232   "xor{b}\t{%2, %h0|%h0, %2}"
9233   [(set_attr "type" "alu")
9234    (set_attr "length_immediate" "0")
9235    (set_attr "mode" "QI")])
9236
9237 (define_insn "*xorqi_ext_1_rex64"
9238   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9239                          (const_int 8)
9240                          (const_int 8))
9241         (xor:SI 
9242           (zero_extract:SI
9243             (match_operand 1 "ext_register_operand" "0")
9244             (const_int 8)
9245             (const_int 8))
9246           (zero_extend:SI
9247             (match_operand 2 "ext_register_operand" "Q"))))
9248    (clobber (reg:CC FLAGS_REG))]
9249   "TARGET_64BIT
9250    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9251   "xor{b}\t{%2, %h0|%h0, %2}"
9252   [(set_attr "type" "alu")
9253    (set_attr "length_immediate" "0")
9254    (set_attr "mode" "QI")])
9255
9256 (define_insn "*xorqi_ext_2"
9257   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9258                          (const_int 8)
9259                          (const_int 8))
9260         (xor:SI 
9261           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9262                            (const_int 8)
9263                            (const_int 8))
9264           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9265                            (const_int 8)
9266                            (const_int 8))))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9269   "xor{b}\t{%h2, %h0|%h0, %h2}"
9270   [(set_attr "type" "alu")
9271    (set_attr "length_immediate" "0")
9272    (set_attr "mode" "QI")])
9273
9274 (define_insn "*xorqi_cc_1"
9275   [(set (reg FLAGS_REG)
9276         (compare
9277           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9278                   (match_operand:QI 2 "general_operand" "qim,qi"))
9279           (const_int 0)))
9280    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9281         (xor:QI (match_dup 1) (match_dup 2)))]
9282   "ix86_match_ccmode (insn, CCNOmode)
9283    && ix86_binary_operator_ok (XOR, QImode, operands)"
9284   "xor{b}\t{%2, %0|%0, %2}"
9285   [(set_attr "type" "alu")
9286    (set_attr "mode" "QI")])
9287
9288 (define_insn "*xorqi_2_slp"
9289   [(set (reg FLAGS_REG)
9290         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9291                          (match_operand:QI 1 "general_operand" "qim,qi"))
9292                  (const_int 0)))
9293    (set (strict_low_part (match_dup 0))
9294         (xor:QI (match_dup 0) (match_dup 1)))]
9295   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9296    && ix86_match_ccmode (insn, CCNOmode)
9297    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9298   "xor{b}\t{%1, %0|%0, %1}"
9299   [(set_attr "type" "alu1")
9300    (set_attr "mode" "QI")])
9301
9302 (define_insn "*xorqi_cc_2"
9303   [(set (reg FLAGS_REG)
9304         (compare
9305           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9306                   (match_operand:QI 2 "general_operand" "qim"))
9307           (const_int 0)))
9308    (clobber (match_scratch:QI 0 "=q"))]
9309   "ix86_match_ccmode (insn, CCNOmode)
9310    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9311   "xor{b}\t{%2, %0|%0, %2}"
9312   [(set_attr "type" "alu")
9313    (set_attr "mode" "QI")])
9314
9315 (define_insn "*xorqi_cc_ext_1"
9316   [(set (reg FLAGS_REG)
9317         (compare
9318           (xor:SI
9319             (zero_extract:SI
9320               (match_operand 1 "ext_register_operand" "0")
9321               (const_int 8)
9322               (const_int 8))
9323             (match_operand:QI 2 "general_operand" "qmn"))
9324           (const_int 0)))
9325    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9326                          (const_int 8)
9327                          (const_int 8))
9328         (xor:SI 
9329           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330           (match_dup 2)))]
9331   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332   "xor{b}\t{%2, %h0|%h0, %2}"
9333   [(set_attr "type" "alu")
9334    (set_attr "mode" "QI")])
9335
9336 (define_insn "*xorqi_cc_ext_1_rex64"
9337   [(set (reg FLAGS_REG)
9338         (compare
9339           (xor:SI
9340             (zero_extract:SI
9341               (match_operand 1 "ext_register_operand" "0")
9342               (const_int 8)
9343               (const_int 8))
9344             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9345           (const_int 0)))
9346    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9347                          (const_int 8)
9348                          (const_int 8))
9349         (xor:SI 
9350           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9351           (match_dup 2)))]
9352   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9353   "xor{b}\t{%2, %h0|%h0, %2}"
9354   [(set_attr "type" "alu")
9355    (set_attr "mode" "QI")])
9356
9357 (define_expand "xorqi_cc_ext_1"
9358   [(parallel [
9359      (set (reg:CCNO FLAGS_REG)
9360           (compare:CCNO
9361             (xor:SI
9362               (zero_extract:SI
9363                 (match_operand 1 "ext_register_operand" "")
9364                 (const_int 8)
9365                 (const_int 8))
9366               (match_operand:QI 2 "general_operand" ""))
9367             (const_int 0)))
9368      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9369                            (const_int 8)
9370                            (const_int 8))
9371           (xor:SI 
9372             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9373             (match_dup 2)))])]
9374   ""
9375   "")
9376
9377 (define_split
9378   [(set (match_operand 0 "register_operand" "")
9379         (xor (match_operand 1 "register_operand" "")
9380              (match_operand 2 "const_int_operand" "")))
9381    (clobber (reg:CC FLAGS_REG))]
9382    "reload_completed
9383     && QI_REG_P (operands[0])
9384     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385     && !(INTVAL (operands[2]) & ~(255 << 8))
9386     && GET_MODE (operands[0]) != QImode"
9387   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9388                    (xor:SI (zero_extract:SI (match_dup 1)
9389                                             (const_int 8) (const_int 8))
9390                            (match_dup 2)))
9391               (clobber (reg:CC FLAGS_REG))])]
9392   "operands[0] = gen_lowpart (SImode, operands[0]);
9393    operands[1] = gen_lowpart (SImode, operands[1]);
9394    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9395
9396 ;; Since XOR can be encoded with sign extended immediate, this is only
9397 ;; profitable when 7th bit is set.
9398 (define_split
9399   [(set (match_operand 0 "register_operand" "")
9400         (xor (match_operand 1 "general_operand" "")
9401              (match_operand 2 "const_int_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403    "reload_completed
9404     && ANY_QI_REG_P (operands[0])
9405     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9406     && !(INTVAL (operands[2]) & ~255)
9407     && (INTVAL (operands[2]) & 128)
9408     && GET_MODE (operands[0]) != QImode"
9409   [(parallel [(set (strict_low_part (match_dup 0))
9410                    (xor:QI (match_dup 1)
9411                            (match_dup 2)))
9412               (clobber (reg:CC FLAGS_REG))])]
9413   "operands[0] = gen_lowpart (QImode, operands[0]);
9414    operands[1] = gen_lowpart (QImode, operands[1]);
9415    operands[2] = gen_lowpart (QImode, operands[2]);")
9416 \f
9417 ;; Negation instructions
9418
9419 (define_expand "negdi2"
9420   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9421                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9422               (clobber (reg:CC FLAGS_REG))])]
9423   ""
9424   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9425
9426 (define_insn "*negdi2_1"
9427   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9428         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9429    (clobber (reg:CC FLAGS_REG))]
9430   "!TARGET_64BIT
9431    && ix86_unary_operator_ok (NEG, DImode, operands)"
9432   "#")
9433
9434 (define_split
9435   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9436         (neg:DI (match_operand:DI 1 "general_operand" "")))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "!TARGET_64BIT && reload_completed"
9439   [(parallel
9440     [(set (reg:CCZ FLAGS_REG)
9441           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9442      (set (match_dup 0) (neg:SI (match_dup 2)))])
9443    (parallel
9444     [(set (match_dup 1)
9445           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9446                             (match_dup 3))
9447                    (const_int 0)))
9448      (clobber (reg:CC FLAGS_REG))])
9449    (parallel
9450     [(set (match_dup 1)
9451           (neg:SI (match_dup 1)))
9452      (clobber (reg:CC FLAGS_REG))])]
9453   "split_di (operands+1, 1, operands+2, operands+3);
9454    split_di (operands+0, 1, operands+0, operands+1);")
9455
9456 (define_insn "*negdi2_1_rex64"
9457   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9458         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9459    (clobber (reg:CC FLAGS_REG))]
9460   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9461   "neg{q}\t%0"
9462   [(set_attr "type" "negnot")
9463    (set_attr "mode" "DI")])
9464
9465 ;; The problem with neg is that it does not perform (compare x 0),
9466 ;; it really performs (compare 0 x), which leaves us with the zero
9467 ;; flag being the only useful item.
9468
9469 (define_insn "*negdi2_cmpz_rex64"
9470   [(set (reg:CCZ FLAGS_REG)
9471         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9472                      (const_int 0)))
9473    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9474         (neg:DI (match_dup 1)))]
9475   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9476   "neg{q}\t%0"
9477   [(set_attr "type" "negnot")
9478    (set_attr "mode" "DI")])
9479
9480
9481 (define_expand "negsi2"
9482   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9483                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9484               (clobber (reg:CC FLAGS_REG))])]
9485   ""
9486   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9487
9488 (define_insn "*negsi2_1"
9489   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9490         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9491    (clobber (reg:CC FLAGS_REG))]
9492   "ix86_unary_operator_ok (NEG, SImode, operands)"
9493   "neg{l}\t%0"
9494   [(set_attr "type" "negnot")
9495    (set_attr "mode" "SI")])
9496
9497 ;; Combine is quite creative about this pattern.
9498 (define_insn "*negsi2_1_zext"
9499   [(set (match_operand:DI 0 "register_operand" "=r")
9500         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9501                                         (const_int 32)))
9502                      (const_int 32)))
9503    (clobber (reg:CC FLAGS_REG))]
9504   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9505   "neg{l}\t%k0"
9506   [(set_attr "type" "negnot")
9507    (set_attr "mode" "SI")])
9508
9509 ;; The problem with neg is that it does not perform (compare x 0),
9510 ;; it really performs (compare 0 x), which leaves us with the zero
9511 ;; flag being the only useful item.
9512
9513 (define_insn "*negsi2_cmpz"
9514   [(set (reg:CCZ FLAGS_REG)
9515         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9516                      (const_int 0)))
9517    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9518         (neg:SI (match_dup 1)))]
9519   "ix86_unary_operator_ok (NEG, SImode, operands)"
9520   "neg{l}\t%0"
9521   [(set_attr "type" "negnot")
9522    (set_attr "mode" "SI")])
9523
9524 (define_insn "*negsi2_cmpz_zext"
9525   [(set (reg:CCZ FLAGS_REG)
9526         (compare:CCZ (lshiftrt:DI
9527                        (neg:DI (ashift:DI
9528                                  (match_operand:DI 1 "register_operand" "0")
9529                                  (const_int 32)))
9530                        (const_int 32))
9531                      (const_int 0)))
9532    (set (match_operand:DI 0 "register_operand" "=r")
9533         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9534                                         (const_int 32)))
9535                      (const_int 32)))]
9536   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9537   "neg{l}\t%k0"
9538   [(set_attr "type" "negnot")
9539    (set_attr "mode" "SI")])
9540
9541 (define_expand "neghi2"
9542   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9543                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9544               (clobber (reg:CC FLAGS_REG))])]
9545   "TARGET_HIMODE_MATH"
9546   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9547
9548 (define_insn "*neghi2_1"
9549   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9550         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9551    (clobber (reg:CC FLAGS_REG))]
9552   "ix86_unary_operator_ok (NEG, HImode, operands)"
9553   "neg{w}\t%0"
9554   [(set_attr "type" "negnot")
9555    (set_attr "mode" "HI")])
9556
9557 (define_insn "*neghi2_cmpz"
9558   [(set (reg:CCZ FLAGS_REG)
9559         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9560                      (const_int 0)))
9561    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9562         (neg:HI (match_dup 1)))]
9563   "ix86_unary_operator_ok (NEG, HImode, operands)"
9564   "neg{w}\t%0"
9565   [(set_attr "type" "negnot")
9566    (set_attr "mode" "HI")])
9567
9568 (define_expand "negqi2"
9569   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9570                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9571               (clobber (reg:CC FLAGS_REG))])]
9572   "TARGET_QIMODE_MATH"
9573   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9574
9575 (define_insn "*negqi2_1"
9576   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9577         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "ix86_unary_operator_ok (NEG, QImode, operands)"
9580   "neg{b}\t%0"
9581   [(set_attr "type" "negnot")
9582    (set_attr "mode" "QI")])
9583
9584 (define_insn "*negqi2_cmpz"
9585   [(set (reg:CCZ FLAGS_REG)
9586         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9587                      (const_int 0)))
9588    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9589         (neg:QI (match_dup 1)))]
9590   "ix86_unary_operator_ok (NEG, QImode, operands)"
9591   "neg{b}\t%0"
9592   [(set_attr "type" "negnot")
9593    (set_attr "mode" "QI")])
9594
9595 ;; Changing of sign for FP values is doable using integer unit too.
9596
9597 (define_expand "negsf2"
9598   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9599         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9600   "TARGET_80387 || TARGET_SSE_MATH"
9601   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9602
9603 (define_expand "abssf2"
9604   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9605         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9606   "TARGET_80387 || TARGET_SSE_MATH"
9607   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9608
9609 (define_insn "*absnegsf2_mixed"
9610   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9611         (match_operator:SF 3 "absneg_operator"
9612           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9613    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9614    (clobber (reg:CC FLAGS_REG))]
9615   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9616    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9617   "#")
9618
9619 (define_insn "*absnegsf2_sse"
9620   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9621         (match_operator:SF 3 "absneg_operator"
9622           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9623    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9624    (clobber (reg:CC FLAGS_REG))]
9625   "TARGET_SSE_MATH
9626    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9627   "#")
9628
9629 (define_insn "*absnegsf2_i387"
9630   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9631         (match_operator:SF 3 "absneg_operator"
9632           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9633    (use (match_operand 2 "" ""))
9634    (clobber (reg:CC FLAGS_REG))]
9635   "TARGET_80387 && !TARGET_SSE_MATH
9636    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9637   "#")
9638
9639 (define_expand "negdf2"
9640   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9641         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9642   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9643   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9644
9645 (define_expand "absdf2"
9646   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9647         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9648   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9649   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9650
9651 (define_insn "*absnegdf2_mixed"
9652   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9653         (match_operator:DF 3 "absneg_operator"
9654           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9655    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9656    (clobber (reg:CC FLAGS_REG))]
9657   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9658    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9659   "#")
9660
9661 (define_insn "*absnegdf2_sse"
9662   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9663         (match_operator:DF 3 "absneg_operator"
9664           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9665    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9666    (clobber (reg:CC FLAGS_REG))]
9667   "TARGET_SSE2 && TARGET_SSE_MATH
9668    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9669   "#")
9670
9671 (define_insn "*absnegdf2_i387"
9672   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9673         (match_operator:DF 3 "absneg_operator"
9674           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9675    (use (match_operand 2 "" ""))
9676    (clobber (reg:CC FLAGS_REG))]
9677   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9678    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9679   "#")
9680
9681 (define_expand "negxf2"
9682   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9683         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9684   "TARGET_80387"
9685   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9686
9687 (define_expand "absxf2"
9688   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9689         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9690   "TARGET_80387"
9691   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9692
9693 (define_insn "*absnegxf2_i387"
9694   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9695         (match_operator:XF 3 "absneg_operator"
9696           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9697    (use (match_operand 2 "" ""))
9698    (clobber (reg:CC FLAGS_REG))]
9699   "TARGET_80387
9700    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9701   "#")
9702
9703 ;; Splitters for fp abs and neg.
9704
9705 (define_split
9706   [(set (match_operand 0 "fp_register_operand" "")
9707         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9708    (use (match_operand 2 "" ""))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "reload_completed"
9711   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9712
9713 (define_split
9714   [(set (match_operand 0 "register_operand" "")
9715         (match_operator 3 "absneg_operator"
9716           [(match_operand 1 "register_operand" "")]))
9717    (use (match_operand 2 "nonimmediate_operand" ""))
9718    (clobber (reg:CC FLAGS_REG))]
9719   "reload_completed && SSE_REG_P (operands[0])"
9720   [(set (match_dup 0) (match_dup 3))]
9721 {
9722   enum machine_mode mode = GET_MODE (operands[0]);
9723   enum machine_mode vmode = GET_MODE (operands[2]);
9724   rtx tmp;
9725   
9726   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9727   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9728   if (operands_match_p (operands[0], operands[2]))
9729     {
9730       tmp = operands[1];
9731       operands[1] = operands[2];
9732       operands[2] = tmp;
9733     }
9734   if (GET_CODE (operands[3]) == ABS)
9735     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9736   else
9737     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9738   operands[3] = tmp;
9739 })
9740
9741 (define_split
9742   [(set (match_operand:SF 0 "register_operand" "")
9743         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9744    (use (match_operand:V4SF 2 "" ""))
9745    (clobber (reg:CC FLAGS_REG))]
9746   "reload_completed"
9747   [(parallel [(set (match_dup 0) (match_dup 1))
9748               (clobber (reg:CC FLAGS_REG))])]
9749
9750   rtx tmp;
9751   operands[0] = gen_lowpart (SImode, operands[0]);
9752   if (GET_CODE (operands[1]) == ABS)
9753     {
9754       tmp = gen_int_mode (0x7fffffff, SImode);
9755       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9756     }
9757   else
9758     {
9759       tmp = gen_int_mode (0x80000000, SImode);
9760       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9761     }
9762   operands[1] = tmp;
9763 })
9764
9765 (define_split
9766   [(set (match_operand:DF 0 "register_operand" "")
9767         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9768    (use (match_operand 2 "" ""))
9769    (clobber (reg:CC FLAGS_REG))]
9770   "reload_completed"
9771   [(parallel [(set (match_dup 0) (match_dup 1))
9772               (clobber (reg:CC FLAGS_REG))])]
9773 {
9774   rtx tmp;
9775   if (TARGET_64BIT)
9776     {
9777       tmp = gen_lowpart (DImode, operands[0]);
9778       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9779       operands[0] = tmp;
9780
9781       if (GET_CODE (operands[1]) == ABS)
9782         tmp = const0_rtx;
9783       else
9784         tmp = gen_rtx_NOT (DImode, tmp);
9785     }
9786   else
9787     {
9788       operands[0] = gen_highpart (SImode, operands[0]);
9789       if (GET_CODE (operands[1]) == ABS)
9790         {
9791           tmp = gen_int_mode (0x7fffffff, SImode);
9792           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9793         }
9794       else
9795         {
9796           tmp = gen_int_mode (0x80000000, SImode);
9797           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9798         }
9799     }
9800   operands[1] = tmp;
9801 })
9802
9803 (define_split
9804   [(set (match_operand:XF 0 "register_operand" "")
9805         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9806    (use (match_operand 2 "" ""))
9807    (clobber (reg:CC FLAGS_REG))]
9808   "reload_completed"
9809   [(parallel [(set (match_dup 0) (match_dup 1))
9810               (clobber (reg:CC FLAGS_REG))])]
9811 {
9812   rtx tmp;
9813   operands[0] = gen_rtx_REG (SImode,
9814                              true_regnum (operands[0])
9815                              + (TARGET_64BIT ? 1 : 2));
9816   if (GET_CODE (operands[1]) == ABS)
9817     {
9818       tmp = GEN_INT (0x7fff);
9819       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9820     }
9821   else
9822     {
9823       tmp = GEN_INT (0x8000);
9824       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9825     }
9826   operands[1] = tmp;
9827 })
9828
9829 (define_split
9830   [(set (match_operand 0 "memory_operand" "")
9831         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9832    (use (match_operand 2 "" ""))
9833    (clobber (reg:CC FLAGS_REG))]
9834   "reload_completed"
9835   [(parallel [(set (match_dup 0) (match_dup 1))
9836               (clobber (reg:CC FLAGS_REG))])]
9837 {
9838   enum machine_mode mode = GET_MODE (operands[0]);
9839   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9840   rtx tmp;
9841
9842   operands[0] = adjust_address (operands[0], QImode, size - 1);
9843   if (GET_CODE (operands[1]) == ABS)
9844     {
9845       tmp = gen_int_mode (0x7f, QImode);
9846       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9847     }
9848   else
9849     {
9850       tmp = gen_int_mode (0x80, QImode);
9851       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9852     }
9853   operands[1] = tmp;
9854 })
9855
9856 ;; Conditionalize these after reload. If they match before reload, we 
9857 ;; lose the clobber and ability to use integer instructions.
9858
9859 (define_insn "*negsf2_1"
9860   [(set (match_operand:SF 0 "register_operand" "=f")
9861         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9862   "TARGET_80387 && reload_completed"
9863   "fchs"
9864   [(set_attr "type" "fsgn")
9865    (set_attr "mode" "SF")])
9866
9867 (define_insn "*negdf2_1"
9868   [(set (match_operand:DF 0 "register_operand" "=f")
9869         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9870   "TARGET_80387 && reload_completed"
9871   "fchs"
9872   [(set_attr "type" "fsgn")
9873    (set_attr "mode" "DF")])
9874
9875 (define_insn "*negxf2_1"
9876   [(set (match_operand:XF 0 "register_operand" "=f")
9877         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9878   "TARGET_80387 && reload_completed"
9879   "fchs"
9880   [(set_attr "type" "fsgn")
9881    (set_attr "mode" "XF")])
9882
9883 (define_insn "*abssf2_1"
9884   [(set (match_operand:SF 0 "register_operand" "=f")
9885         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9886   "TARGET_80387 && reload_completed"
9887   "fabs"
9888   [(set_attr "type" "fsgn")
9889    (set_attr "mode" "SF")])
9890
9891 (define_insn "*absdf2_1"
9892   [(set (match_operand:DF 0 "register_operand" "=f")
9893         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9894   "TARGET_80387 && reload_completed"
9895   "fabs"
9896   [(set_attr "type" "fsgn")
9897    (set_attr "mode" "DF")])
9898
9899 (define_insn "*absxf2_1"
9900   [(set (match_operand:XF 0 "register_operand" "=f")
9901         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9902   "TARGET_80387 && reload_completed"
9903   "fabs"
9904   [(set_attr "type" "fsgn")
9905    (set_attr "mode" "DF")])
9906
9907 (define_insn "*negextendsfdf2"
9908   [(set (match_operand:DF 0 "register_operand" "=f")
9909         (neg:DF (float_extend:DF
9910                   (match_operand:SF 1 "register_operand" "0"))))]
9911   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9912   "fchs"
9913   [(set_attr "type" "fsgn")
9914    (set_attr "mode" "DF")])
9915
9916 (define_insn "*negextenddfxf2"
9917   [(set (match_operand:XF 0 "register_operand" "=f")
9918         (neg:XF (float_extend:XF
9919                   (match_operand:DF 1 "register_operand" "0"))))]
9920   "TARGET_80387"
9921   "fchs"
9922   [(set_attr "type" "fsgn")
9923    (set_attr "mode" "XF")])
9924
9925 (define_insn "*negextendsfxf2"
9926   [(set (match_operand:XF 0 "register_operand" "=f")
9927         (neg:XF (float_extend:XF
9928                   (match_operand:SF 1 "register_operand" "0"))))]
9929   "TARGET_80387"
9930   "fchs"
9931   [(set_attr "type" "fsgn")
9932    (set_attr "mode" "XF")])
9933
9934 (define_insn "*absextendsfdf2"
9935   [(set (match_operand:DF 0 "register_operand" "=f")
9936         (abs:DF (float_extend:DF
9937                   (match_operand:SF 1 "register_operand" "0"))))]
9938   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9939   "fabs"
9940   [(set_attr "type" "fsgn")
9941    (set_attr "mode" "DF")])
9942
9943 (define_insn "*absextenddfxf2"
9944   [(set (match_operand:XF 0 "register_operand" "=f")
9945         (abs:XF (float_extend:XF
9946           (match_operand:DF 1 "register_operand" "0"))))]
9947   "TARGET_80387"
9948   "fabs"
9949   [(set_attr "type" "fsgn")
9950    (set_attr "mode" "XF")])
9951
9952 (define_insn "*absextendsfxf2"
9953   [(set (match_operand:XF 0 "register_operand" "=f")
9954         (abs:XF (float_extend:XF
9955           (match_operand:SF 1 "register_operand" "0"))))]
9956   "TARGET_80387"
9957   "fabs"
9958   [(set_attr "type" "fsgn")
9959    (set_attr "mode" "XF")])
9960 \f
9961 ;; One complement instructions
9962
9963 (define_expand "one_cmpldi2"
9964   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9965         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9966   "TARGET_64BIT"
9967   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9968
9969 (define_insn "*one_cmpldi2_1_rex64"
9970   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9971         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9972   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9973   "not{q}\t%0"
9974   [(set_attr "type" "negnot")
9975    (set_attr "mode" "DI")])
9976
9977 (define_insn "*one_cmpldi2_2_rex64"
9978   [(set (reg FLAGS_REG)
9979         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9980                  (const_int 0)))
9981    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9982         (not:DI (match_dup 1)))]
9983   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9984    && ix86_unary_operator_ok (NOT, DImode, operands)"
9985   "#"
9986   [(set_attr "type" "alu1")
9987    (set_attr "mode" "DI")])
9988
9989 (define_split
9990   [(set (match_operand 0 "flags_reg_operand" "")
9991         (match_operator 2 "compare_operator"
9992           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9993            (const_int 0)]))
9994    (set (match_operand:DI 1 "nonimmediate_operand" "")
9995         (not:DI (match_dup 3)))]
9996   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9997   [(parallel [(set (match_dup 0)
9998                    (match_op_dup 2
9999                      [(xor:DI (match_dup 3) (const_int -1))
10000                       (const_int 0)]))
10001               (set (match_dup 1)
10002                    (xor:DI (match_dup 3) (const_int -1)))])]
10003   "")
10004
10005 (define_expand "one_cmplsi2"
10006   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10007         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10008   ""
10009   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10010
10011 (define_insn "*one_cmplsi2_1"
10012   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10013         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10014   "ix86_unary_operator_ok (NOT, SImode, operands)"
10015   "not{l}\t%0"
10016   [(set_attr "type" "negnot")
10017    (set_attr "mode" "SI")])
10018
10019 ;; ??? Currently never generated - xor is used instead.
10020 (define_insn "*one_cmplsi2_1_zext"
10021   [(set (match_operand:DI 0 "register_operand" "=r")
10022         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10023   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10024   "not{l}\t%k0"
10025   [(set_attr "type" "negnot")
10026    (set_attr "mode" "SI")])
10027
10028 (define_insn "*one_cmplsi2_2"
10029   [(set (reg FLAGS_REG)
10030         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10031                  (const_int 0)))
10032    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10033         (not:SI (match_dup 1)))]
10034   "ix86_match_ccmode (insn, CCNOmode)
10035    && ix86_unary_operator_ok (NOT, SImode, operands)"
10036   "#"
10037   [(set_attr "type" "alu1")
10038    (set_attr "mode" "SI")])
10039
10040 (define_split
10041   [(set (match_operand 0 "flags_reg_operand" "")
10042         (match_operator 2 "compare_operator"
10043           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10044            (const_int 0)]))
10045    (set (match_operand:SI 1 "nonimmediate_operand" "")
10046         (not:SI (match_dup 3)))]
10047   "ix86_match_ccmode (insn, CCNOmode)"
10048   [(parallel [(set (match_dup 0)
10049                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10050                                     (const_int 0)]))
10051               (set (match_dup 1)
10052                    (xor:SI (match_dup 3) (const_int -1)))])]
10053   "")
10054
10055 ;; ??? Currently never generated - xor is used instead.
10056 (define_insn "*one_cmplsi2_2_zext"
10057   [(set (reg FLAGS_REG)
10058         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10059                  (const_int 0)))
10060    (set (match_operand:DI 0 "register_operand" "=r")
10061         (zero_extend:DI (not:SI (match_dup 1))))]
10062   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10063    && ix86_unary_operator_ok (NOT, SImode, operands)"
10064   "#"
10065   [(set_attr "type" "alu1")
10066    (set_attr "mode" "SI")])
10067
10068 (define_split
10069   [(set (match_operand 0 "flags_reg_operand" "")
10070         (match_operator 2 "compare_operator"
10071           [(not:SI (match_operand:SI 3 "register_operand" ""))
10072            (const_int 0)]))
10073    (set (match_operand:DI 1 "register_operand" "")
10074         (zero_extend:DI (not:SI (match_dup 3))))]
10075   "ix86_match_ccmode (insn, CCNOmode)"
10076   [(parallel [(set (match_dup 0)
10077                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10078                                     (const_int 0)]))
10079               (set (match_dup 1)
10080                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10081   "")
10082
10083 (define_expand "one_cmplhi2"
10084   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10085         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10086   "TARGET_HIMODE_MATH"
10087   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10088
10089 (define_insn "*one_cmplhi2_1"
10090   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10091         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10092   "ix86_unary_operator_ok (NOT, HImode, operands)"
10093   "not{w}\t%0"
10094   [(set_attr "type" "negnot")
10095    (set_attr "mode" "HI")])
10096
10097 (define_insn "*one_cmplhi2_2"
10098   [(set (reg FLAGS_REG)
10099         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10100                  (const_int 0)))
10101    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10102         (not:HI (match_dup 1)))]
10103   "ix86_match_ccmode (insn, CCNOmode)
10104    && ix86_unary_operator_ok (NEG, HImode, operands)"
10105   "#"
10106   [(set_attr "type" "alu1")
10107    (set_attr "mode" "HI")])
10108
10109 (define_split
10110   [(set (match_operand 0 "flags_reg_operand" "")
10111         (match_operator 2 "compare_operator"
10112           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10113            (const_int 0)]))
10114    (set (match_operand:HI 1 "nonimmediate_operand" "")
10115         (not:HI (match_dup 3)))]
10116   "ix86_match_ccmode (insn, CCNOmode)"
10117   [(parallel [(set (match_dup 0)
10118                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10119                                     (const_int 0)]))
10120               (set (match_dup 1)
10121                    (xor:HI (match_dup 3) (const_int -1)))])]
10122   "")
10123
10124 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10125 (define_expand "one_cmplqi2"
10126   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10127         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10128   "TARGET_QIMODE_MATH"
10129   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10130
10131 (define_insn "*one_cmplqi2_1"
10132   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10133         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10134   "ix86_unary_operator_ok (NOT, QImode, operands)"
10135   "@
10136    not{b}\t%0
10137    not{l}\t%k0"
10138   [(set_attr "type" "negnot")
10139    (set_attr "mode" "QI,SI")])
10140
10141 (define_insn "*one_cmplqi2_2"
10142   [(set (reg FLAGS_REG)
10143         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10144                  (const_int 0)))
10145    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10146         (not:QI (match_dup 1)))]
10147   "ix86_match_ccmode (insn, CCNOmode)
10148    && ix86_unary_operator_ok (NOT, QImode, operands)"
10149   "#"
10150   [(set_attr "type" "alu1")
10151    (set_attr "mode" "QI")])
10152
10153 (define_split
10154   [(set (match_operand 0 "flags_reg_operand" "")
10155         (match_operator 2 "compare_operator"
10156           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10157            (const_int 0)]))
10158    (set (match_operand:QI 1 "nonimmediate_operand" "")
10159         (not:QI (match_dup 3)))]
10160   "ix86_match_ccmode (insn, CCNOmode)"
10161   [(parallel [(set (match_dup 0)
10162                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10163                                     (const_int 0)]))
10164               (set (match_dup 1)
10165                    (xor:QI (match_dup 3) (const_int -1)))])]
10166   "")
10167 \f
10168 ;; Arithmetic shift instructions
10169
10170 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10171 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10172 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10173 ;; from the assembler input.
10174 ;;
10175 ;; This instruction shifts the target reg/mem as usual, but instead of
10176 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10177 ;; is a left shift double, bits are taken from the high order bits of
10178 ;; reg, else if the insn is a shift right double, bits are taken from the
10179 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10180 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10181 ;;
10182 ;; Since sh[lr]d does not change the `reg' operand, that is done
10183 ;; separately, making all shifts emit pairs of shift double and normal
10184 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10185 ;; support a 63 bit shift, each shift where the count is in a reg expands
10186 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10187 ;;
10188 ;; If the shift count is a constant, we need never emit more than one
10189 ;; shift pair, instead using moves and sign extension for counts greater
10190 ;; than 31.
10191
10192 (define_expand "ashldi3"
10193   [(set (match_operand:DI 0 "shiftdi_operand" "")
10194         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10195                    (match_operand:QI 2 "nonmemory_operand" "")))]
10196   ""
10197   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10198
10199 (define_insn "*ashldi3_1_rex64"
10200   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10201         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10202                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10203    (clobber (reg:CC FLAGS_REG))]
10204   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10205 {
10206   switch (get_attr_type (insn))
10207     {
10208     case TYPE_ALU:
10209       if (operands[2] != const1_rtx)
10210         abort ();
10211       if (!rtx_equal_p (operands[0], operands[1]))
10212         abort ();
10213       return "add{q}\t{%0, %0|%0, %0}";
10214
10215     case TYPE_LEA:
10216       if (GET_CODE (operands[2]) != CONST_INT
10217           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10218         abort ();
10219       operands[1] = gen_rtx_MULT (DImode, operands[1],
10220                                   GEN_INT (1 << INTVAL (operands[2])));
10221       return "lea{q}\t{%a1, %0|%0, %a1}";
10222
10223     default:
10224       if (REG_P (operands[2]))
10225         return "sal{q}\t{%b2, %0|%0, %b2}";
10226       else if (operands[2] == const1_rtx
10227                && (TARGET_SHIFT1 || optimize_size))
10228         return "sal{q}\t%0";
10229       else
10230         return "sal{q}\t{%2, %0|%0, %2}";
10231     }
10232 }
10233   [(set (attr "type")
10234      (cond [(eq_attr "alternative" "1")
10235               (const_string "lea")
10236             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10237                           (const_int 0))
10238                       (match_operand 0 "register_operand" ""))
10239                  (match_operand 2 "const1_operand" ""))
10240               (const_string "alu")
10241            ]
10242            (const_string "ishift")))
10243    (set_attr "mode" "DI")])
10244
10245 ;; Convert lea to the lea pattern to avoid flags dependency.
10246 (define_split
10247   [(set (match_operand:DI 0 "register_operand" "")
10248         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10249                    (match_operand:QI 2 "immediate_operand" "")))
10250    (clobber (reg:CC FLAGS_REG))]
10251   "TARGET_64BIT && reload_completed
10252    && true_regnum (operands[0]) != true_regnum (operands[1])"
10253   [(set (match_dup 0)
10254         (mult:DI (match_dup 1)
10255                  (match_dup 2)))]
10256   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10257
10258 ;; This pattern can't accept a variable shift count, since shifts by
10259 ;; zero don't affect the flags.  We assume that shifts by constant
10260 ;; zero are optimized away.
10261 (define_insn "*ashldi3_cmp_rex64"
10262   [(set (reg FLAGS_REG)
10263         (compare
10264           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10265                      (match_operand:QI 2 "immediate_operand" "e"))
10266           (const_int 0)))
10267    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10268         (ashift:DI (match_dup 1) (match_dup 2)))]
10269   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10270    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10271 {
10272   switch (get_attr_type (insn))
10273     {
10274     case TYPE_ALU:
10275       if (operands[2] != const1_rtx)
10276         abort ();
10277       return "add{q}\t{%0, %0|%0, %0}";
10278
10279     default:
10280       if (REG_P (operands[2]))
10281         return "sal{q}\t{%b2, %0|%0, %b2}";
10282       else if (operands[2] == const1_rtx
10283                && (TARGET_SHIFT1 || optimize_size))
10284         return "sal{q}\t%0";
10285       else
10286         return "sal{q}\t{%2, %0|%0, %2}";
10287     }
10288 }
10289   [(set (attr "type")
10290      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10291                           (const_int 0))
10292                       (match_operand 0 "register_operand" ""))
10293                  (match_operand 2 "const1_operand" ""))
10294               (const_string "alu")
10295            ]
10296            (const_string "ishift")))
10297    (set_attr "mode" "DI")])
10298
10299 (define_insn "*ashldi3_1"
10300   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10301         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10302                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10303    (clobber (reg:CC FLAGS_REG))]
10304   "!TARGET_64BIT"
10305   "#"
10306   [(set_attr "type" "multi")])
10307
10308 ;; By default we don't ask for a scratch register, because when DImode
10309 ;; values are manipulated, registers are already at a premium.  But if
10310 ;; we have one handy, we won't turn it away.
10311 (define_peephole2
10312   [(match_scratch:SI 3 "r")
10313    (parallel [(set (match_operand:DI 0 "register_operand" "")
10314                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10315                               (match_operand:QI 2 "nonmemory_operand" "")))
10316               (clobber (reg:CC FLAGS_REG))])
10317    (match_dup 3)]
10318   "!TARGET_64BIT && TARGET_CMOVE"
10319   [(const_int 0)]
10320   "ix86_split_ashldi (operands, operands[3]); DONE;")
10321
10322 (define_split
10323   [(set (match_operand:DI 0 "register_operand" "")
10324         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10325                    (match_operand:QI 2 "nonmemory_operand" "")))
10326    (clobber (reg:CC FLAGS_REG))]
10327   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10328   [(const_int 0)]
10329   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10330
10331 (define_insn "x86_shld_1"
10332   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10333         (ior:SI (ashift:SI (match_dup 0)
10334                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10335                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10336                   (minus:QI (const_int 32) (match_dup 2)))))
10337    (clobber (reg:CC FLAGS_REG))]
10338   ""
10339   "@
10340    shld{l}\t{%2, %1, %0|%0, %1, %2}
10341    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10342   [(set_attr "type" "ishift")
10343    (set_attr "prefix_0f" "1")
10344    (set_attr "mode" "SI")
10345    (set_attr "pent_pair" "np")
10346    (set_attr "athlon_decode" "vector")])
10347
10348 (define_expand "x86_shift_adj_1"
10349   [(set (reg:CCZ FLAGS_REG)
10350         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10351                              (const_int 32))
10352                      (const_int 0)))
10353    (set (match_operand:SI 0 "register_operand" "")
10354         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10355                          (match_operand:SI 1 "register_operand" "")
10356                          (match_dup 0)))
10357    (set (match_dup 1)
10358         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10359                          (match_operand:SI 3 "register_operand" "r")
10360                          (match_dup 1)))]
10361   "TARGET_CMOVE"
10362   "")
10363
10364 (define_expand "x86_shift_adj_2"
10365   [(use (match_operand:SI 0 "register_operand" ""))
10366    (use (match_operand:SI 1 "register_operand" ""))
10367    (use (match_operand:QI 2 "register_operand" ""))]
10368   ""
10369 {
10370   rtx label = gen_label_rtx ();
10371   rtx tmp;
10372
10373   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10374
10375   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10376   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10377   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10378                               gen_rtx_LABEL_REF (VOIDmode, label),
10379                               pc_rtx);
10380   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10381   JUMP_LABEL (tmp) = label;
10382
10383   emit_move_insn (operands[0], operands[1]);
10384   ix86_expand_clear (operands[1]);
10385
10386   emit_label (label);
10387   LABEL_NUSES (label) = 1;
10388
10389   DONE;
10390 })
10391
10392 (define_expand "ashlsi3"
10393   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10394         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10395                    (match_operand:QI 2 "nonmemory_operand" "")))
10396    (clobber (reg:CC FLAGS_REG))]
10397   ""
10398   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10399
10400 (define_insn "*ashlsi3_1"
10401   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10402         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10403                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10404    (clobber (reg:CC FLAGS_REG))]
10405   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10406 {
10407   switch (get_attr_type (insn))
10408     {
10409     case TYPE_ALU:
10410       if (operands[2] != const1_rtx)
10411         abort ();
10412       if (!rtx_equal_p (operands[0], operands[1]))
10413         abort ();
10414       return "add{l}\t{%0, %0|%0, %0}";
10415
10416     case TYPE_LEA:
10417       return "#";
10418
10419     default:
10420       if (REG_P (operands[2]))
10421         return "sal{l}\t{%b2, %0|%0, %b2}";
10422       else if (operands[2] == const1_rtx
10423                && (TARGET_SHIFT1 || optimize_size))
10424         return "sal{l}\t%0";
10425       else
10426         return "sal{l}\t{%2, %0|%0, %2}";
10427     }
10428 }
10429   [(set (attr "type")
10430      (cond [(eq_attr "alternative" "1")
10431               (const_string "lea")
10432             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10433                           (const_int 0))
10434                       (match_operand 0 "register_operand" ""))
10435                  (match_operand 2 "const1_operand" ""))
10436               (const_string "alu")
10437            ]
10438            (const_string "ishift")))
10439    (set_attr "mode" "SI")])
10440
10441 ;; Convert lea to the lea pattern to avoid flags dependency.
10442 (define_split
10443   [(set (match_operand 0 "register_operand" "")
10444         (ashift (match_operand 1 "index_register_operand" "")
10445                 (match_operand:QI 2 "const_int_operand" "")))
10446    (clobber (reg:CC FLAGS_REG))]
10447   "reload_completed
10448    && true_regnum (operands[0]) != true_regnum (operands[1])
10449    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10450   [(const_int 0)]
10451 {
10452   rtx pat;
10453   enum machine_mode mode = GET_MODE (operands[0]);
10454
10455   if (GET_MODE_SIZE (mode) < 4)
10456     operands[0] = gen_lowpart (SImode, operands[0]);
10457   if (mode != Pmode)
10458     operands[1] = gen_lowpart (Pmode, operands[1]);
10459   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10460
10461   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10462   if (Pmode != SImode)
10463     pat = gen_rtx_SUBREG (SImode, pat, 0);
10464   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10465   DONE;
10466 })
10467
10468 ;; Rare case of shifting RSP is handled by generating move and shift
10469 (define_split
10470   [(set (match_operand 0 "register_operand" "")
10471         (ashift (match_operand 1 "register_operand" "")
10472                 (match_operand:QI 2 "const_int_operand" "")))
10473    (clobber (reg:CC FLAGS_REG))]
10474   "reload_completed
10475    && true_regnum (operands[0]) != true_regnum (operands[1])"
10476   [(const_int 0)]
10477 {
10478   rtx pat, clob;
10479   emit_move_insn (operands[1], operands[0]);
10480   pat = gen_rtx_SET (VOIDmode, operands[0],
10481                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10482                                      operands[0], operands[2]));
10483   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10484   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10485   DONE;
10486 })
10487
10488 (define_insn "*ashlsi3_1_zext"
10489   [(set (match_operand:DI 0 "register_operand" "=r,r")
10490         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10491                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10492    (clobber (reg:CC FLAGS_REG))]
10493   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10494 {
10495   switch (get_attr_type (insn))
10496     {
10497     case TYPE_ALU:
10498       if (operands[2] != const1_rtx)
10499         abort ();
10500       return "add{l}\t{%k0, %k0|%k0, %k0}";
10501
10502     case TYPE_LEA:
10503       return "#";
10504
10505     default:
10506       if (REG_P (operands[2]))
10507         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10508       else if (operands[2] == const1_rtx
10509                && (TARGET_SHIFT1 || optimize_size))
10510         return "sal{l}\t%k0";
10511       else
10512         return "sal{l}\t{%2, %k0|%k0, %2}";
10513     }
10514 }
10515   [(set (attr "type")
10516      (cond [(eq_attr "alternative" "1")
10517               (const_string "lea")
10518             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10519                      (const_int 0))
10520                  (match_operand 2 "const1_operand" ""))
10521               (const_string "alu")
10522            ]
10523            (const_string "ishift")))
10524    (set_attr "mode" "SI")])
10525
10526 ;; Convert lea to the lea pattern to avoid flags dependency.
10527 (define_split
10528   [(set (match_operand:DI 0 "register_operand" "")
10529         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10530                                 (match_operand:QI 2 "const_int_operand" ""))))
10531    (clobber (reg:CC FLAGS_REG))]
10532   "TARGET_64BIT && reload_completed
10533    && true_regnum (operands[0]) != true_regnum (operands[1])"
10534   [(set (match_dup 0) (zero_extend:DI
10535                         (subreg:SI (mult:SI (match_dup 1)
10536                                             (match_dup 2)) 0)))]
10537 {
10538   operands[1] = gen_lowpart (Pmode, operands[1]);
10539   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10540 })
10541
10542 ;; This pattern can't accept a variable shift count, since shifts by
10543 ;; zero don't affect the flags.  We assume that shifts by constant
10544 ;; zero are optimized away.
10545 (define_insn "*ashlsi3_cmp"
10546   [(set (reg FLAGS_REG)
10547         (compare
10548           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10549                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10550           (const_int 0)))
10551    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10552         (ashift:SI (match_dup 1) (match_dup 2)))]
10553   "ix86_match_ccmode (insn, CCGOCmode)
10554    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10555 {
10556   switch (get_attr_type (insn))
10557     {
10558     case TYPE_ALU:
10559       if (operands[2] != const1_rtx)
10560         abort ();
10561       return "add{l}\t{%0, %0|%0, %0}";
10562
10563     default:
10564       if (REG_P (operands[2]))
10565         return "sal{l}\t{%b2, %0|%0, %b2}";
10566       else if (operands[2] == const1_rtx
10567                && (TARGET_SHIFT1 || optimize_size))
10568         return "sal{l}\t%0";
10569       else
10570         return "sal{l}\t{%2, %0|%0, %2}";
10571     }
10572 }
10573   [(set (attr "type")
10574      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10575                           (const_int 0))
10576                       (match_operand 0 "register_operand" ""))
10577                  (match_operand 2 "const1_operand" ""))
10578               (const_string "alu")
10579            ]
10580            (const_string "ishift")))
10581    (set_attr "mode" "SI")])
10582
10583 (define_insn "*ashlsi3_cmp_zext"
10584   [(set (reg FLAGS_REG)
10585         (compare
10586           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10587                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10588           (const_int 0)))
10589    (set (match_operand:DI 0 "register_operand" "=r")
10590         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10591   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10592    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10593 {
10594   switch (get_attr_type (insn))
10595     {
10596     case TYPE_ALU:
10597       if (operands[2] != const1_rtx)
10598         abort ();
10599       return "add{l}\t{%k0, %k0|%k0, %k0}";
10600
10601     default:
10602       if (REG_P (operands[2]))
10603         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10604       else if (operands[2] == const1_rtx
10605                && (TARGET_SHIFT1 || optimize_size))
10606         return "sal{l}\t%k0";
10607       else
10608         return "sal{l}\t{%2, %k0|%k0, %2}";
10609     }
10610 }
10611   [(set (attr "type")
10612      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613                      (const_int 0))
10614                  (match_operand 2 "const1_operand" ""))
10615               (const_string "alu")
10616            ]
10617            (const_string "ishift")))
10618    (set_attr "mode" "SI")])
10619
10620 (define_expand "ashlhi3"
10621   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10622         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10623                    (match_operand:QI 2 "nonmemory_operand" "")))
10624    (clobber (reg:CC FLAGS_REG))]
10625   "TARGET_HIMODE_MATH"
10626   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10627
10628 (define_insn "*ashlhi3_1_lea"
10629   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10630         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10631                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10632    (clobber (reg:CC FLAGS_REG))]
10633   "!TARGET_PARTIAL_REG_STALL
10634    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10635 {
10636   switch (get_attr_type (insn))
10637     {
10638     case TYPE_LEA:
10639       return "#";
10640     case TYPE_ALU:
10641       if (operands[2] != const1_rtx)
10642         abort ();
10643       return "add{w}\t{%0, %0|%0, %0}";
10644
10645     default:
10646       if (REG_P (operands[2]))
10647         return "sal{w}\t{%b2, %0|%0, %b2}";
10648       else if (operands[2] == const1_rtx
10649                && (TARGET_SHIFT1 || optimize_size))
10650         return "sal{w}\t%0";
10651       else
10652         return "sal{w}\t{%2, %0|%0, %2}";
10653     }
10654 }
10655   [(set (attr "type")
10656      (cond [(eq_attr "alternative" "1")
10657               (const_string "lea")
10658             (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,SI")])
10666
10667 (define_insn "*ashlhi3_1"
10668   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10669         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10670                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10671    (clobber (reg:CC FLAGS_REG))]
10672   "TARGET_PARTIAL_REG_STALL
10673    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10674 {
10675   switch (get_attr_type (insn))
10676     {
10677     case TYPE_ALU:
10678       if (operands[2] != const1_rtx)
10679         abort ();
10680       return "add{w}\t{%0, %0|%0, %0}";
10681
10682     default:
10683       if (REG_P (operands[2]))
10684         return "sal{w}\t{%b2, %0|%0, %b2}";
10685       else if (operands[2] == const1_rtx
10686                && (TARGET_SHIFT1 || optimize_size))
10687         return "sal{w}\t%0";
10688       else
10689         return "sal{w}\t{%2, %0|%0, %2}";
10690     }
10691 }
10692   [(set (attr "type")
10693      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10694                           (const_int 0))
10695                       (match_operand 0 "register_operand" ""))
10696                  (match_operand 2 "const1_operand" ""))
10697               (const_string "alu")
10698            ]
10699            (const_string "ishift")))
10700    (set_attr "mode" "HI")])
10701
10702 ;; This pattern can't accept a variable shift count, since shifts by
10703 ;; zero don't affect the flags.  We assume that shifts by constant
10704 ;; zero are optimized away.
10705 (define_insn "*ashlhi3_cmp"
10706   [(set (reg FLAGS_REG)
10707         (compare
10708           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10709                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10710           (const_int 0)))
10711    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10712         (ashift:HI (match_dup 1) (match_dup 2)))]
10713   "ix86_match_ccmode (insn, CCGOCmode)
10714    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10715 {
10716   switch (get_attr_type (insn))
10717     {
10718     case TYPE_ALU:
10719       if (operands[2] != const1_rtx)
10720         abort ();
10721       return "add{w}\t{%0, %0|%0, %0}";
10722
10723     default:
10724       if (REG_P (operands[2]))
10725         return "sal{w}\t{%b2, %0|%0, %b2}";
10726       else if (operands[2] == const1_rtx
10727                && (TARGET_SHIFT1 || optimize_size))
10728         return "sal{w}\t%0";
10729       else
10730         return "sal{w}\t{%2, %0|%0, %2}";
10731     }
10732 }
10733   [(set (attr "type")
10734      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10735                           (const_int 0))
10736                       (match_operand 0 "register_operand" ""))
10737                  (match_operand 2 "const1_operand" ""))
10738               (const_string "alu")
10739            ]
10740            (const_string "ishift")))
10741    (set_attr "mode" "HI")])
10742
10743 (define_expand "ashlqi3"
10744   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10745         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10746                    (match_operand:QI 2 "nonmemory_operand" "")))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "TARGET_QIMODE_MATH"
10749   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10750
10751 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10752
10753 (define_insn "*ashlqi3_1_lea"
10754   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10755         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10756                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10757    (clobber (reg:CC FLAGS_REG))]
10758   "!TARGET_PARTIAL_REG_STALL
10759    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10760 {
10761   switch (get_attr_type (insn))
10762     {
10763     case TYPE_LEA:
10764       return "#";
10765     case TYPE_ALU:
10766       if (operands[2] != const1_rtx)
10767         abort ();
10768       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10769         return "add{l}\t{%k0, %k0|%k0, %k0}";
10770       else
10771         return "add{b}\t{%0, %0|%0, %0}";
10772
10773     default:
10774       if (REG_P (operands[2]))
10775         {
10776           if (get_attr_mode (insn) == MODE_SI)
10777             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10778           else
10779             return "sal{b}\t{%b2, %0|%0, %b2}";
10780         }
10781       else if (operands[2] == const1_rtx
10782                && (TARGET_SHIFT1 || optimize_size))
10783         {
10784           if (get_attr_mode (insn) == MODE_SI)
10785             return "sal{l}\t%0";
10786           else
10787             return "sal{b}\t%0";
10788         }
10789       else
10790         {
10791           if (get_attr_mode (insn) == MODE_SI)
10792             return "sal{l}\t{%2, %k0|%k0, %2}";
10793           else
10794             return "sal{b}\t{%2, %0|%0, %2}";
10795         }
10796     }
10797 }
10798   [(set (attr "type")
10799      (cond [(eq_attr "alternative" "2")
10800               (const_string "lea")
10801             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10802                           (const_int 0))
10803                       (match_operand 0 "register_operand" ""))
10804                  (match_operand 2 "const1_operand" ""))
10805               (const_string "alu")
10806            ]
10807            (const_string "ishift")))
10808    (set_attr "mode" "QI,SI,SI")])
10809
10810 (define_insn "*ashlqi3_1"
10811   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10812         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10813                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10814    (clobber (reg:CC FLAGS_REG))]
10815   "TARGET_PARTIAL_REG_STALL
10816    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10817 {
10818   switch (get_attr_type (insn))
10819     {
10820     case TYPE_ALU:
10821       if (operands[2] != const1_rtx)
10822         abort ();
10823       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10824         return "add{l}\t{%k0, %k0|%k0, %k0}";
10825       else
10826         return "add{b}\t{%0, %0|%0, %0}";
10827
10828     default:
10829       if (REG_P (operands[2]))
10830         {
10831           if (get_attr_mode (insn) == MODE_SI)
10832             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10833           else
10834             return "sal{b}\t{%b2, %0|%0, %b2}";
10835         }
10836       else if (operands[2] == const1_rtx
10837                && (TARGET_SHIFT1 || optimize_size))
10838         {
10839           if (get_attr_mode (insn) == MODE_SI)
10840             return "sal{l}\t%0";
10841           else
10842             return "sal{b}\t%0";
10843         }
10844       else
10845         {
10846           if (get_attr_mode (insn) == MODE_SI)
10847             return "sal{l}\t{%2, %k0|%k0, %2}";
10848           else
10849             return "sal{b}\t{%2, %0|%0, %2}";
10850         }
10851     }
10852 }
10853   [(set (attr "type")
10854      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10855                           (const_int 0))
10856                       (match_operand 0 "register_operand" ""))
10857                  (match_operand 2 "const1_operand" ""))
10858               (const_string "alu")
10859            ]
10860            (const_string "ishift")))
10861    (set_attr "mode" "QI,SI")])
10862
10863 ;; This pattern can't accept a variable shift count, since shifts by
10864 ;; zero don't affect the flags.  We assume that shifts by constant
10865 ;; zero are optimized away.
10866 (define_insn "*ashlqi3_cmp"
10867   [(set (reg FLAGS_REG)
10868         (compare
10869           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10870                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10871           (const_int 0)))
10872    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10873         (ashift:QI (match_dup 1) (match_dup 2)))]
10874   "ix86_match_ccmode (insn, CCGOCmode)
10875    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10876 {
10877   switch (get_attr_type (insn))
10878     {
10879     case TYPE_ALU:
10880       if (operands[2] != const1_rtx)
10881         abort ();
10882       return "add{b}\t{%0, %0|%0, %0}";
10883
10884     default:
10885       if (REG_P (operands[2]))
10886         return "sal{b}\t{%b2, %0|%0, %b2}";
10887       else if (operands[2] == const1_rtx
10888                && (TARGET_SHIFT1 || optimize_size))
10889         return "sal{b}\t%0";
10890       else
10891         return "sal{b}\t{%2, %0|%0, %2}";
10892     }
10893 }
10894   [(set (attr "type")
10895      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10896                           (const_int 0))
10897                       (match_operand 0 "register_operand" ""))
10898                  (match_operand 2 "const1_operand" ""))
10899               (const_string "alu")
10900            ]
10901            (const_string "ishift")))
10902    (set_attr "mode" "QI")])
10903
10904 ;; See comment above `ashldi3' about how this works.
10905
10906 (define_expand "ashrdi3"
10907   [(set (match_operand:DI 0 "shiftdi_operand" "")
10908         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10909                      (match_operand:QI 2 "nonmemory_operand" "")))]
10910   ""
10911   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10912
10913 (define_insn "*ashrdi3_63_rex64"
10914   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10915         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10916                      (match_operand:DI 2 "const_int_operand" "i,i")))
10917    (clobber (reg:CC FLAGS_REG))]
10918   "TARGET_64BIT && INTVAL (operands[2]) == 63
10919    && (TARGET_USE_CLTD || optimize_size)
10920    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10921   "@
10922    {cqto|cqo}
10923    sar{q}\t{%2, %0|%0, %2}"
10924   [(set_attr "type" "imovx,ishift")
10925    (set_attr "prefix_0f" "0,*")
10926    (set_attr "length_immediate" "0,*")
10927    (set_attr "modrm" "0,1")
10928    (set_attr "mode" "DI")])
10929
10930 (define_insn "*ashrdi3_1_one_bit_rex64"
10931   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10932         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10933                      (match_operand:QI 2 "const1_operand" "")))
10934    (clobber (reg:CC FLAGS_REG))]
10935   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10936    && (TARGET_SHIFT1 || optimize_size)"
10937   "sar{q}\t%0"
10938   [(set_attr "type" "ishift")
10939    (set (attr "length") 
10940      (if_then_else (match_operand:DI 0 "register_operand" "") 
10941         (const_string "2")
10942         (const_string "*")))])
10943
10944 (define_insn "*ashrdi3_1_rex64"
10945   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10946         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10947                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10948    (clobber (reg:CC FLAGS_REG))]
10949   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10950   "@
10951    sar{q}\t{%2, %0|%0, %2}
10952    sar{q}\t{%b2, %0|%0, %b2}"
10953   [(set_attr "type" "ishift")
10954    (set_attr "mode" "DI")])
10955
10956 ;; This pattern can't accept a variable shift count, since shifts by
10957 ;; zero don't affect the flags.  We assume that shifts by constant
10958 ;; zero are optimized away.
10959 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10960   [(set (reg FLAGS_REG)
10961         (compare
10962           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10963                        (match_operand:QI 2 "const1_operand" ""))
10964           (const_int 0)))
10965    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10966         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10967   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10968    && (TARGET_SHIFT1 || optimize_size)
10969    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10970   "sar{q}\t%0"
10971   [(set_attr "type" "ishift")
10972    (set (attr "length") 
10973      (if_then_else (match_operand:DI 0 "register_operand" "") 
10974         (const_string "2")
10975         (const_string "*")))])
10976
10977 ;; This pattern can't accept a variable shift count, since shifts by
10978 ;; zero don't affect the flags.  We assume that shifts by constant
10979 ;; zero are optimized away.
10980 (define_insn "*ashrdi3_cmp_rex64"
10981   [(set (reg FLAGS_REG)
10982         (compare
10983           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10984                        (match_operand:QI 2 "const_int_operand" "n"))
10985           (const_int 0)))
10986    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10987         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10988   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10989    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10990   "sar{q}\t{%2, %0|%0, %2}"
10991   [(set_attr "type" "ishift")
10992    (set_attr "mode" "DI")])
10993
10994 (define_insn "*ashrdi3_1"
10995   [(set (match_operand:DI 0 "register_operand" "=r")
10996         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10997                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10998    (clobber (reg:CC FLAGS_REG))]
10999   "!TARGET_64BIT"
11000   "#"
11001   [(set_attr "type" "multi")])
11002
11003 ;; By default we don't ask for a scratch register, because when DImode
11004 ;; values are manipulated, registers are already at a premium.  But if
11005 ;; we have one handy, we won't turn it away.
11006 (define_peephole2
11007   [(match_scratch:SI 3 "r")
11008    (parallel [(set (match_operand:DI 0 "register_operand" "")
11009                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11010                                 (match_operand:QI 2 "nonmemory_operand" "")))
11011               (clobber (reg:CC FLAGS_REG))])
11012    (match_dup 3)]
11013   "!TARGET_64BIT && TARGET_CMOVE"
11014   [(const_int 0)]
11015   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11016
11017 (define_split
11018   [(set (match_operand:DI 0 "register_operand" "")
11019         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11020                      (match_operand:QI 2 "nonmemory_operand" "")))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11023   [(const_int 0)]
11024   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11025
11026 (define_insn "x86_shrd_1"
11027   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11028         (ior:SI (ashiftrt:SI (match_dup 0)
11029                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11030                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11031                   (minus:QI (const_int 32) (match_dup 2)))))
11032    (clobber (reg:CC FLAGS_REG))]
11033   ""
11034   "@
11035    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11036    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11037   [(set_attr "type" "ishift")
11038    (set_attr "prefix_0f" "1")
11039    (set_attr "pent_pair" "np")
11040    (set_attr "mode" "SI")])
11041
11042 (define_expand "x86_shift_adj_3"
11043   [(use (match_operand:SI 0 "register_operand" ""))
11044    (use (match_operand:SI 1 "register_operand" ""))
11045    (use (match_operand:QI 2 "register_operand" ""))]
11046   ""
11047 {
11048   rtx label = gen_label_rtx ();
11049   rtx tmp;
11050
11051   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11052
11053   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11054   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11055   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11056                               gen_rtx_LABEL_REF (VOIDmode, label),
11057                               pc_rtx);
11058   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11059   JUMP_LABEL (tmp) = label;
11060
11061   emit_move_insn (operands[0], operands[1]);
11062   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11063
11064   emit_label (label);
11065   LABEL_NUSES (label) = 1;
11066
11067   DONE;
11068 })
11069
11070 (define_insn "ashrsi3_31"
11071   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11072         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11073                      (match_operand:SI 2 "const_int_operand" "i,i")))
11074    (clobber (reg:CC FLAGS_REG))]
11075   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11076    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11077   "@
11078    {cltd|cdq}
11079    sar{l}\t{%2, %0|%0, %2}"
11080   [(set_attr "type" "imovx,ishift")
11081    (set_attr "prefix_0f" "0,*")
11082    (set_attr "length_immediate" "0,*")
11083    (set_attr "modrm" "0,1")
11084    (set_attr "mode" "SI")])
11085
11086 (define_insn "*ashrsi3_31_zext"
11087   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11088         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11089                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11090    (clobber (reg:CC FLAGS_REG))]
11091   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11092    && INTVAL (operands[2]) == 31
11093    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11094   "@
11095    {cltd|cdq}
11096    sar{l}\t{%2, %k0|%k0, %2}"
11097   [(set_attr "type" "imovx,ishift")
11098    (set_attr "prefix_0f" "0,*")
11099    (set_attr "length_immediate" "0,*")
11100    (set_attr "modrm" "0,1")
11101    (set_attr "mode" "SI")])
11102
11103 (define_expand "ashrsi3"
11104   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11105         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11106                      (match_operand:QI 2 "nonmemory_operand" "")))
11107    (clobber (reg:CC FLAGS_REG))]
11108   ""
11109   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11110
11111 (define_insn "*ashrsi3_1_one_bit"
11112   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11113         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11114                      (match_operand:QI 2 "const1_operand" "")))
11115    (clobber (reg:CC FLAGS_REG))]
11116   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11117    && (TARGET_SHIFT1 || optimize_size)"
11118   "sar{l}\t%0"
11119   [(set_attr "type" "ishift")
11120    (set (attr "length") 
11121      (if_then_else (match_operand:SI 0 "register_operand" "") 
11122         (const_string "2")
11123         (const_string "*")))])
11124
11125 (define_insn "*ashrsi3_1_one_bit_zext"
11126   [(set (match_operand:DI 0 "register_operand" "=r")
11127         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11128                                      (match_operand:QI 2 "const1_operand" ""))))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11131    && (TARGET_SHIFT1 || optimize_size)"
11132   "sar{l}\t%k0"
11133   [(set_attr "type" "ishift")
11134    (set_attr "length" "2")])
11135
11136 (define_insn "*ashrsi3_1"
11137   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11138         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11139                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11140    (clobber (reg:CC FLAGS_REG))]
11141   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11142   "@
11143    sar{l}\t{%2, %0|%0, %2}
11144    sar{l}\t{%b2, %0|%0, %b2}"
11145   [(set_attr "type" "ishift")
11146    (set_attr "mode" "SI")])
11147
11148 (define_insn "*ashrsi3_1_zext"
11149   [(set (match_operand:DI 0 "register_operand" "=r,r")
11150         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11151                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11152    (clobber (reg:CC FLAGS_REG))]
11153   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11154   "@
11155    sar{l}\t{%2, %k0|%k0, %2}
11156    sar{l}\t{%b2, %k0|%k0, %b2}"
11157   [(set_attr "type" "ishift")
11158    (set_attr "mode" "SI")])
11159
11160 ;; This pattern can't accept a variable shift count, since shifts by
11161 ;; zero don't affect the flags.  We assume that shifts by constant
11162 ;; zero are optimized away.
11163 (define_insn "*ashrsi3_one_bit_cmp"
11164   [(set (reg FLAGS_REG)
11165         (compare
11166           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11167                        (match_operand:QI 2 "const1_operand" ""))
11168           (const_int 0)))
11169    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11170         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11171   "ix86_match_ccmode (insn, CCGOCmode)
11172    && (TARGET_SHIFT1 || optimize_size)
11173    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11174   "sar{l}\t%0"
11175   [(set_attr "type" "ishift")
11176    (set (attr "length") 
11177      (if_then_else (match_operand:SI 0 "register_operand" "") 
11178         (const_string "2")
11179         (const_string "*")))])
11180
11181 (define_insn "*ashrsi3_one_bit_cmp_zext"
11182   [(set (reg FLAGS_REG)
11183         (compare
11184           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11185                        (match_operand:QI 2 "const1_operand" ""))
11186           (const_int 0)))
11187    (set (match_operand:DI 0 "register_operand" "=r")
11188         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11189   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11190    && (TARGET_SHIFT1 || optimize_size)
11191    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11192   "sar{l}\t%k0"
11193   [(set_attr "type" "ishift")
11194    (set_attr "length" "2")])
11195
11196 ;; This pattern can't accept a variable shift count, since shifts by
11197 ;; zero don't affect the flags.  We assume that shifts by constant
11198 ;; zero are optimized away.
11199 (define_insn "*ashrsi3_cmp"
11200   [(set (reg FLAGS_REG)
11201         (compare
11202           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11203                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11204           (const_int 0)))
11205    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11206         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11207   "ix86_match_ccmode (insn, CCGOCmode)
11208    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11209   "sar{l}\t{%2, %0|%0, %2}"
11210   [(set_attr "type" "ishift")
11211    (set_attr "mode" "SI")])
11212
11213 (define_insn "*ashrsi3_cmp_zext"
11214   [(set (reg FLAGS_REG)
11215         (compare
11216           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11217                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11218           (const_int 0)))
11219    (set (match_operand:DI 0 "register_operand" "=r")
11220         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11221   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11222    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11223   "sar{l}\t{%2, %k0|%k0, %2}"
11224   [(set_attr "type" "ishift")
11225    (set_attr "mode" "SI")])
11226
11227 (define_expand "ashrhi3"
11228   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11229         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11230                      (match_operand:QI 2 "nonmemory_operand" "")))
11231    (clobber (reg:CC FLAGS_REG))]
11232   "TARGET_HIMODE_MATH"
11233   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11234
11235 (define_insn "*ashrhi3_1_one_bit"
11236   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11237         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11238                      (match_operand:QI 2 "const1_operand" "")))
11239    (clobber (reg:CC FLAGS_REG))]
11240   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11241    && (TARGET_SHIFT1 || optimize_size)"
11242   "sar{w}\t%0"
11243   [(set_attr "type" "ishift")
11244    (set (attr "length") 
11245      (if_then_else (match_operand 0 "register_operand" "") 
11246         (const_string "2")
11247         (const_string "*")))])
11248
11249 (define_insn "*ashrhi3_1"
11250   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11251         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11252                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11253    (clobber (reg:CC FLAGS_REG))]
11254   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11255   "@
11256    sar{w}\t{%2, %0|%0, %2}
11257    sar{w}\t{%b2, %0|%0, %b2}"
11258   [(set_attr "type" "ishift")
11259    (set_attr "mode" "HI")])
11260
11261 ;; This pattern can't accept a variable shift count, since shifts by
11262 ;; zero don't affect the flags.  We assume that shifts by constant
11263 ;; zero are optimized away.
11264 (define_insn "*ashrhi3_one_bit_cmp"
11265   [(set (reg FLAGS_REG)
11266         (compare
11267           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11268                        (match_operand:QI 2 "const1_operand" ""))
11269           (const_int 0)))
11270    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11271         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11272   "ix86_match_ccmode (insn, CCGOCmode)
11273    && (TARGET_SHIFT1 || optimize_size)
11274    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11275   "sar{w}\t%0"
11276   [(set_attr "type" "ishift")
11277    (set (attr "length") 
11278      (if_then_else (match_operand 0 "register_operand" "") 
11279         (const_string "2")
11280         (const_string "*")))])
11281
11282 ;; This pattern can't accept a variable shift count, since shifts by
11283 ;; zero don't affect the flags.  We assume that shifts by constant
11284 ;; zero are optimized away.
11285 (define_insn "*ashrhi3_cmp"
11286   [(set (reg FLAGS_REG)
11287         (compare
11288           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11289                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11290           (const_int 0)))
11291    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11292         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11293   "ix86_match_ccmode (insn, CCGOCmode)
11294    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11295   "sar{w}\t{%2, %0|%0, %2}"
11296   [(set_attr "type" "ishift")
11297    (set_attr "mode" "HI")])
11298
11299 (define_expand "ashrqi3"
11300   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11301         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11302                      (match_operand:QI 2 "nonmemory_operand" "")))
11303    (clobber (reg:CC FLAGS_REG))]
11304   "TARGET_QIMODE_MATH"
11305   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11306
11307 (define_insn "*ashrqi3_1_one_bit"
11308   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11309         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11310                      (match_operand:QI 2 "const1_operand" "")))
11311    (clobber (reg:CC FLAGS_REG))]
11312   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11313    && (TARGET_SHIFT1 || optimize_size)"
11314   "sar{b}\t%0"
11315   [(set_attr "type" "ishift")
11316    (set (attr "length") 
11317      (if_then_else (match_operand 0 "register_operand" "") 
11318         (const_string "2")
11319         (const_string "*")))])
11320
11321 (define_insn "*ashrqi3_1_one_bit_slp"
11322   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11323         (ashiftrt:QI (match_dup 0)
11324                      (match_operand:QI 1 "const1_operand" "")))
11325    (clobber (reg:CC FLAGS_REG))]
11326   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11327    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11328    && (TARGET_SHIFT1 || optimize_size)"
11329   "sar{b}\t%0"
11330   [(set_attr "type" "ishift1")
11331    (set (attr "length") 
11332      (if_then_else (match_operand 0 "register_operand" "") 
11333         (const_string "2")
11334         (const_string "*")))])
11335
11336 (define_insn "*ashrqi3_1"
11337   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11338         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11339                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11340    (clobber (reg:CC FLAGS_REG))]
11341   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11342   "@
11343    sar{b}\t{%2, %0|%0, %2}
11344    sar{b}\t{%b2, %0|%0, %b2}"
11345   [(set_attr "type" "ishift")
11346    (set_attr "mode" "QI")])
11347
11348 (define_insn "*ashrqi3_1_slp"
11349   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11350         (ashiftrt:QI (match_dup 0)
11351                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11352    (clobber (reg:CC FLAGS_REG))]
11353   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11354    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11355   "@
11356    sar{b}\t{%1, %0|%0, %1}
11357    sar{b}\t{%b1, %0|%0, %b1}"
11358   [(set_attr "type" "ishift1")
11359    (set_attr "mode" "QI")])
11360
11361 ;; This pattern can't accept a variable shift count, since shifts by
11362 ;; zero don't affect the flags.  We assume that shifts by constant
11363 ;; zero are optimized away.
11364 (define_insn "*ashrqi3_one_bit_cmp"
11365   [(set (reg FLAGS_REG)
11366         (compare
11367           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11368                        (match_operand:QI 2 "const1_operand" "I"))
11369           (const_int 0)))
11370    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11371         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11372   "ix86_match_ccmode (insn, CCGOCmode)
11373    && (TARGET_SHIFT1 || optimize_size)
11374    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11375   "sar{b}\t%0"
11376   [(set_attr "type" "ishift")
11377    (set (attr "length") 
11378      (if_then_else (match_operand 0 "register_operand" "") 
11379         (const_string "2")
11380         (const_string "*")))])
11381
11382 ;; This pattern can't accept a variable shift count, since shifts by
11383 ;; zero don't affect the flags.  We assume that shifts by constant
11384 ;; zero are optimized away.
11385 (define_insn "*ashrqi3_cmp"
11386   [(set (reg FLAGS_REG)
11387         (compare
11388           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11389                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11390           (const_int 0)))
11391    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11392         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11393   "ix86_match_ccmode (insn, CCGOCmode)
11394    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11395   "sar{b}\t{%2, %0|%0, %2}"
11396   [(set_attr "type" "ishift")
11397    (set_attr "mode" "QI")])
11398 \f
11399 ;; Logical shift instructions
11400
11401 ;; See comment above `ashldi3' about how this works.
11402
11403 (define_expand "lshrdi3"
11404   [(set (match_operand:DI 0 "shiftdi_operand" "")
11405         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11406                      (match_operand:QI 2 "nonmemory_operand" "")))]
11407   ""
11408   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11409
11410 (define_insn "*lshrdi3_1_one_bit_rex64"
11411   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11412         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11413                      (match_operand:QI 2 "const1_operand" "")))
11414    (clobber (reg:CC FLAGS_REG))]
11415   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11416    && (TARGET_SHIFT1 || optimize_size)"
11417   "shr{q}\t%0"
11418   [(set_attr "type" "ishift")
11419    (set (attr "length") 
11420      (if_then_else (match_operand:DI 0 "register_operand" "") 
11421         (const_string "2")
11422         (const_string "*")))])
11423
11424 (define_insn "*lshrdi3_1_rex64"
11425   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11426         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11427                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11428    (clobber (reg:CC FLAGS_REG))]
11429   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11430   "@
11431    shr{q}\t{%2, %0|%0, %2}
11432    shr{q}\t{%b2, %0|%0, %b2}"
11433   [(set_attr "type" "ishift")
11434    (set_attr "mode" "DI")])
11435
11436 ;; This pattern can't accept a variable shift count, since shifts by
11437 ;; zero don't affect the flags.  We assume that shifts by constant
11438 ;; zero are optimized away.
11439 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11440   [(set (reg FLAGS_REG)
11441         (compare
11442           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11443                        (match_operand:QI 2 "const1_operand" ""))
11444           (const_int 0)))
11445    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11446         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11447   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11448    && (TARGET_SHIFT1 || optimize_size)
11449    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11450   "shr{q}\t%0"
11451   [(set_attr "type" "ishift")
11452    (set (attr "length") 
11453      (if_then_else (match_operand:DI 0 "register_operand" "") 
11454         (const_string "2")
11455         (const_string "*")))])
11456
11457 ;; This pattern can't accept a variable shift count, since shifts by
11458 ;; zero don't affect the flags.  We assume that shifts by constant
11459 ;; zero are optimized away.
11460 (define_insn "*lshrdi3_cmp_rex64"
11461   [(set (reg FLAGS_REG)
11462         (compare
11463           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11464                        (match_operand:QI 2 "const_int_operand" "e"))
11465           (const_int 0)))
11466    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11467         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11468   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11469    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11470   "shr{q}\t{%2, %0|%0, %2}"
11471   [(set_attr "type" "ishift")
11472    (set_attr "mode" "DI")])
11473
11474 (define_insn "*lshrdi3_1"
11475   [(set (match_operand:DI 0 "register_operand" "=r")
11476         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11477                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11478    (clobber (reg:CC FLAGS_REG))]
11479   "!TARGET_64BIT"
11480   "#"
11481   [(set_attr "type" "multi")])
11482
11483 ;; By default we don't ask for a scratch register, because when DImode
11484 ;; values are manipulated, registers are already at a premium.  But if
11485 ;; we have one handy, we won't turn it away.
11486 (define_peephole2
11487   [(match_scratch:SI 3 "r")
11488    (parallel [(set (match_operand:DI 0 "register_operand" "")
11489                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11490                                 (match_operand:QI 2 "nonmemory_operand" "")))
11491               (clobber (reg:CC FLAGS_REG))])
11492    (match_dup 3)]
11493   "!TARGET_64BIT && TARGET_CMOVE"
11494   [(const_int 0)]
11495   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11496
11497 (define_split 
11498   [(set (match_operand:DI 0 "register_operand" "")
11499         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11500                      (match_operand:QI 2 "nonmemory_operand" "")))
11501    (clobber (reg:CC FLAGS_REG))]
11502   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11503   [(const_int 0)]
11504   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11505
11506 (define_expand "lshrsi3"
11507   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11508         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11509                      (match_operand:QI 2 "nonmemory_operand" "")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   ""
11512   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11513
11514 (define_insn "*lshrsi3_1_one_bit"
11515   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11516         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11517                      (match_operand:QI 2 "const1_operand" "")))
11518    (clobber (reg:CC FLAGS_REG))]
11519   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11520    && (TARGET_SHIFT1 || optimize_size)"
11521   "shr{l}\t%0"
11522   [(set_attr "type" "ishift")
11523    (set (attr "length") 
11524      (if_then_else (match_operand:SI 0 "register_operand" "") 
11525         (const_string "2")
11526         (const_string "*")))])
11527
11528 (define_insn "*lshrsi3_1_one_bit_zext"
11529   [(set (match_operand:DI 0 "register_operand" "=r")
11530         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11531                      (match_operand:QI 2 "const1_operand" "")))
11532    (clobber (reg:CC FLAGS_REG))]
11533   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11534    && (TARGET_SHIFT1 || optimize_size)"
11535   "shr{l}\t%k0"
11536   [(set_attr "type" "ishift")
11537    (set_attr "length" "2")])
11538
11539 (define_insn "*lshrsi3_1"
11540   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11541         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11542                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11543    (clobber (reg:CC FLAGS_REG))]
11544   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11545   "@
11546    shr{l}\t{%2, %0|%0, %2}
11547    shr{l}\t{%b2, %0|%0, %b2}"
11548   [(set_attr "type" "ishift")
11549    (set_attr "mode" "SI")])
11550
11551 (define_insn "*lshrsi3_1_zext"
11552   [(set (match_operand:DI 0 "register_operand" "=r,r")
11553         (zero_extend:DI
11554           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11555                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11558   "@
11559    shr{l}\t{%2, %k0|%k0, %2}
11560    shr{l}\t{%b2, %k0|%k0, %b2}"
11561   [(set_attr "type" "ishift")
11562    (set_attr "mode" "SI")])
11563
11564 ;; This pattern can't accept a variable shift count, since shifts by
11565 ;; zero don't affect the flags.  We assume that shifts by constant
11566 ;; zero are optimized away.
11567 (define_insn "*lshrsi3_one_bit_cmp"
11568   [(set (reg FLAGS_REG)
11569         (compare
11570           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11571                        (match_operand:QI 2 "const1_operand" ""))
11572           (const_int 0)))
11573    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11574         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11575   "ix86_match_ccmode (insn, CCGOCmode)
11576    && (TARGET_SHIFT1 || optimize_size)
11577    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11578   "shr{l}\t%0"
11579   [(set_attr "type" "ishift")
11580    (set (attr "length") 
11581      (if_then_else (match_operand:SI 0 "register_operand" "") 
11582         (const_string "2")
11583         (const_string "*")))])
11584
11585 (define_insn "*lshrsi3_cmp_one_bit_zext"
11586   [(set (reg FLAGS_REG)
11587         (compare
11588           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11589                        (match_operand:QI 2 "const1_operand" ""))
11590           (const_int 0)))
11591    (set (match_operand:DI 0 "register_operand" "=r")
11592         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11593   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11594    && (TARGET_SHIFT1 || optimize_size)
11595    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11596   "shr{l}\t%k0"
11597   [(set_attr "type" "ishift")
11598    (set_attr "length" "2")])
11599
11600 ;; This pattern can't accept a variable shift count, since shifts by
11601 ;; zero don't affect the flags.  We assume that shifts by constant
11602 ;; zero are optimized away.
11603 (define_insn "*lshrsi3_cmp"
11604   [(set (reg FLAGS_REG)
11605         (compare
11606           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11607                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11608           (const_int 0)))
11609    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11610         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11611   "ix86_match_ccmode (insn, CCGOCmode)
11612    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11613   "shr{l}\t{%2, %0|%0, %2}"
11614   [(set_attr "type" "ishift")
11615    (set_attr "mode" "SI")])
11616
11617 (define_insn "*lshrsi3_cmp_zext"
11618   [(set (reg FLAGS_REG)
11619         (compare
11620           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11621                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11622           (const_int 0)))
11623    (set (match_operand:DI 0 "register_operand" "=r")
11624         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11625   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11626    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11627   "shr{l}\t{%2, %k0|%k0, %2}"
11628   [(set_attr "type" "ishift")
11629    (set_attr "mode" "SI")])
11630
11631 (define_expand "lshrhi3"
11632   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11633         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11634                      (match_operand:QI 2 "nonmemory_operand" "")))
11635    (clobber (reg:CC FLAGS_REG))]
11636   "TARGET_HIMODE_MATH"
11637   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11638
11639 (define_insn "*lshrhi3_1_one_bit"
11640   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11641         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11642                      (match_operand:QI 2 "const1_operand" "")))
11643    (clobber (reg:CC FLAGS_REG))]
11644   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11645    && (TARGET_SHIFT1 || optimize_size)"
11646   "shr{w}\t%0"
11647   [(set_attr "type" "ishift")
11648    (set (attr "length") 
11649      (if_then_else (match_operand 0 "register_operand" "") 
11650         (const_string "2")
11651         (const_string "*")))])
11652
11653 (define_insn "*lshrhi3_1"
11654   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11655         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11656                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11657    (clobber (reg:CC FLAGS_REG))]
11658   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11659   "@
11660    shr{w}\t{%2, %0|%0, %2}
11661    shr{w}\t{%b2, %0|%0, %b2}"
11662   [(set_attr "type" "ishift")
11663    (set_attr "mode" "HI")])
11664
11665 ;; This pattern can't accept a variable shift count, since shifts by
11666 ;; zero don't affect the flags.  We assume that shifts by constant
11667 ;; zero are optimized away.
11668 (define_insn "*lshrhi3_one_bit_cmp"
11669   [(set (reg FLAGS_REG)
11670         (compare
11671           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11672                        (match_operand:QI 2 "const1_operand" ""))
11673           (const_int 0)))
11674    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11675         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11676   "ix86_match_ccmode (insn, CCGOCmode)
11677    && (TARGET_SHIFT1 || optimize_size)
11678    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11679   "shr{w}\t%0"
11680   [(set_attr "type" "ishift")
11681    (set (attr "length") 
11682      (if_then_else (match_operand:SI 0 "register_operand" "") 
11683         (const_string "2")
11684         (const_string "*")))])
11685
11686 ;; This pattern can't accept a variable shift count, since shifts by
11687 ;; zero don't affect the flags.  We assume that shifts by constant
11688 ;; zero are optimized away.
11689 (define_insn "*lshrhi3_cmp"
11690   [(set (reg FLAGS_REG)
11691         (compare
11692           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11693                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11694           (const_int 0)))
11695    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11696         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11697   "ix86_match_ccmode (insn, CCGOCmode)
11698    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11699   "shr{w}\t{%2, %0|%0, %2}"
11700   [(set_attr "type" "ishift")
11701    (set_attr "mode" "HI")])
11702
11703 (define_expand "lshrqi3"
11704   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11705         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11706                      (match_operand:QI 2 "nonmemory_operand" "")))
11707    (clobber (reg:CC FLAGS_REG))]
11708   "TARGET_QIMODE_MATH"
11709   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11710
11711 (define_insn "*lshrqi3_1_one_bit"
11712   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11713         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11714                      (match_operand:QI 2 "const1_operand" "")))
11715    (clobber (reg:CC FLAGS_REG))]
11716   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11717    && (TARGET_SHIFT1 || optimize_size)"
11718   "shr{b}\t%0"
11719   [(set_attr "type" "ishift")
11720    (set (attr "length") 
11721      (if_then_else (match_operand 0 "register_operand" "") 
11722         (const_string "2")
11723         (const_string "*")))])
11724
11725 (define_insn "*lshrqi3_1_one_bit_slp"
11726   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11727         (lshiftrt:QI (match_dup 0)
11728                      (match_operand:QI 1 "const1_operand" "")))
11729    (clobber (reg:CC FLAGS_REG))]
11730   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11731    && (TARGET_SHIFT1 || optimize_size)"
11732   "shr{b}\t%0"
11733   [(set_attr "type" "ishift1")
11734    (set (attr "length") 
11735      (if_then_else (match_operand 0 "register_operand" "") 
11736         (const_string "2")
11737         (const_string "*")))])
11738
11739 (define_insn "*lshrqi3_1"
11740   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11741         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11742                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11743    (clobber (reg:CC FLAGS_REG))]
11744   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11745   "@
11746    shr{b}\t{%2, %0|%0, %2}
11747    shr{b}\t{%b2, %0|%0, %b2}"
11748   [(set_attr "type" "ishift")
11749    (set_attr "mode" "QI")])
11750
11751 (define_insn "*lshrqi3_1_slp"
11752   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11753         (lshiftrt:QI (match_dup 0)
11754                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11755    (clobber (reg:CC FLAGS_REG))]
11756   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11757    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11758   "@
11759    shr{b}\t{%1, %0|%0, %1}
11760    shr{b}\t{%b1, %0|%0, %b1}"
11761   [(set_attr "type" "ishift1")
11762    (set_attr "mode" "QI")])
11763
11764 ;; This pattern can't accept a variable shift count, since shifts by
11765 ;; zero don't affect the flags.  We assume that shifts by constant
11766 ;; zero are optimized away.
11767 (define_insn "*lshrqi2_one_bit_cmp"
11768   [(set (reg FLAGS_REG)
11769         (compare
11770           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11771                        (match_operand:QI 2 "const1_operand" ""))
11772           (const_int 0)))
11773    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11774         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11775   "ix86_match_ccmode (insn, CCGOCmode)
11776    && (TARGET_SHIFT1 || optimize_size)
11777    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11778   "shr{b}\t%0"
11779   [(set_attr "type" "ishift")
11780    (set (attr "length") 
11781      (if_then_else (match_operand:SI 0 "register_operand" "") 
11782         (const_string "2")
11783         (const_string "*")))])
11784
11785 ;; This pattern can't accept a variable shift count, since shifts by
11786 ;; zero don't affect the flags.  We assume that shifts by constant
11787 ;; zero are optimized away.
11788 (define_insn "*lshrqi2_cmp"
11789   [(set (reg FLAGS_REG)
11790         (compare
11791           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11792                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11793           (const_int 0)))
11794    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11795         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11796   "ix86_match_ccmode (insn, CCGOCmode)
11797    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11798   "shr{b}\t{%2, %0|%0, %2}"
11799   [(set_attr "type" "ishift")
11800    (set_attr "mode" "QI")])
11801 \f
11802 ;; Rotate instructions
11803
11804 (define_expand "rotldi3"
11805   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11806         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11807                    (match_operand:QI 2 "nonmemory_operand" "")))
11808    (clobber (reg:CC FLAGS_REG))]
11809   "TARGET_64BIT"
11810   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11811
11812 (define_insn "*rotlsi3_1_one_bit_rex64"
11813   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11814         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11815                    (match_operand:QI 2 "const1_operand" "")))
11816    (clobber (reg:CC FLAGS_REG))]
11817   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11818    && (TARGET_SHIFT1 || optimize_size)"
11819   "rol{q}\t%0"
11820   [(set_attr "type" "rotate")
11821    (set (attr "length") 
11822      (if_then_else (match_operand:DI 0 "register_operand" "") 
11823         (const_string "2")
11824         (const_string "*")))])
11825
11826 (define_insn "*rotldi3_1_rex64"
11827   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11828         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11829                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11830    (clobber (reg:CC FLAGS_REG))]
11831   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11832   "@
11833    rol{q}\t{%2, %0|%0, %2}
11834    rol{q}\t{%b2, %0|%0, %b2}"
11835   [(set_attr "type" "rotate")
11836    (set_attr "mode" "DI")])
11837
11838 (define_expand "rotlsi3"
11839   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11840         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11841                    (match_operand:QI 2 "nonmemory_operand" "")))
11842    (clobber (reg:CC FLAGS_REG))]
11843   ""
11844   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11845
11846 (define_insn "*rotlsi3_1_one_bit"
11847   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11848         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11849                    (match_operand:QI 2 "const1_operand" "")))
11850    (clobber (reg:CC FLAGS_REG))]
11851   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11852    && (TARGET_SHIFT1 || optimize_size)"
11853   "rol{l}\t%0"
11854   [(set_attr "type" "rotate")
11855    (set (attr "length") 
11856      (if_then_else (match_operand:SI 0 "register_operand" "") 
11857         (const_string "2")
11858         (const_string "*")))])
11859
11860 (define_insn "*rotlsi3_1_one_bit_zext"
11861   [(set (match_operand:DI 0 "register_operand" "=r")
11862         (zero_extend:DI
11863           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11864                      (match_operand:QI 2 "const1_operand" ""))))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11867    && (TARGET_SHIFT1 || optimize_size)"
11868   "rol{l}\t%k0"
11869   [(set_attr "type" "rotate")
11870    (set_attr "length" "2")])
11871
11872 (define_insn "*rotlsi3_1"
11873   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11874         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11875                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11876    (clobber (reg:CC FLAGS_REG))]
11877   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11878   "@
11879    rol{l}\t{%2, %0|%0, %2}
11880    rol{l}\t{%b2, %0|%0, %b2}"
11881   [(set_attr "type" "rotate")
11882    (set_attr "mode" "SI")])
11883
11884 (define_insn "*rotlsi3_1_zext"
11885   [(set (match_operand:DI 0 "register_operand" "=r,r")
11886         (zero_extend:DI
11887           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11888                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11889    (clobber (reg:CC FLAGS_REG))]
11890   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11891   "@
11892    rol{l}\t{%2, %k0|%k0, %2}
11893    rol{l}\t{%b2, %k0|%k0, %b2}"
11894   [(set_attr "type" "rotate")
11895    (set_attr "mode" "SI")])
11896
11897 (define_expand "rotlhi3"
11898   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11899         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11900                    (match_operand:QI 2 "nonmemory_operand" "")))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "TARGET_HIMODE_MATH"
11903   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11904
11905 (define_insn "*rotlhi3_1_one_bit"
11906   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11907         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11908                    (match_operand:QI 2 "const1_operand" "")))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11911    && (TARGET_SHIFT1 || optimize_size)"
11912   "rol{w}\t%0"
11913   [(set_attr "type" "rotate")
11914    (set (attr "length") 
11915      (if_then_else (match_operand 0 "register_operand" "") 
11916         (const_string "2")
11917         (const_string "*")))])
11918
11919 (define_insn "*rotlhi3_1"
11920   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11921         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11922                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11923    (clobber (reg:CC FLAGS_REG))]
11924   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11925   "@
11926    rol{w}\t{%2, %0|%0, %2}
11927    rol{w}\t{%b2, %0|%0, %b2}"
11928   [(set_attr "type" "rotate")
11929    (set_attr "mode" "HI")])
11930
11931 (define_expand "rotlqi3"
11932   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11933         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11934                    (match_operand:QI 2 "nonmemory_operand" "")))
11935    (clobber (reg:CC FLAGS_REG))]
11936   "TARGET_QIMODE_MATH"
11937   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11938
11939 (define_insn "*rotlqi3_1_one_bit_slp"
11940   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11941         (rotate:QI (match_dup 0)
11942                    (match_operand:QI 1 "const1_operand" "")))
11943    (clobber (reg:CC FLAGS_REG))]
11944   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11945    && (TARGET_SHIFT1 || optimize_size)"
11946   "rol{b}\t%0"
11947   [(set_attr "type" "rotate1")
11948    (set (attr "length") 
11949      (if_then_else (match_operand 0 "register_operand" "") 
11950         (const_string "2")
11951         (const_string "*")))])
11952
11953 (define_insn "*rotlqi3_1_one_bit"
11954   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11955         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11956                    (match_operand:QI 2 "const1_operand" "")))
11957    (clobber (reg:CC FLAGS_REG))]
11958   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11959    && (TARGET_SHIFT1 || optimize_size)"
11960   "rol{b}\t%0"
11961   [(set_attr "type" "rotate")
11962    (set (attr "length") 
11963      (if_then_else (match_operand 0 "register_operand" "") 
11964         (const_string "2")
11965         (const_string "*")))])
11966
11967 (define_insn "*rotlqi3_1_slp"
11968   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11969         (rotate:QI (match_dup 0)
11970                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11971    (clobber (reg:CC FLAGS_REG))]
11972   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11973    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11974   "@
11975    rol{b}\t{%1, %0|%0, %1}
11976    rol{b}\t{%b1, %0|%0, %b1}"
11977   [(set_attr "type" "rotate1")
11978    (set_attr "mode" "QI")])
11979
11980 (define_insn "*rotlqi3_1"
11981   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11982         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11983                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11984    (clobber (reg:CC FLAGS_REG))]
11985   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11986   "@
11987    rol{b}\t{%2, %0|%0, %2}
11988    rol{b}\t{%b2, %0|%0, %b2}"
11989   [(set_attr "type" "rotate")
11990    (set_attr "mode" "QI")])
11991
11992 (define_expand "rotrdi3"
11993   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11994         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11995                      (match_operand:QI 2 "nonmemory_operand" "")))
11996    (clobber (reg:CC FLAGS_REG))]
11997   "TARGET_64BIT"
11998   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11999
12000 (define_insn "*rotrdi3_1_one_bit_rex64"
12001   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12002         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12003                      (match_operand:QI 2 "const1_operand" "")))
12004    (clobber (reg:CC FLAGS_REG))]
12005   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12006    && (TARGET_SHIFT1 || optimize_size)"
12007   "ror{q}\t%0"
12008   [(set_attr "type" "rotate")
12009    (set (attr "length") 
12010      (if_then_else (match_operand:DI 0 "register_operand" "") 
12011         (const_string "2")
12012         (const_string "*")))])
12013
12014 (define_insn "*rotrdi3_1_rex64"
12015   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12016         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12017                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12018    (clobber (reg:CC FLAGS_REG))]
12019   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12020   "@
12021    ror{q}\t{%2, %0|%0, %2}
12022    ror{q}\t{%b2, %0|%0, %b2}"
12023   [(set_attr "type" "rotate")
12024    (set_attr "mode" "DI")])
12025
12026 (define_expand "rotrsi3"
12027   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12028         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12029                      (match_operand:QI 2 "nonmemory_operand" "")))
12030    (clobber (reg:CC FLAGS_REG))]
12031   ""
12032   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12033
12034 (define_insn "*rotrsi3_1_one_bit"
12035   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12036         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12037                      (match_operand:QI 2 "const1_operand" "")))
12038    (clobber (reg:CC FLAGS_REG))]
12039   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12040    && (TARGET_SHIFT1 || optimize_size)"
12041   "ror{l}\t%0"
12042   [(set_attr "type" "rotate")
12043    (set (attr "length") 
12044      (if_then_else (match_operand:SI 0 "register_operand" "") 
12045         (const_string "2")
12046         (const_string "*")))])
12047
12048 (define_insn "*rotrsi3_1_one_bit_zext"
12049   [(set (match_operand:DI 0 "register_operand" "=r")
12050         (zero_extend:DI
12051           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12052                        (match_operand:QI 2 "const1_operand" ""))))
12053    (clobber (reg:CC FLAGS_REG))]
12054   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12055    && (TARGET_SHIFT1 || optimize_size)"
12056   "ror{l}\t%k0"
12057   [(set_attr "type" "rotate")
12058    (set (attr "length") 
12059      (if_then_else (match_operand:SI 0 "register_operand" "") 
12060         (const_string "2")
12061         (const_string "*")))])
12062
12063 (define_insn "*rotrsi3_1"
12064   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12065         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12066                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12069   "@
12070    ror{l}\t{%2, %0|%0, %2}
12071    ror{l}\t{%b2, %0|%0, %b2}"
12072   [(set_attr "type" "rotate")
12073    (set_attr "mode" "SI")])
12074
12075 (define_insn "*rotrsi3_1_zext"
12076   [(set (match_operand:DI 0 "register_operand" "=r,r")
12077         (zero_extend:DI
12078           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12079                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12080    (clobber (reg:CC FLAGS_REG))]
12081   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12082   "@
12083    ror{l}\t{%2, %k0|%k0, %2}
12084    ror{l}\t{%b2, %k0|%k0, %b2}"
12085   [(set_attr "type" "rotate")
12086    (set_attr "mode" "SI")])
12087
12088 (define_expand "rotrhi3"
12089   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12090         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12091                      (match_operand:QI 2 "nonmemory_operand" "")))
12092    (clobber (reg:CC FLAGS_REG))]
12093   "TARGET_HIMODE_MATH"
12094   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12095
12096 (define_insn "*rotrhi3_one_bit"
12097   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12098         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12099                      (match_operand:QI 2 "const1_operand" "")))
12100    (clobber (reg:CC FLAGS_REG))]
12101   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12102    && (TARGET_SHIFT1 || optimize_size)"
12103   "ror{w}\t%0"
12104   [(set_attr "type" "rotate")
12105    (set (attr "length") 
12106      (if_then_else (match_operand 0 "register_operand" "") 
12107         (const_string "2")
12108         (const_string "*")))])
12109
12110 (define_insn "*rotrhi3"
12111   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12112         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12113                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12114    (clobber (reg:CC FLAGS_REG))]
12115   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12116   "@
12117    ror{w}\t{%2, %0|%0, %2}
12118    ror{w}\t{%b2, %0|%0, %b2}"
12119   [(set_attr "type" "rotate")
12120    (set_attr "mode" "HI")])
12121
12122 (define_expand "rotrqi3"
12123   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12124         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12125                      (match_operand:QI 2 "nonmemory_operand" "")))
12126    (clobber (reg:CC FLAGS_REG))]
12127   "TARGET_QIMODE_MATH"
12128   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12129
12130 (define_insn "*rotrqi3_1_one_bit"
12131   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12132         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12133                      (match_operand:QI 2 "const1_operand" "")))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12136    && (TARGET_SHIFT1 || optimize_size)"
12137   "ror{b}\t%0"
12138   [(set_attr "type" "rotate")
12139    (set (attr "length") 
12140      (if_then_else (match_operand 0 "register_operand" "") 
12141         (const_string "2")
12142         (const_string "*")))])
12143
12144 (define_insn "*rotrqi3_1_one_bit_slp"
12145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12146         (rotatert:QI (match_dup 0)
12147                      (match_operand:QI 1 "const1_operand" "")))
12148    (clobber (reg:CC FLAGS_REG))]
12149   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12150    && (TARGET_SHIFT1 || optimize_size)"
12151   "ror{b}\t%0"
12152   [(set_attr "type" "rotate1")
12153    (set (attr "length") 
12154      (if_then_else (match_operand 0 "register_operand" "") 
12155         (const_string "2")
12156         (const_string "*")))])
12157
12158 (define_insn "*rotrqi3_1"
12159   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12160         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12161                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12164   "@
12165    ror{b}\t{%2, %0|%0, %2}
12166    ror{b}\t{%b2, %0|%0, %b2}"
12167   [(set_attr "type" "rotate")
12168    (set_attr "mode" "QI")])
12169
12170 (define_insn "*rotrqi3_1_slp"
12171   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12172         (rotatert:QI (match_dup 0)
12173                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12174    (clobber (reg:CC FLAGS_REG))]
12175   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12176    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12177   "@
12178    ror{b}\t{%1, %0|%0, %1}
12179    ror{b}\t{%b1, %0|%0, %b1}"
12180   [(set_attr "type" "rotate1")
12181    (set_attr "mode" "QI")])
12182 \f
12183 ;; Bit set / bit test instructions
12184
12185 (define_expand "extv"
12186   [(set (match_operand:SI 0 "register_operand" "")
12187         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12188                          (match_operand:SI 2 "immediate_operand" "")
12189                          (match_operand:SI 3 "immediate_operand" "")))]
12190   ""
12191 {
12192   /* Handle extractions from %ah et al.  */
12193   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12194     FAIL;
12195
12196   /* From mips.md: extract_bit_field doesn't verify that our source
12197      matches the predicate, so check it again here.  */
12198   if (! register_operand (operands[1], VOIDmode))
12199     FAIL;
12200 })
12201
12202 (define_expand "extzv"
12203   [(set (match_operand:SI 0 "register_operand" "")
12204         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12205                          (match_operand:SI 2 "immediate_operand" "")
12206                          (match_operand:SI 3 "immediate_operand" "")))]
12207   ""
12208 {
12209   /* Handle extractions from %ah et al.  */
12210   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12211     FAIL;
12212
12213   /* From mips.md: extract_bit_field doesn't verify that our source
12214      matches the predicate, so check it again here.  */
12215   if (! register_operand (operands[1], VOIDmode))
12216     FAIL;
12217 })
12218
12219 (define_expand "insv"
12220   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12221                       (match_operand 1 "immediate_operand" "")
12222                       (match_operand 2 "immediate_operand" ""))
12223         (match_operand 3 "register_operand" ""))]
12224   ""
12225 {
12226   /* Handle extractions from %ah et al.  */
12227   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12228     FAIL;
12229
12230   /* From mips.md: insert_bit_field doesn't verify that our source
12231      matches the predicate, so check it again here.  */
12232   if (! register_operand (operands[0], VOIDmode))
12233     FAIL;
12234
12235   if (TARGET_64BIT)
12236     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12237   else
12238     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12239
12240   DONE;
12241 })
12242
12243 ;; %%% bts, btr, btc, bt.
12244 ;; In general these instructions are *slow* when applied to memory,
12245 ;; since they enforce atomic operation.  When applied to registers,
12246 ;; it depends on the cpu implementation.  They're never faster than
12247 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12248 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12249 ;; within the instruction itself, so operating on bits in the high
12250 ;; 32-bits of a register becomes easier.
12251 ;;
12252 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12253 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12254 ;; negdf respectively, so they can never be disabled entirely.
12255
12256 (define_insn "*btsq"
12257   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12258                          (const_int 1)
12259                          (match_operand 1 "const_0_to_63_operand" ""))
12260         (const_int 1))
12261    (clobber (reg:CC FLAGS_REG))]
12262   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12263   "bts{q} %1,%0"
12264   [(set_attr "type" "alu1")])
12265
12266 (define_insn "*btrq"
12267   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12268                          (const_int 1)
12269                          (match_operand 1 "const_0_to_63_operand" ""))
12270         (const_int 0))
12271    (clobber (reg:CC FLAGS_REG))]
12272   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12273   "btr{q} %1,%0"
12274   [(set_attr "type" "alu1")])
12275
12276 (define_insn "*btcq"
12277   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12278                          (const_int 1)
12279                          (match_operand 1 "const_0_to_63_operand" ""))
12280         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12281    (clobber (reg:CC FLAGS_REG))]
12282   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12283   "btc{q} %1,%0"
12284   [(set_attr "type" "alu1")])
12285
12286 ;; Allow Nocona to avoid these instructions if a register is available.
12287
12288 (define_peephole2
12289   [(match_scratch:DI 2 "r")
12290    (parallel [(set (zero_extract:DI
12291                      (match_operand 0 "register_operand" "")
12292                      (const_int 1)
12293                      (match_operand 1 "const_0_to_63_operand" ""))
12294                    (const_int 1))
12295               (clobber (reg:CC FLAGS_REG))])]
12296   "TARGET_64BIT && !TARGET_USE_BT"
12297   [(const_int 0)]
12298 {
12299   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12300   rtx op1;
12301
12302   if (HOST_BITS_PER_WIDE_INT >= 64)
12303     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12304   else if (i < HOST_BITS_PER_WIDE_INT)
12305     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12306   else
12307     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12308
12309   op1 = immed_double_const (lo, hi, DImode);
12310   if (i >= 31)
12311     {
12312       emit_move_insn (operands[2], op1);
12313       op1 = operands[2];
12314     }
12315
12316   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12317   DONE;
12318 })
12319
12320 (define_peephole2
12321   [(match_scratch:DI 2 "r")
12322    (parallel [(set (zero_extract:DI
12323                      (match_operand 0 "register_operand" "")
12324                      (const_int 1)
12325                      (match_operand 1 "const_0_to_63_operand" ""))
12326                    (const_int 0))
12327               (clobber (reg:CC FLAGS_REG))])]
12328   "TARGET_64BIT && !TARGET_USE_BT"
12329   [(const_int 0)]
12330 {
12331   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12332   rtx op1;
12333
12334   if (HOST_BITS_PER_WIDE_INT >= 64)
12335     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12336   else if (i < HOST_BITS_PER_WIDE_INT)
12337     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12338   else
12339     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12340
12341   op1 = immed_double_const (~lo, ~hi, DImode);
12342   if (i >= 32)
12343     {
12344       emit_move_insn (operands[2], op1);
12345       op1 = operands[2];
12346     }
12347
12348   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12349   DONE;
12350 })
12351
12352 (define_peephole2
12353   [(match_scratch:DI 2 "r")
12354    (parallel [(set (zero_extract:DI
12355                      (match_operand 0 "register_operand" "")
12356                      (const_int 1)
12357                      (match_operand 1 "const_0_to_63_operand" ""))
12358               (not:DI (zero_extract:DI
12359                         (match_dup 0) (const_int 1) (match_dup 1))))
12360               (clobber (reg:CC FLAGS_REG))])]
12361   "TARGET_64BIT && !TARGET_USE_BT"
12362   [(const_int 0)]
12363 {
12364   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12365   rtx op1;
12366
12367   if (HOST_BITS_PER_WIDE_INT >= 64)
12368     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12369   else if (i < HOST_BITS_PER_WIDE_INT)
12370     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12371   else
12372     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12373
12374   op1 = immed_double_const (lo, hi, DImode);
12375   if (i >= 31)
12376     {
12377       emit_move_insn (operands[2], op1);
12378       op1 = operands[2];
12379     }
12380
12381   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12382   DONE;
12383 })
12384 \f
12385 ;; Store-flag instructions.
12386
12387 ;; For all sCOND expanders, also expand the compare or test insn that
12388 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12389
12390 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12391 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12392 ;; way, which can later delete the movzx if only QImode is needed.
12393
12394 (define_expand "seq"
12395   [(set (match_operand:QI 0 "register_operand" "")
12396         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12397   ""
12398   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12399
12400 (define_expand "sne"
12401   [(set (match_operand:QI 0 "register_operand" "")
12402         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12403   ""
12404   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12405
12406 (define_expand "sgt"
12407   [(set (match_operand:QI 0 "register_operand" "")
12408         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12409   ""
12410   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12411
12412 (define_expand "sgtu"
12413   [(set (match_operand:QI 0 "register_operand" "")
12414         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12415   ""
12416   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12417
12418 (define_expand "slt"
12419   [(set (match_operand:QI 0 "register_operand" "")
12420         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12421   ""
12422   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12423
12424 (define_expand "sltu"
12425   [(set (match_operand:QI 0 "register_operand" "")
12426         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12427   ""
12428   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12429
12430 (define_expand "sge"
12431   [(set (match_operand:QI 0 "register_operand" "")
12432         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12433   ""
12434   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12435
12436 (define_expand "sgeu"
12437   [(set (match_operand:QI 0 "register_operand" "")
12438         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12439   ""
12440   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12441
12442 (define_expand "sle"
12443   [(set (match_operand:QI 0 "register_operand" "")
12444         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12445   ""
12446   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12447
12448 (define_expand "sleu"
12449   [(set (match_operand:QI 0 "register_operand" "")
12450         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12451   ""
12452   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12453
12454 (define_expand "sunordered"
12455   [(set (match_operand:QI 0 "register_operand" "")
12456         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12457   "TARGET_80387 || TARGET_SSE"
12458   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12459
12460 (define_expand "sordered"
12461   [(set (match_operand:QI 0 "register_operand" "")
12462         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12463   "TARGET_80387"
12464   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12465
12466 (define_expand "suneq"
12467   [(set (match_operand:QI 0 "register_operand" "")
12468         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12469   "TARGET_80387 || TARGET_SSE"
12470   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12471
12472 (define_expand "sunge"
12473   [(set (match_operand:QI 0 "register_operand" "")
12474         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12475   "TARGET_80387 || TARGET_SSE"
12476   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12477
12478 (define_expand "sungt"
12479   [(set (match_operand:QI 0 "register_operand" "")
12480         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12481   "TARGET_80387 || TARGET_SSE"
12482   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12483
12484 (define_expand "sunle"
12485   [(set (match_operand:QI 0 "register_operand" "")
12486         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12487   "TARGET_80387 || TARGET_SSE"
12488   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12489
12490 (define_expand "sunlt"
12491   [(set (match_operand:QI 0 "register_operand" "")
12492         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12493   "TARGET_80387 || TARGET_SSE"
12494   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12495
12496 (define_expand "sltgt"
12497   [(set (match_operand:QI 0 "register_operand" "")
12498         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12499   "TARGET_80387 || TARGET_SSE"
12500   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12501
12502 (define_insn "*setcc_1"
12503   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12504         (match_operator:QI 1 "ix86_comparison_operator"
12505           [(reg FLAGS_REG) (const_int 0)]))]
12506   ""
12507   "set%C1\t%0"
12508   [(set_attr "type" "setcc")
12509    (set_attr "mode" "QI")])
12510
12511 (define_insn "*setcc_2"
12512   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12513         (match_operator:QI 1 "ix86_comparison_operator"
12514           [(reg FLAGS_REG) (const_int 0)]))]
12515   ""
12516   "set%C1\t%0"
12517   [(set_attr "type" "setcc")
12518    (set_attr "mode" "QI")])
12519
12520 ;; In general it is not safe to assume too much about CCmode registers,
12521 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12522 ;; conditions this is safe on x86, so help combine not create
12523 ;;
12524 ;;      seta    %al
12525 ;;      testb   %al, %al
12526 ;;      sete    %al
12527
12528 (define_split 
12529   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12530         (ne:QI (match_operator 1 "ix86_comparison_operator"
12531                  [(reg FLAGS_REG) (const_int 0)])
12532             (const_int 0)))]
12533   ""
12534   [(set (match_dup 0) (match_dup 1))]
12535 {
12536   PUT_MODE (operands[1], QImode);
12537 })
12538
12539 (define_split 
12540   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12541         (ne:QI (match_operator 1 "ix86_comparison_operator"
12542                  [(reg FLAGS_REG) (const_int 0)])
12543             (const_int 0)))]
12544   ""
12545   [(set (match_dup 0) (match_dup 1))]
12546 {
12547   PUT_MODE (operands[1], QImode);
12548 })
12549
12550 (define_split 
12551   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12552         (eq:QI (match_operator 1 "ix86_comparison_operator"
12553                  [(reg FLAGS_REG) (const_int 0)])
12554             (const_int 0)))]
12555   ""
12556   [(set (match_dup 0) (match_dup 1))]
12557 {
12558   rtx new_op1 = copy_rtx (operands[1]);
12559   operands[1] = new_op1;
12560   PUT_MODE (new_op1, QImode);
12561   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12562                                              GET_MODE (XEXP (new_op1, 0))));
12563
12564   /* Make sure that (a) the CCmode we have for the flags is strong
12565      enough for the reversed compare or (b) we have a valid FP compare.  */
12566   if (! ix86_comparison_operator (new_op1, VOIDmode))
12567     FAIL;
12568 })
12569
12570 (define_split 
12571   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12572         (eq:QI (match_operator 1 "ix86_comparison_operator"
12573                  [(reg FLAGS_REG) (const_int 0)])
12574             (const_int 0)))]
12575   ""
12576   [(set (match_dup 0) (match_dup 1))]
12577 {
12578   rtx new_op1 = copy_rtx (operands[1]);
12579   operands[1] = new_op1;
12580   PUT_MODE (new_op1, QImode);
12581   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12582                                              GET_MODE (XEXP (new_op1, 0))));
12583
12584   /* Make sure that (a) the CCmode we have for the flags is strong
12585      enough for the reversed compare or (b) we have a valid FP compare.  */
12586   if (! ix86_comparison_operator (new_op1, VOIDmode))
12587     FAIL;
12588 })
12589
12590 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12591 ;; subsequent logical operations are used to imitate conditional moves.
12592 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12593 ;; it directly.  Further holding this value in pseudo register might bring
12594 ;; problem in implicit normalization in spill code.
12595 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12596 ;; instructions after reload by splitting the conditional move patterns.
12597
12598 (define_insn "*sse_setccsf"
12599   [(set (match_operand:SF 0 "register_operand" "=x")
12600         (match_operator:SF 1 "sse_comparison_operator"
12601           [(match_operand:SF 2 "register_operand" "0")
12602            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12603   "TARGET_SSE && reload_completed"
12604   "cmp%D1ss\t{%3, %0|%0, %3}"
12605   [(set_attr "type" "ssecmp")
12606    (set_attr "mode" "SF")])
12607
12608 (define_insn "*sse_setccdf"
12609   [(set (match_operand:DF 0 "register_operand" "=Y")
12610         (match_operator:DF 1 "sse_comparison_operator"
12611           [(match_operand:DF 2 "register_operand" "0")
12612            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12613   "TARGET_SSE2 && reload_completed"
12614   "cmp%D1sd\t{%3, %0|%0, %3}"
12615   [(set_attr "type" "ssecmp")
12616    (set_attr "mode" "DF")])
12617 \f
12618 ;; Basic conditional jump instructions.
12619 ;; We ignore the overflow flag for signed branch instructions.
12620
12621 ;; For all bCOND expanders, also expand the compare or test insn that
12622 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12623
12624 (define_expand "beq"
12625   [(set (pc)
12626         (if_then_else (match_dup 1)
12627                       (label_ref (match_operand 0 "" ""))
12628                       (pc)))]
12629   ""
12630   "ix86_expand_branch (EQ, operands[0]); DONE;")
12631
12632 (define_expand "bne"
12633   [(set (pc)
12634         (if_then_else (match_dup 1)
12635                       (label_ref (match_operand 0 "" ""))
12636                       (pc)))]
12637   ""
12638   "ix86_expand_branch (NE, operands[0]); DONE;")
12639
12640 (define_expand "bgt"
12641   [(set (pc)
12642         (if_then_else (match_dup 1)
12643                       (label_ref (match_operand 0 "" ""))
12644                       (pc)))]
12645   ""
12646   "ix86_expand_branch (GT, operands[0]); DONE;")
12647
12648 (define_expand "bgtu"
12649   [(set (pc)
12650         (if_then_else (match_dup 1)
12651                       (label_ref (match_operand 0 "" ""))
12652                       (pc)))]
12653   ""
12654   "ix86_expand_branch (GTU, operands[0]); DONE;")
12655
12656 (define_expand "blt"
12657   [(set (pc)
12658         (if_then_else (match_dup 1)
12659                       (label_ref (match_operand 0 "" ""))
12660                       (pc)))]
12661   ""
12662   "ix86_expand_branch (LT, operands[0]); DONE;")
12663
12664 (define_expand "bltu"
12665   [(set (pc)
12666         (if_then_else (match_dup 1)
12667                       (label_ref (match_operand 0 "" ""))
12668                       (pc)))]
12669   ""
12670   "ix86_expand_branch (LTU, operands[0]); DONE;")
12671
12672 (define_expand "bge"
12673   [(set (pc)
12674         (if_then_else (match_dup 1)
12675                       (label_ref (match_operand 0 "" ""))
12676                       (pc)))]
12677   ""
12678   "ix86_expand_branch (GE, operands[0]); DONE;")
12679
12680 (define_expand "bgeu"
12681   [(set (pc)
12682         (if_then_else (match_dup 1)
12683                       (label_ref (match_operand 0 "" ""))
12684                       (pc)))]
12685   ""
12686   "ix86_expand_branch (GEU, operands[0]); DONE;")
12687
12688 (define_expand "ble"
12689   [(set (pc)
12690         (if_then_else (match_dup 1)
12691                       (label_ref (match_operand 0 "" ""))
12692                       (pc)))]
12693   ""
12694   "ix86_expand_branch (LE, operands[0]); DONE;")
12695
12696 (define_expand "bleu"
12697   [(set (pc)
12698         (if_then_else (match_dup 1)
12699                       (label_ref (match_operand 0 "" ""))
12700                       (pc)))]
12701   ""
12702   "ix86_expand_branch (LEU, operands[0]); DONE;")
12703
12704 (define_expand "bunordered"
12705   [(set (pc)
12706         (if_then_else (match_dup 1)
12707                       (label_ref (match_operand 0 "" ""))
12708                       (pc)))]
12709   "TARGET_80387 || TARGET_SSE"
12710   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12711
12712 (define_expand "bordered"
12713   [(set (pc)
12714         (if_then_else (match_dup 1)
12715                       (label_ref (match_operand 0 "" ""))
12716                       (pc)))]
12717   "TARGET_80387 || TARGET_SSE"
12718   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12719
12720 (define_expand "buneq"
12721   [(set (pc)
12722         (if_then_else (match_dup 1)
12723                       (label_ref (match_operand 0 "" ""))
12724                       (pc)))]
12725   "TARGET_80387 || TARGET_SSE"
12726   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12727
12728 (define_expand "bunge"
12729   [(set (pc)
12730         (if_then_else (match_dup 1)
12731                       (label_ref (match_operand 0 "" ""))
12732                       (pc)))]
12733   "TARGET_80387 || TARGET_SSE"
12734   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12735
12736 (define_expand "bungt"
12737   [(set (pc)
12738         (if_then_else (match_dup 1)
12739                       (label_ref (match_operand 0 "" ""))
12740                       (pc)))]
12741   "TARGET_80387 || TARGET_SSE"
12742   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12743
12744 (define_expand "bunle"
12745   [(set (pc)
12746         (if_then_else (match_dup 1)
12747                       (label_ref (match_operand 0 "" ""))
12748                       (pc)))]
12749   "TARGET_80387 || TARGET_SSE"
12750   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12751
12752 (define_expand "bunlt"
12753   [(set (pc)
12754         (if_then_else (match_dup 1)
12755                       (label_ref (match_operand 0 "" ""))
12756                       (pc)))]
12757   "TARGET_80387 || TARGET_SSE"
12758   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12759
12760 (define_expand "bltgt"
12761   [(set (pc)
12762         (if_then_else (match_dup 1)
12763                       (label_ref (match_operand 0 "" ""))
12764                       (pc)))]
12765   "TARGET_80387 || TARGET_SSE"
12766   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12767
12768 (define_insn "*jcc_1"
12769   [(set (pc)
12770         (if_then_else (match_operator 1 "ix86_comparison_operator"
12771                                       [(reg FLAGS_REG) (const_int 0)])
12772                       (label_ref (match_operand 0 "" ""))
12773                       (pc)))]
12774   ""
12775   "%+j%C1\t%l0"
12776   [(set_attr "type" "ibr")
12777    (set_attr "modrm" "0")
12778    (set (attr "length")
12779            (if_then_else (and (ge (minus (match_dup 0) (pc))
12780                                   (const_int -126))
12781                               (lt (minus (match_dup 0) (pc))
12782                                   (const_int 128)))
12783              (const_int 2)
12784              (const_int 6)))])
12785
12786 (define_insn "*jcc_2"
12787   [(set (pc)
12788         (if_then_else (match_operator 1 "ix86_comparison_operator"
12789                                       [(reg FLAGS_REG) (const_int 0)])
12790                       (pc)
12791                       (label_ref (match_operand 0 "" ""))))]
12792   ""
12793   "%+j%c1\t%l0"
12794   [(set_attr "type" "ibr")
12795    (set_attr "modrm" "0")
12796    (set (attr "length")
12797            (if_then_else (and (ge (minus (match_dup 0) (pc))
12798                                   (const_int -126))
12799                               (lt (minus (match_dup 0) (pc))
12800                                   (const_int 128)))
12801              (const_int 2)
12802              (const_int 6)))])
12803
12804 ;; In general it is not safe to assume too much about CCmode registers,
12805 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12806 ;; conditions this is safe on x86, so help combine not create
12807 ;;
12808 ;;      seta    %al
12809 ;;      testb   %al, %al
12810 ;;      je      Lfoo
12811
12812 (define_split 
12813   [(set (pc)
12814         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12815                                       [(reg FLAGS_REG) (const_int 0)])
12816                           (const_int 0))
12817                       (label_ref (match_operand 1 "" ""))
12818                       (pc)))]
12819   ""
12820   [(set (pc)
12821         (if_then_else (match_dup 0)
12822                       (label_ref (match_dup 1))
12823                       (pc)))]
12824 {
12825   PUT_MODE (operands[0], VOIDmode);
12826 })
12827   
12828 (define_split 
12829   [(set (pc)
12830         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12831                                       [(reg FLAGS_REG) (const_int 0)])
12832                           (const_int 0))
12833                       (label_ref (match_operand 1 "" ""))
12834                       (pc)))]
12835   ""
12836   [(set (pc)
12837         (if_then_else (match_dup 0)
12838                       (label_ref (match_dup 1))
12839                       (pc)))]
12840 {
12841   rtx new_op0 = copy_rtx (operands[0]);
12842   operands[0] = new_op0;
12843   PUT_MODE (new_op0, VOIDmode);
12844   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12845                                              GET_MODE (XEXP (new_op0, 0))));
12846
12847   /* Make sure that (a) the CCmode we have for the flags is strong
12848      enough for the reversed compare or (b) we have a valid FP compare.  */
12849   if (! ix86_comparison_operator (new_op0, VOIDmode))
12850     FAIL;
12851 })
12852
12853 ;; Define combination compare-and-branch fp compare instructions to use
12854 ;; during early optimization.  Splitting the operation apart early makes
12855 ;; for bad code when we want to reverse the operation.
12856
12857 (define_insn "*fp_jcc_1"
12858   [(set (pc)
12859         (if_then_else (match_operator 0 "comparison_operator"
12860                         [(match_operand 1 "register_operand" "f")
12861                          (match_operand 2 "register_operand" "f")])
12862           (label_ref (match_operand 3 "" ""))
12863           (pc)))
12864    (clobber (reg:CCFP FPSR_REG))
12865    (clobber (reg:CCFP FLAGS_REG))]
12866   "TARGET_CMOVE && TARGET_80387
12867    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12868    && FLOAT_MODE_P (GET_MODE (operands[1]))
12869    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12870    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12871   "#")
12872
12873 (define_insn "*fp_jcc_1_sse"
12874   [(set (pc)
12875         (if_then_else (match_operator 0 "comparison_operator"
12876                         [(match_operand 1 "register_operand" "f#x,x#f")
12877                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12878           (label_ref (match_operand 3 "" ""))
12879           (pc)))
12880    (clobber (reg:CCFP FPSR_REG))
12881    (clobber (reg:CCFP FLAGS_REG))]
12882   "TARGET_80387
12883    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12884    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12885    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12886   "#")
12887
12888 (define_insn "*fp_jcc_1_sse_only"
12889   [(set (pc)
12890         (if_then_else (match_operator 0 "comparison_operator"
12891                         [(match_operand 1 "register_operand" "x")
12892                          (match_operand 2 "nonimmediate_operand" "xm")])
12893           (label_ref (match_operand 3 "" ""))
12894           (pc)))
12895    (clobber (reg:CCFP FPSR_REG))
12896    (clobber (reg:CCFP FLAGS_REG))]
12897   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12898    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12899    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12900   "#")
12901
12902 (define_insn "*fp_jcc_2"
12903   [(set (pc)
12904         (if_then_else (match_operator 0 "comparison_operator"
12905                         [(match_operand 1 "register_operand" "f")
12906                          (match_operand 2 "register_operand" "f")])
12907           (pc)
12908           (label_ref (match_operand 3 "" ""))))
12909    (clobber (reg:CCFP FPSR_REG))
12910    (clobber (reg:CCFP FLAGS_REG))]
12911   "TARGET_CMOVE && TARGET_80387
12912    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12913    && FLOAT_MODE_P (GET_MODE (operands[1]))
12914    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12915    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12916   "#")
12917
12918 (define_insn "*fp_jcc_2_sse"
12919   [(set (pc)
12920         (if_then_else (match_operator 0 "comparison_operator"
12921                         [(match_operand 1 "register_operand" "f#x,x#f")
12922                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12923           (pc)
12924           (label_ref (match_operand 3 "" ""))))
12925    (clobber (reg:CCFP FPSR_REG))
12926    (clobber (reg:CCFP FLAGS_REG))]
12927   "TARGET_80387
12928    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12929    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12930    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12931   "#")
12932
12933 (define_insn "*fp_jcc_2_sse_only"
12934   [(set (pc)
12935         (if_then_else (match_operator 0 "comparison_operator"
12936                         [(match_operand 1 "register_operand" "x")
12937                          (match_operand 2 "nonimmediate_operand" "xm")])
12938           (pc)
12939           (label_ref (match_operand 3 "" ""))))
12940    (clobber (reg:CCFP FPSR_REG))
12941    (clobber (reg:CCFP FLAGS_REG))]
12942   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12943    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12944    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12945   "#")
12946
12947 (define_insn "*fp_jcc_3"
12948   [(set (pc)
12949         (if_then_else (match_operator 0 "comparison_operator"
12950                         [(match_operand 1 "register_operand" "f")
12951                          (match_operand 2 "nonimmediate_operand" "fm")])
12952           (label_ref (match_operand 3 "" ""))
12953           (pc)))
12954    (clobber (reg:CCFP FPSR_REG))
12955    (clobber (reg:CCFP FLAGS_REG))
12956    (clobber (match_scratch:HI 4 "=a"))]
12957   "TARGET_80387
12958    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12959    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12960    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12961    && SELECT_CC_MODE (GET_CODE (operands[0]),
12962                       operands[1], operands[2]) == CCFPmode
12963    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12964   "#")
12965
12966 (define_insn "*fp_jcc_4"
12967   [(set (pc)
12968         (if_then_else (match_operator 0 "comparison_operator"
12969                         [(match_operand 1 "register_operand" "f")
12970                          (match_operand 2 "nonimmediate_operand" "fm")])
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    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12978    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12979    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12980    && SELECT_CC_MODE (GET_CODE (operands[0]),
12981                       operands[1], operands[2]) == CCFPmode
12982    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12983   "#")
12984
12985 (define_insn "*fp_jcc_5"
12986   [(set (pc)
12987         (if_then_else (match_operator 0 "comparison_operator"
12988                         [(match_operand 1 "register_operand" "f")
12989                          (match_operand 2 "register_operand" "f")])
12990           (label_ref (match_operand 3 "" ""))
12991           (pc)))
12992    (clobber (reg:CCFP FPSR_REG))
12993    (clobber (reg:CCFP FLAGS_REG))
12994    (clobber (match_scratch:HI 4 "=a"))]
12995   "TARGET_80387
12996    && FLOAT_MODE_P (GET_MODE (operands[1]))
12997    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12998    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12999   "#")
13000
13001 (define_insn "*fp_jcc_6"
13002   [(set (pc)
13003         (if_then_else (match_operator 0 "comparison_operator"
13004                         [(match_operand 1 "register_operand" "f")
13005                          (match_operand 2 "register_operand" "f")])
13006           (pc)
13007           (label_ref (match_operand 3 "" ""))))
13008    (clobber (reg:CCFP FPSR_REG))
13009    (clobber (reg:CCFP FLAGS_REG))
13010    (clobber (match_scratch:HI 4 "=a"))]
13011   "TARGET_80387
13012    && FLOAT_MODE_P (GET_MODE (operands[1]))
13013    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13014    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13015   "#")
13016
13017 (define_insn "*fp_jcc_7"
13018   [(set (pc)
13019         (if_then_else (match_operator 0 "comparison_operator"
13020                         [(match_operand 1 "register_operand" "f")
13021                          (match_operand 2 "const_double_operand" "C")])
13022           (label_ref (match_operand 3 "" ""))
13023           (pc)))
13024    (clobber (reg:CCFP FPSR_REG))
13025    (clobber (reg:CCFP FLAGS_REG))
13026    (clobber (match_scratch:HI 4 "=a"))]
13027   "TARGET_80387
13028    && FLOAT_MODE_P (GET_MODE (operands[1]))
13029    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13030    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13031    && SELECT_CC_MODE (GET_CODE (operands[0]),
13032                       operands[1], operands[2]) == CCFPmode
13033    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13034   "#")
13035
13036 ;; The order of operands in *fp_jcc_8 is forced by combine in
13037 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13038 ;; with a precedence over other operators and is always put in the first
13039 ;; place. Swap condition and operands to match ficom instruction.
13040
13041 (define_insn "*fp_jcc_8"
13042   [(set (pc)
13043         (if_then_else (match_operator 0 "comparison_operator"
13044                         [(match_operator 1 "float_operator"
13045                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13046                            (match_operand 3 "register_operand" "f,f")])
13047           (label_ref (match_operand 4 "" ""))
13048           (pc)))
13049    (clobber (reg:CCFP FPSR_REG))
13050    (clobber (reg:CCFP FLAGS_REG))
13051    (clobber (match_scratch:HI 5 "=a,a"))]
13052   "TARGET_80387 && TARGET_USE_FIOP
13053    && FLOAT_MODE_P (GET_MODE (operands[3]))
13054    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13055    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13056    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13057    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13058   "#")
13059
13060 (define_split
13061   [(set (pc)
13062         (if_then_else (match_operator 0 "comparison_operator"
13063                         [(match_operand 1 "register_operand" "")
13064                          (match_operand 2 "nonimmediate_operand" "")])
13065           (match_operand 3 "" "")
13066           (match_operand 4 "" "")))
13067    (clobber (reg:CCFP FPSR_REG))
13068    (clobber (reg:CCFP FLAGS_REG))]
13069   "reload_completed"
13070   [(const_int 0)]
13071 {
13072   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13073                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13074   DONE;
13075 })
13076
13077 (define_split
13078   [(set (pc)
13079         (if_then_else (match_operator 0 "comparison_operator"
13080                         [(match_operand 1 "register_operand" "")
13081                          (match_operand 2 "general_operand" "")])
13082           (match_operand 3 "" "")
13083           (match_operand 4 "" "")))
13084    (clobber (reg:CCFP FPSR_REG))
13085    (clobber (reg:CCFP FLAGS_REG))
13086    (clobber (match_scratch:HI 5 "=a"))]
13087   "reload_completed"
13088   [(const_int 0)]
13089 {
13090   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13091                         operands[3], operands[4], operands[5], NULL_RTX);
13092   DONE;
13093 })
13094
13095 (define_split
13096   [(set (pc)
13097         (if_then_else (match_operator 0 "comparison_operator"
13098                         [(match_operator 1 "float_operator"
13099                            [(match_operand:SI 2 "memory_operand" "")])
13100                            (match_operand 3 "register_operand" "")])
13101           (match_operand 4 "" "")
13102           (match_operand 5 "" "")))
13103    (clobber (reg:CCFP FPSR_REG))
13104    (clobber (reg:CCFP FLAGS_REG))
13105    (clobber (match_scratch:HI 6 "=a"))]
13106   "reload_completed"
13107   [(const_int 0)]
13108 {
13109   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13110   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13111                         operands[3], operands[7],
13112                         operands[4], operands[5], operands[6], NULL_RTX);
13113   DONE;
13114 })
13115
13116 ;; %%% Kill this when reload knows how to do it.
13117 (define_split
13118   [(set (pc)
13119         (if_then_else (match_operator 0 "comparison_operator"
13120                         [(match_operator 1 "float_operator"
13121                            [(match_operand:SI 2 "register_operand" "")])
13122                            (match_operand 3 "register_operand" "")])
13123           (match_operand 4 "" "")
13124           (match_operand 5 "" "")))
13125    (clobber (reg:CCFP FPSR_REG))
13126    (clobber (reg:CCFP FLAGS_REG))
13127    (clobber (match_scratch:HI 6 "=a"))]
13128   "reload_completed"
13129   [(const_int 0)]
13130 {
13131   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13132   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13133   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13134                         operands[3], operands[7],
13135                         operands[4], operands[5], operands[6], operands[2]);
13136   DONE;
13137 })
13138 \f
13139 ;; Unconditional and other jump instructions
13140
13141 (define_insn "jump"
13142   [(set (pc)
13143         (label_ref (match_operand 0 "" "")))]
13144   ""
13145   "jmp\t%l0"
13146   [(set_attr "type" "ibr")
13147    (set (attr "length")
13148            (if_then_else (and (ge (minus (match_dup 0) (pc))
13149                                   (const_int -126))
13150                               (lt (minus (match_dup 0) (pc))
13151                                   (const_int 128)))
13152              (const_int 2)
13153              (const_int 5)))
13154    (set_attr "modrm" "0")])
13155
13156 (define_expand "indirect_jump"
13157   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13158   ""
13159   "")
13160
13161 (define_insn "*indirect_jump"
13162   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13163   "!TARGET_64BIT"
13164   "jmp\t%A0"
13165   [(set_attr "type" "ibr")
13166    (set_attr "length_immediate" "0")])
13167
13168 (define_insn "*indirect_jump_rtx64"
13169   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13170   "TARGET_64BIT"
13171   "jmp\t%A0"
13172   [(set_attr "type" "ibr")
13173    (set_attr "length_immediate" "0")])
13174
13175 (define_expand "tablejump"
13176   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13177               (use (label_ref (match_operand 1 "" "")))])]
13178   ""
13179 {
13180   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13181      relative.  Convert the relative address to an absolute address.  */
13182   if (flag_pic)
13183     {
13184       rtx op0, op1;
13185       enum rtx_code code;
13186
13187       if (TARGET_64BIT)
13188         {
13189           code = PLUS;
13190           op0 = operands[0];
13191           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13192         }
13193       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13194         {
13195           code = PLUS;
13196           op0 = operands[0];
13197           op1 = pic_offset_table_rtx;
13198         }
13199       else
13200         {
13201           code = MINUS;
13202           op0 = pic_offset_table_rtx;
13203           op1 = operands[0];
13204         }
13205
13206       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13207                                          OPTAB_DIRECT);
13208     }
13209 })
13210
13211 (define_insn "*tablejump_1"
13212   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13213    (use (label_ref (match_operand 1 "" "")))]
13214   "!TARGET_64BIT"
13215   "jmp\t%A0"
13216   [(set_attr "type" "ibr")
13217    (set_attr "length_immediate" "0")])
13218
13219 (define_insn "*tablejump_1_rtx64"
13220   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13221    (use (label_ref (match_operand 1 "" "")))]
13222   "TARGET_64BIT"
13223   "jmp\t%A0"
13224   [(set_attr "type" "ibr")
13225    (set_attr "length_immediate" "0")])
13226 \f
13227 ;; Loop instruction
13228 ;;
13229 ;; This is all complicated by the fact that since this is a jump insn
13230 ;; we must handle our own reloads.
13231
13232 (define_expand "doloop_end"
13233   [(use (match_operand 0 "" ""))        ; loop pseudo
13234    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13235    (use (match_operand 2 "" ""))        ; max iterations
13236    (use (match_operand 3 "" ""))        ; loop level 
13237    (use (match_operand 4 "" ""))]       ; label
13238   "!TARGET_64BIT && TARGET_USE_LOOP"
13239   "                                 
13240 {
13241   /* Only use cloop on innermost loops.  */
13242   if (INTVAL (operands[3]) > 1)
13243     FAIL;
13244   if (GET_MODE (operands[0]) != SImode)
13245     FAIL;
13246   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13247                                            operands[0]));
13248   DONE;
13249 }")
13250
13251 (define_insn "doloop_end_internal"
13252   [(set (pc)
13253         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13254                           (const_int 1))
13255                       (label_ref (match_operand 0 "" ""))
13256                       (pc)))
13257    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13258         (plus:SI (match_dup 1)
13259                  (const_int -1)))
13260    (clobber (match_scratch:SI 3 "=X,X,r"))
13261    (clobber (reg:CC FLAGS_REG))]
13262   "!TARGET_64BIT && TARGET_USE_LOOP
13263    && (reload_in_progress || reload_completed
13264        || register_operand (operands[2], VOIDmode))"
13265 {
13266   if (which_alternative != 0)
13267     return "#";
13268   if (get_attr_length (insn) == 2)
13269     return "%+loop\t%l0";
13270   else
13271     return "dec{l}\t%1\;%+jne\t%l0";
13272 }
13273   [(set (attr "length")
13274         (if_then_else (and (eq_attr "alternative" "0")
13275                            (and (ge (minus (match_dup 0) (pc))
13276                                     (const_int -126))
13277                                 (lt (minus (match_dup 0) (pc))
13278                                     (const_int 128))))
13279                       (const_int 2)
13280                       (const_int 16)))
13281    ;; We don't know the type before shorten branches.  Optimistically expect
13282    ;; the loop instruction to match.
13283    (set (attr "type") (const_string "ibr"))])
13284
13285 (define_split
13286   [(set (pc)
13287         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13288                           (const_int 1))
13289                       (match_operand 0 "" "")
13290                       (pc)))
13291    (set (match_dup 1)
13292         (plus:SI (match_dup 1)
13293                  (const_int -1)))
13294    (clobber (match_scratch:SI 2 ""))
13295    (clobber (reg:CC FLAGS_REG))]
13296   "!TARGET_64BIT && TARGET_USE_LOOP
13297    && reload_completed
13298    && REGNO (operands[1]) != 2"
13299   [(parallel [(set (reg:CCZ FLAGS_REG)
13300                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13301                                  (const_int 0)))
13302               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13303    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13304                            (match_dup 0)
13305                            (pc)))]
13306   "")
13307   
13308 (define_split
13309   [(set (pc)
13310         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13311                           (const_int 1))
13312                       (match_operand 0 "" "")
13313                       (pc)))
13314    (set (match_operand:SI 2 "nonimmediate_operand" "")
13315         (plus:SI (match_dup 1)
13316                  (const_int -1)))
13317    (clobber (match_scratch:SI 3 ""))
13318    (clobber (reg:CC FLAGS_REG))]
13319   "!TARGET_64BIT && TARGET_USE_LOOP
13320    && reload_completed
13321    && (! REG_P (operands[2])
13322        || ! rtx_equal_p (operands[1], operands[2]))"
13323   [(set (match_dup 3) (match_dup 1))
13324    (parallel [(set (reg:CCZ FLAGS_REG)
13325                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13326                                 (const_int 0)))
13327               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13328    (set (match_dup 2) (match_dup 3))
13329    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13330                            (match_dup 0)
13331                            (pc)))]
13332   "")
13333
13334 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13335
13336 (define_peephole2
13337   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13338    (set (match_operand:QI 1 "register_operand" "")
13339         (match_operator:QI 2 "ix86_comparison_operator"
13340           [(reg FLAGS_REG) (const_int 0)]))
13341    (set (match_operand 3 "q_regs_operand" "")
13342         (zero_extend (match_dup 1)))]
13343   "(peep2_reg_dead_p (3, operands[1])
13344     || operands_match_p (operands[1], operands[3]))
13345    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13346   [(set (match_dup 4) (match_dup 0))
13347    (set (strict_low_part (match_dup 5))
13348         (match_dup 2))]
13349 {
13350   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13351   operands[5] = gen_lowpart (QImode, operands[3]);
13352   ix86_expand_clear (operands[3]);
13353 })
13354
13355 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13356
13357 (define_peephole2
13358   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13359    (set (match_operand:QI 1 "register_operand" "")
13360         (match_operator:QI 2 "ix86_comparison_operator"
13361           [(reg FLAGS_REG) (const_int 0)]))
13362    (parallel [(set (match_operand 3 "q_regs_operand" "")
13363                    (zero_extend (match_dup 1)))
13364               (clobber (reg:CC FLAGS_REG))])]
13365   "(peep2_reg_dead_p (3, operands[1])
13366     || operands_match_p (operands[1], operands[3]))
13367    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13368   [(set (match_dup 4) (match_dup 0))
13369    (set (strict_low_part (match_dup 5))
13370         (match_dup 2))]
13371 {
13372   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13373   operands[5] = gen_lowpart (QImode, operands[3]);
13374   ix86_expand_clear (operands[3]);
13375 })
13376 \f
13377 ;; Call instructions.
13378
13379 ;; The predicates normally associated with named expanders are not properly
13380 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13381 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13382
13383 ;; Call subroutine returning no value.
13384
13385 (define_expand "call_pop"
13386   [(parallel [(call (match_operand:QI 0 "" "")
13387                     (match_operand:SI 1 "" ""))
13388               (set (reg:SI SP_REG)
13389                    (plus:SI (reg:SI SP_REG)
13390                             (match_operand:SI 3 "" "")))])]
13391   "!TARGET_64BIT"
13392 {
13393   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13394   DONE;
13395 })
13396
13397 (define_insn "*call_pop_0"
13398   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13399          (match_operand:SI 1 "" ""))
13400    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13401                             (match_operand:SI 2 "immediate_operand" "")))]
13402   "!TARGET_64BIT"
13403 {
13404   if (SIBLING_CALL_P (insn))
13405     return "jmp\t%P0";
13406   else
13407     return "call\t%P0";
13408 }
13409   [(set_attr "type" "call")])
13410   
13411 (define_insn "*call_pop_1"
13412   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13413          (match_operand:SI 1 "" ""))
13414    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13415                             (match_operand:SI 2 "immediate_operand" "i")))]
13416   "!TARGET_64BIT"
13417 {
13418   if (constant_call_address_operand (operands[0], Pmode))
13419     {
13420       if (SIBLING_CALL_P (insn))
13421         return "jmp\t%P0";
13422       else
13423         return "call\t%P0";
13424     }
13425   if (SIBLING_CALL_P (insn))
13426     return "jmp\t%A0";
13427   else
13428     return "call\t%A0";
13429 }
13430   [(set_attr "type" "call")])
13431
13432 (define_expand "call"
13433   [(call (match_operand:QI 0 "" "")
13434          (match_operand 1 "" ""))
13435    (use (match_operand 2 "" ""))]
13436   ""
13437 {
13438   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13439   DONE;
13440 })
13441
13442 (define_expand "sibcall"
13443   [(call (match_operand:QI 0 "" "")
13444          (match_operand 1 "" ""))
13445    (use (match_operand 2 "" ""))]
13446   ""
13447 {
13448   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13449   DONE;
13450 })
13451
13452 (define_insn "*call_0"
13453   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13454          (match_operand 1 "" ""))]
13455   ""
13456 {
13457   if (SIBLING_CALL_P (insn))
13458     return "jmp\t%P0";
13459   else
13460     return "call\t%P0";
13461 }
13462   [(set_attr "type" "call")])
13463
13464 (define_insn "*call_1"
13465   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13466          (match_operand 1 "" ""))]
13467   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13468 {
13469   if (constant_call_address_operand (operands[0], Pmode))
13470     return "call\t%P0";
13471   return "call\t%A0";
13472 }
13473   [(set_attr "type" "call")])
13474
13475 (define_insn "*sibcall_1"
13476   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13477          (match_operand 1 "" ""))]
13478   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13479 {
13480   if (constant_call_address_operand (operands[0], Pmode))
13481     return "jmp\t%P0";
13482   return "jmp\t%A0";
13483 }
13484   [(set_attr "type" "call")])
13485
13486 (define_insn "*call_1_rex64"
13487   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13488          (match_operand 1 "" ""))]
13489   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13490 {
13491   if (constant_call_address_operand (operands[0], Pmode))
13492     return "call\t%P0";
13493   return "call\t%A0";
13494 }
13495   [(set_attr "type" "call")])
13496
13497 (define_insn "*sibcall_1_rex64"
13498   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13499          (match_operand 1 "" ""))]
13500   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13501   "jmp\t%P0"
13502   [(set_attr "type" "call")])
13503
13504 (define_insn "*sibcall_1_rex64_v"
13505   [(call (mem:QI (reg:DI 40))
13506          (match_operand 0 "" ""))]
13507   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13508   "jmp\t*%%r11"
13509   [(set_attr "type" "call")])
13510
13511
13512 ;; Call subroutine, returning value in operand 0
13513
13514 (define_expand "call_value_pop"
13515   [(parallel [(set (match_operand 0 "" "")
13516                    (call (match_operand:QI 1 "" "")
13517                          (match_operand:SI 2 "" "")))
13518               (set (reg:SI SP_REG)
13519                    (plus:SI (reg:SI SP_REG)
13520                             (match_operand:SI 4 "" "")))])]
13521   "!TARGET_64BIT"
13522 {
13523   ix86_expand_call (operands[0], operands[1], operands[2],
13524                     operands[3], operands[4], 0);
13525   DONE;
13526 })
13527
13528 (define_expand "call_value"
13529   [(set (match_operand 0 "" "")
13530         (call (match_operand:QI 1 "" "")
13531               (match_operand:SI 2 "" "")))
13532    (use (match_operand:SI 3 "" ""))]
13533   ;; Operand 2 not used on the i386.
13534   ""
13535 {
13536   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13537   DONE;
13538 })
13539
13540 (define_expand "sibcall_value"
13541   [(set (match_operand 0 "" "")
13542         (call (match_operand:QI 1 "" "")
13543               (match_operand:SI 2 "" "")))
13544    (use (match_operand:SI 3 "" ""))]
13545   ;; Operand 2 not used on the i386.
13546   ""
13547 {
13548   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13549   DONE;
13550 })
13551
13552 ;; Call subroutine returning any type.
13553
13554 (define_expand "untyped_call"
13555   [(parallel [(call (match_operand 0 "" "")
13556                     (const_int 0))
13557               (match_operand 1 "" "")
13558               (match_operand 2 "" "")])]
13559   ""
13560 {
13561   int i;
13562
13563   /* In order to give reg-stack an easier job in validating two
13564      coprocessor registers as containing a possible return value,
13565      simply pretend the untyped call returns a complex long double
13566      value.  */
13567
13568   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13569                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13570                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13571                     NULL, 0);
13572
13573   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13574     {
13575       rtx set = XVECEXP (operands[2], 0, i);
13576       emit_move_insn (SET_DEST (set), SET_SRC (set));
13577     }
13578
13579   /* The optimizer does not know that the call sets the function value
13580      registers we stored in the result block.  We avoid problems by
13581      claiming that all hard registers are used and clobbered at this
13582      point.  */
13583   emit_insn (gen_blockage (const0_rtx));
13584
13585   DONE;
13586 })
13587 \f
13588 ;; Prologue and epilogue instructions
13589
13590 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13591 ;; all of memory.  This blocks insns from being moved across this point.
13592
13593 (define_insn "blockage"
13594   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13595   ""
13596   ""
13597   [(set_attr "length" "0")])
13598
13599 ;; Insn emitted into the body of a function to return from a function.
13600 ;; This is only done if the function's epilogue is known to be simple.
13601 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13602
13603 (define_expand "return"
13604   [(return)]
13605   "ix86_can_use_return_insn_p ()"
13606 {
13607   if (current_function_pops_args)
13608     {
13609       rtx popc = GEN_INT (current_function_pops_args);
13610       emit_jump_insn (gen_return_pop_internal (popc));
13611       DONE;
13612     }
13613 })
13614
13615 (define_insn "return_internal"
13616   [(return)]
13617   "reload_completed"
13618   "ret"
13619   [(set_attr "length" "1")
13620    (set_attr "length_immediate" "0")
13621    (set_attr "modrm" "0")])
13622
13623 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13624 ;; instruction Athlon and K8 have.
13625
13626 (define_insn "return_internal_long"
13627   [(return)
13628    (unspec [(const_int 0)] UNSPEC_REP)]
13629   "reload_completed"
13630   "rep {;} ret"
13631   [(set_attr "length" "1")
13632    (set_attr "length_immediate" "0")
13633    (set_attr "prefix_rep" "1")
13634    (set_attr "modrm" "0")])
13635
13636 (define_insn "return_pop_internal"
13637   [(return)
13638    (use (match_operand:SI 0 "const_int_operand" ""))]
13639   "reload_completed"
13640   "ret\t%0"
13641   [(set_attr "length" "3")
13642    (set_attr "length_immediate" "2")
13643    (set_attr "modrm" "0")])
13644
13645 (define_insn "return_indirect_internal"
13646   [(return)
13647    (use (match_operand:SI 0 "register_operand" "r"))]
13648   "reload_completed"
13649   "jmp\t%A0"
13650   [(set_attr "type" "ibr")
13651    (set_attr "length_immediate" "0")])
13652
13653 (define_insn "nop"
13654   [(const_int 0)]
13655   ""
13656   "nop"
13657   [(set_attr "length" "1")
13658    (set_attr "length_immediate" "0")
13659    (set_attr "modrm" "0")])
13660
13661 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13662 ;; branch prediction penalty for the third jump in a 16-byte
13663 ;; block on K8.
13664
13665 (define_insn "align"
13666   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13667   ""
13668 {
13669 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13670   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13671 #else
13672   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13673      The align insn is used to avoid 3 jump instructions in the row to improve
13674      branch prediction and the benefits hardly outweight the cost of extra 8
13675      nops on the average inserted by full alignment pseudo operation.  */
13676 #endif
13677   return "";
13678 }
13679   [(set_attr "length" "16")])
13680
13681 (define_expand "prologue"
13682   [(const_int 1)]
13683   ""
13684   "ix86_expand_prologue (); DONE;")
13685
13686 (define_insn "set_got"
13687   [(set (match_operand:SI 0 "register_operand" "=r")
13688         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13689    (clobber (reg:CC FLAGS_REG))]
13690   "!TARGET_64BIT"
13691   { return output_set_got (operands[0]); }
13692   [(set_attr "type" "multi")
13693    (set_attr "length" "12")])
13694
13695 (define_expand "epilogue"
13696   [(const_int 1)]
13697   ""
13698   "ix86_expand_epilogue (1); DONE;")
13699
13700 (define_expand "sibcall_epilogue"
13701   [(const_int 1)]
13702   ""
13703   "ix86_expand_epilogue (0); DONE;")
13704
13705 (define_expand "eh_return"
13706   [(use (match_operand 0 "register_operand" ""))]
13707   ""
13708 {
13709   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13710
13711   /* Tricky bit: we write the address of the handler to which we will
13712      be returning into someone else's stack frame, one word below the
13713      stack address we wish to restore.  */
13714   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13715   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13716   tmp = gen_rtx_MEM (Pmode, tmp);
13717   emit_move_insn (tmp, ra);
13718
13719   if (Pmode == SImode)
13720     emit_jump_insn (gen_eh_return_si (sa));
13721   else
13722     emit_jump_insn (gen_eh_return_di (sa));
13723   emit_barrier ();
13724   DONE;
13725 })
13726
13727 (define_insn_and_split "eh_return_si"
13728   [(set (pc) 
13729         (unspec [(match_operand:SI 0 "register_operand" "c")]
13730                  UNSPEC_EH_RETURN))]
13731   "!TARGET_64BIT"
13732   "#"
13733   "reload_completed"
13734   [(const_int 1)]
13735   "ix86_expand_epilogue (2); DONE;")
13736
13737 (define_insn_and_split "eh_return_di"
13738   [(set (pc) 
13739         (unspec [(match_operand:DI 0 "register_operand" "c")]
13740                  UNSPEC_EH_RETURN))]
13741   "TARGET_64BIT"
13742   "#"
13743   "reload_completed"
13744   [(const_int 1)]
13745   "ix86_expand_epilogue (2); DONE;")
13746
13747 (define_insn "leave"
13748   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13749    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13750    (clobber (mem:BLK (scratch)))]
13751   "!TARGET_64BIT"
13752   "leave"
13753   [(set_attr "type" "leave")])
13754
13755 (define_insn "leave_rex64"
13756   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13757    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13758    (clobber (mem:BLK (scratch)))]
13759   "TARGET_64BIT"
13760   "leave"
13761   [(set_attr "type" "leave")])
13762 \f
13763 (define_expand "ffssi2"
13764   [(parallel
13765      [(set (match_operand:SI 0 "register_operand" "") 
13766            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13767       (clobber (match_scratch:SI 2 ""))
13768       (clobber (reg:CC FLAGS_REG))])]
13769   ""
13770   "")
13771
13772 (define_insn_and_split "*ffs_cmove"
13773   [(set (match_operand:SI 0 "register_operand" "=r") 
13774         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13775    (clobber (match_scratch:SI 2 "=&r"))
13776    (clobber (reg:CC FLAGS_REG))]
13777   "TARGET_CMOVE"
13778   "#"
13779   "&& reload_completed"
13780   [(set (match_dup 2) (const_int -1))
13781    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13782               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13783    (set (match_dup 0) (if_then_else:SI
13784                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13785                         (match_dup 2)
13786                         (match_dup 0)))
13787    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13788               (clobber (reg:CC FLAGS_REG))])]
13789   "")
13790
13791 (define_insn_and_split "*ffs_no_cmove"
13792   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13793         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13794    (clobber (match_scratch:SI 2 "=&q"))
13795    (clobber (reg:CC FLAGS_REG))]
13796   ""
13797   "#"
13798   "reload_completed"
13799   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13800               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13801    (set (strict_low_part (match_dup 3))
13802         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13803    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13804               (clobber (reg:CC FLAGS_REG))])
13805    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13806               (clobber (reg:CC FLAGS_REG))])
13807    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13808               (clobber (reg:CC FLAGS_REG))])]
13809 {
13810   operands[3] = gen_lowpart (QImode, operands[2]);
13811   ix86_expand_clear (operands[2]);
13812 })
13813
13814 (define_insn "*ffssi_1"
13815   [(set (reg:CCZ FLAGS_REG)
13816         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13817                      (const_int 0)))
13818    (set (match_operand:SI 0 "register_operand" "=r")
13819         (ctz:SI (match_dup 1)))]
13820   ""
13821   "bsf{l}\t{%1, %0|%0, %1}"
13822   [(set_attr "prefix_0f" "1")])
13823
13824 (define_expand "ffsdi2"
13825   [(parallel
13826      [(set (match_operand:DI 0 "register_operand" "") 
13827            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13828       (clobber (match_scratch:DI 2 ""))
13829       (clobber (reg:CC FLAGS_REG))])]
13830   "TARGET_64BIT && TARGET_CMOVE"
13831   "")
13832
13833 (define_insn_and_split "*ffs_rex64"
13834   [(set (match_operand:DI 0 "register_operand" "=r") 
13835         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13836    (clobber (match_scratch:DI 2 "=&r"))
13837    (clobber (reg:CC FLAGS_REG))]
13838   "TARGET_64BIT && TARGET_CMOVE"
13839   "#"
13840   "&& reload_completed"
13841   [(set (match_dup 2) (const_int -1))
13842    (parallel [(set (reg:CCZ FLAGS_REG)
13843                    (compare:CCZ (match_dup 1) (const_int 0)))
13844               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13845    (set (match_dup 0) (if_then_else:DI
13846                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13847                         (match_dup 2)
13848                         (match_dup 0)))
13849    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13850               (clobber (reg:CC FLAGS_REG))])]
13851   "")
13852
13853 (define_insn "*ffsdi_1"
13854   [(set (reg:CCZ FLAGS_REG)
13855         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13856                      (const_int 0)))
13857    (set (match_operand:DI 0 "register_operand" "=r")
13858         (ctz:DI (match_dup 1)))]
13859   "TARGET_64BIT"
13860   "bsf{q}\t{%1, %0|%0, %1}"
13861   [(set_attr "prefix_0f" "1")])
13862
13863 (define_insn "ctzsi2"
13864   [(set (match_operand:SI 0 "register_operand" "=r")
13865         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13866    (clobber (reg:CC FLAGS_REG))]
13867   ""
13868   "bsf{l}\t{%1, %0|%0, %1}"
13869   [(set_attr "prefix_0f" "1")])
13870
13871 (define_insn "ctzdi2"
13872   [(set (match_operand:DI 0 "register_operand" "=r")
13873         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13874    (clobber (reg:CC FLAGS_REG))]
13875   "TARGET_64BIT"
13876   "bsf{q}\t{%1, %0|%0, %1}"
13877   [(set_attr "prefix_0f" "1")])
13878
13879 (define_expand "clzsi2"
13880   [(parallel
13881      [(set (match_operand:SI 0 "register_operand" "")
13882            (minus:SI (const_int 31)
13883                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13884       (clobber (reg:CC FLAGS_REG))])
13885    (parallel
13886      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13887       (clobber (reg:CC FLAGS_REG))])]
13888   ""
13889   "")
13890
13891 (define_insn "*bsr"
13892   [(set (match_operand:SI 0 "register_operand" "=r")
13893         (minus:SI (const_int 31)
13894                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13895    (clobber (reg:CC FLAGS_REG))]
13896   ""
13897   "bsr{l}\t{%1, %0|%0, %1}"
13898   [(set_attr "prefix_0f" "1")])
13899
13900 (define_expand "clzdi2"
13901   [(parallel
13902      [(set (match_operand:DI 0 "register_operand" "")
13903            (minus:DI (const_int 63)
13904                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13905       (clobber (reg:CC FLAGS_REG))])
13906    (parallel
13907      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13908       (clobber (reg:CC FLAGS_REG))])]
13909   "TARGET_64BIT"
13910   "")
13911
13912 (define_insn "*bsr_rex64"
13913   [(set (match_operand:DI 0 "register_operand" "=r")
13914         (minus:DI (const_int 63)
13915                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13916    (clobber (reg:CC FLAGS_REG))]
13917   "TARGET_64BIT"
13918   "bsr{q}\t{%1, %0|%0, %1}"
13919   [(set_attr "prefix_0f" "1")])
13920 \f
13921 ;; Thread-local storage patterns for ELF.
13922 ;;
13923 ;; Note that these code sequences must appear exactly as shown
13924 ;; in order to allow linker relaxation.
13925
13926 (define_insn "*tls_global_dynamic_32_gnu"
13927   [(set (match_operand:SI 0 "register_operand" "=a")
13928         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13929                     (match_operand:SI 2 "tls_symbolic_operand" "")
13930                     (match_operand:SI 3 "call_insn_operand" "")]
13931                     UNSPEC_TLS_GD))
13932    (clobber (match_scratch:SI 4 "=d"))
13933    (clobber (match_scratch:SI 5 "=c"))
13934    (clobber (reg:CC FLAGS_REG))]
13935   "!TARGET_64BIT && TARGET_GNU_TLS"
13936   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13937   [(set_attr "type" "multi")
13938    (set_attr "length" "12")])
13939
13940 (define_insn "*tls_global_dynamic_32_sun"
13941   [(set (match_operand:SI 0 "register_operand" "=a")
13942         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13943                     (match_operand:SI 2 "tls_symbolic_operand" "")
13944                     (match_operand:SI 3 "call_insn_operand" "")]
13945                     UNSPEC_TLS_GD))
13946    (clobber (match_scratch:SI 4 "=d"))
13947    (clobber (match_scratch:SI 5 "=c"))
13948    (clobber (reg:CC FLAGS_REG))]
13949   "!TARGET_64BIT && TARGET_SUN_TLS"
13950   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13951         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13952   [(set_attr "type" "multi")
13953    (set_attr "length" "14")])
13954
13955 (define_expand "tls_global_dynamic_32"
13956   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13957                    (unspec:SI
13958                     [(match_dup 2)
13959                      (match_operand:SI 1 "tls_symbolic_operand" "")
13960                      (match_dup 3)]
13961                     UNSPEC_TLS_GD))
13962               (clobber (match_scratch:SI 4 ""))
13963               (clobber (match_scratch:SI 5 ""))
13964               (clobber (reg:CC FLAGS_REG))])]
13965   ""
13966 {
13967   if (flag_pic)
13968     operands[2] = pic_offset_table_rtx;
13969   else
13970     {
13971       operands[2] = gen_reg_rtx (Pmode);
13972       emit_insn (gen_set_got (operands[2]));
13973     }
13974   operands[3] = ix86_tls_get_addr ();
13975 })
13976
13977 (define_insn "*tls_global_dynamic_64"
13978   [(set (match_operand:DI 0 "register_operand" "=a")
13979         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13980                       (match_operand:DI 3 "" "")))
13981    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13982               UNSPEC_TLS_GD)]
13983   "TARGET_64BIT"
13984   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13985   [(set_attr "type" "multi")
13986    (set_attr "length" "16")])
13987
13988 (define_expand "tls_global_dynamic_64"
13989   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13990                    (call (mem:QI (match_dup 2)) (const_int 0)))
13991               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13992                          UNSPEC_TLS_GD)])]
13993   ""
13994 {
13995   operands[2] = ix86_tls_get_addr ();
13996 })
13997
13998 (define_insn "*tls_local_dynamic_base_32_gnu"
13999   [(set (match_operand:SI 0 "register_operand" "=a")
14000         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14001                     (match_operand:SI 2 "call_insn_operand" "")]
14002                    UNSPEC_TLS_LD_BASE))
14003    (clobber (match_scratch:SI 3 "=d"))
14004    (clobber (match_scratch:SI 4 "=c"))
14005    (clobber (reg:CC FLAGS_REG))]
14006   "!TARGET_64BIT && TARGET_GNU_TLS"
14007   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14008   [(set_attr "type" "multi")
14009    (set_attr "length" "11")])
14010
14011 (define_insn "*tls_local_dynamic_base_32_sun"
14012   [(set (match_operand:SI 0 "register_operand" "=a")
14013         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14014                     (match_operand:SI 2 "call_insn_operand" "")]
14015                    UNSPEC_TLS_LD_BASE))
14016    (clobber (match_scratch:SI 3 "=d"))
14017    (clobber (match_scratch:SI 4 "=c"))
14018    (clobber (reg:CC FLAGS_REG))]
14019   "!TARGET_64BIT && TARGET_SUN_TLS"
14020   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14021         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14022   [(set_attr "type" "multi")
14023    (set_attr "length" "13")])
14024
14025 (define_expand "tls_local_dynamic_base_32"
14026   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14027                    (unspec:SI [(match_dup 1) (match_dup 2)]
14028                               UNSPEC_TLS_LD_BASE))
14029               (clobber (match_scratch:SI 3 ""))
14030               (clobber (match_scratch:SI 4 ""))
14031               (clobber (reg:CC FLAGS_REG))])]
14032   ""
14033 {
14034   if (flag_pic)
14035     operands[1] = pic_offset_table_rtx;
14036   else
14037     {
14038       operands[1] = gen_reg_rtx (Pmode);
14039       emit_insn (gen_set_got (operands[1]));
14040     }
14041   operands[2] = ix86_tls_get_addr ();
14042 })
14043
14044 (define_insn "*tls_local_dynamic_base_64"
14045   [(set (match_operand:DI 0 "register_operand" "=a")
14046         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14047                       (match_operand:DI 2 "" "")))
14048    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14049   "TARGET_64BIT"
14050   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14051   [(set_attr "type" "multi")
14052    (set_attr "length" "12")])
14053
14054 (define_expand "tls_local_dynamic_base_64"
14055   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14056                    (call (mem:QI (match_dup 1)) (const_int 0)))
14057               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14058   ""
14059 {
14060   operands[1] = ix86_tls_get_addr ();
14061 })
14062
14063 ;; Local dynamic of a single variable is a lose.  Show combine how
14064 ;; to convert that back to global dynamic.
14065
14066 (define_insn_and_split "*tls_local_dynamic_32_once"
14067   [(set (match_operand:SI 0 "register_operand" "=a")
14068         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14069                              (match_operand:SI 2 "call_insn_operand" "")]
14070                             UNSPEC_TLS_LD_BASE)
14071                  (const:SI (unspec:SI
14072                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14073                             UNSPEC_DTPOFF))))
14074    (clobber (match_scratch:SI 4 "=d"))
14075    (clobber (match_scratch:SI 5 "=c"))
14076    (clobber (reg:CC FLAGS_REG))]
14077   ""
14078   "#"
14079   ""
14080   [(parallel [(set (match_dup 0)
14081                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14082                               UNSPEC_TLS_GD))
14083               (clobber (match_dup 4))
14084               (clobber (match_dup 5))
14085               (clobber (reg:CC FLAGS_REG))])]
14086   "")
14087
14088 ;; Load and add the thread base pointer from %gs:0.
14089
14090 (define_insn "*load_tp_si"
14091   [(set (match_operand:SI 0 "register_operand" "=r")
14092         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14093   "!TARGET_64BIT"
14094   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14095   [(set_attr "type" "imov")
14096    (set_attr "modrm" "0")
14097    (set_attr "length" "7")
14098    (set_attr "memory" "load")
14099    (set_attr "imm_disp" "false")])
14100
14101 (define_insn "*add_tp_si"
14102   [(set (match_operand:SI 0 "register_operand" "=r")
14103         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14104                  (match_operand:SI 1 "register_operand" "0")))
14105    (clobber (reg:CC FLAGS_REG))]
14106   "!TARGET_64BIT"
14107   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14108   [(set_attr "type" "alu")
14109    (set_attr "modrm" "0")
14110    (set_attr "length" "7")
14111    (set_attr "memory" "load")
14112    (set_attr "imm_disp" "false")])
14113
14114 (define_insn "*load_tp_di"
14115   [(set (match_operand:DI 0 "register_operand" "=r")
14116         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14117   "TARGET_64BIT"
14118   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14119   [(set_attr "type" "imov")
14120    (set_attr "modrm" "0")
14121    (set_attr "length" "7")
14122    (set_attr "memory" "load")
14123    (set_attr "imm_disp" "false")])
14124
14125 (define_insn "*add_tp_di"
14126   [(set (match_operand:DI 0 "register_operand" "=r")
14127         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14128                  (match_operand:DI 1 "register_operand" "0")))
14129    (clobber (reg:CC FLAGS_REG))]
14130   "TARGET_64BIT"
14131   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14132   [(set_attr "type" "alu")
14133    (set_attr "modrm" "0")
14134    (set_attr "length" "7")
14135    (set_attr "memory" "load")
14136    (set_attr "imm_disp" "false")])
14137 \f
14138 ;; These patterns match the binary 387 instructions for addM3, subM3,
14139 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14140 ;; SFmode.  The first is the normal insn, the second the same insn but
14141 ;; with one operand a conversion, and the third the same insn but with
14142 ;; the other operand a conversion.  The conversion may be SFmode or
14143 ;; SImode if the target mode DFmode, but only SImode if the target mode
14144 ;; is SFmode.
14145
14146 ;; Gcc is slightly more smart about handling normal two address instructions
14147 ;; so use special patterns for add and mull.
14148
14149 (define_insn "*fop_sf_comm_mixed"
14150   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14151         (match_operator:SF 3 "binary_fp_operator"
14152                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14153                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14154   "TARGET_MIX_SSE_I387
14155    && COMMUTATIVE_ARITH_P (operands[3])
14156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14157   "* return output_387_binary_op (insn, operands);"
14158   [(set (attr "type") 
14159         (if_then_else (eq_attr "alternative" "1")
14160            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14161               (const_string "ssemul")
14162               (const_string "sseadd"))
14163            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14164               (const_string "fmul")
14165               (const_string "fop"))))
14166    (set_attr "mode" "SF")])
14167
14168 (define_insn "*fop_sf_comm_sse"
14169   [(set (match_operand:SF 0 "register_operand" "=x")
14170         (match_operator:SF 3 "binary_fp_operator"
14171                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14172                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14173   "TARGET_SSE_MATH
14174    && COMMUTATIVE_ARITH_P (operands[3])
14175    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14176   "* return output_387_binary_op (insn, operands);"
14177   [(set (attr "type") 
14178         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14179            (const_string "ssemul")
14180            (const_string "sseadd")))
14181    (set_attr "mode" "SF")])
14182
14183 (define_insn "*fop_sf_comm_i387"
14184   [(set (match_operand:SF 0 "register_operand" "=f")
14185         (match_operator:SF 3 "binary_fp_operator"
14186                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14187                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14188   "TARGET_80387
14189    && COMMUTATIVE_ARITH_P (operands[3])
14190    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14191   "* return output_387_binary_op (insn, operands);"
14192   [(set (attr "type") 
14193         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14194            (const_string "fmul")
14195            (const_string "fop")))
14196    (set_attr "mode" "SF")])
14197
14198 (define_insn "*fop_sf_1_mixed"
14199   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14200         (match_operator:SF 3 "binary_fp_operator"
14201                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14202                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14203   "TARGET_MIX_SSE_I387
14204    && !COMMUTATIVE_ARITH_P (operands[3])
14205    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14206   "* return output_387_binary_op (insn, operands);"
14207   [(set (attr "type") 
14208         (cond [(and (eq_attr "alternative" "2")
14209                     (match_operand:SF 3 "mult_operator" ""))
14210                  (const_string "ssemul")
14211                (and (eq_attr "alternative" "2")
14212                     (match_operand:SF 3 "div_operator" ""))
14213                  (const_string "ssediv")
14214                (eq_attr "alternative" "2")
14215                  (const_string "sseadd")
14216                (match_operand:SF 3 "mult_operator" "") 
14217                  (const_string "fmul")
14218                (match_operand:SF 3 "div_operator" "") 
14219                  (const_string "fdiv")
14220               ]
14221               (const_string "fop")))
14222    (set_attr "mode" "SF")])
14223
14224 (define_insn "*fop_sf_1_sse"
14225   [(set (match_operand:SF 0 "register_operand" "=x")
14226         (match_operator:SF 3 "binary_fp_operator"
14227                         [(match_operand:SF 1 "register_operand" "0")
14228                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14229   "TARGET_SSE_MATH
14230    && !COMMUTATIVE_ARITH_P (operands[3])"
14231   "* return output_387_binary_op (insn, operands);"
14232   [(set (attr "type") 
14233         (cond [(match_operand:SF 3 "mult_operator" "")
14234                  (const_string "ssemul")
14235                (match_operand:SF 3 "div_operator" "")
14236                  (const_string "ssediv")
14237               ]
14238               (const_string "sseadd")))
14239    (set_attr "mode" "SF")])
14240
14241 (define_insn "*fop_sf_1_i387"
14242   [(set (match_operand:SF 0 "register_operand" "=f,f")
14243         (match_operator:SF 3 "binary_fp_operator"
14244                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14245                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14246   "TARGET_80387
14247    && !COMMUTATIVE_ARITH_P (operands[3])
14248    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14249   "* return output_387_binary_op (insn, operands);"
14250   [(set (attr "type") 
14251         (cond [(match_operand:SF 3 "mult_operator" "") 
14252                  (const_string "fmul")
14253                (match_operand:SF 3 "div_operator" "") 
14254                  (const_string "fdiv")
14255               ]
14256               (const_string "fop")))
14257    (set_attr "mode" "SF")])
14258
14259
14260 ;; ??? Add SSE splitters for these!
14261 (define_insn "*fop_sf_2_i387"
14262   [(set (match_operand:SF 0 "register_operand" "=f,f")
14263         (match_operator:SF 3 "binary_fp_operator"
14264           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14265            (match_operand:SF 2 "register_operand" "0,0")]))]
14266   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14267   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14268   [(set (attr "type") 
14269         (cond [(match_operand:SF 3 "mult_operator" "") 
14270                  (const_string "fmul")
14271                (match_operand:SF 3 "div_operator" "") 
14272                  (const_string "fdiv")
14273               ]
14274               (const_string "fop")))
14275    (set_attr "fp_int_src" "true")
14276    (set_attr "mode" "SI")])
14277
14278 (define_insn "*fop_sf_3_i387"
14279   [(set (match_operand:SF 0 "register_operand" "=f,f")
14280         (match_operator:SF 3 "binary_fp_operator"
14281           [(match_operand:SF 1 "register_operand" "0,0")
14282            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14283   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14284   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14285   [(set (attr "type") 
14286         (cond [(match_operand:SF 3 "mult_operator" "") 
14287                  (const_string "fmul")
14288                (match_operand:SF 3 "div_operator" "") 
14289                  (const_string "fdiv")
14290               ]
14291               (const_string "fop")))
14292    (set_attr "fp_int_src" "true")
14293    (set_attr "mode" "SI")])
14294
14295 (define_insn "*fop_df_comm_mixed"
14296   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14297         (match_operator:DF 3 "binary_fp_operator"
14298                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14299                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14300   "TARGET_SSE2 && TARGET_MIX_SSE_I387
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 (eq_attr "alternative" "1")
14306            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14307               (const_string "ssemul")
14308               (const_string "sseadd"))
14309            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14310               (const_string "fmul")
14311               (const_string "fop"))))
14312    (set_attr "mode" "DF")])
14313
14314 (define_insn "*fop_df_comm_sse"
14315   [(set (match_operand:DF 0 "register_operand" "=Y")
14316         (match_operator:DF 3 "binary_fp_operator"
14317                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14318                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14319   "TARGET_SSE2 && TARGET_SSE_MATH
14320    && COMMUTATIVE_ARITH_P (operands[3])
14321    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14322   "* return output_387_binary_op (insn, operands);"
14323   [(set (attr "type") 
14324         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14325            (const_string "ssemul")
14326            (const_string "sseadd")))
14327    (set_attr "mode" "DF")])
14328
14329 (define_insn "*fop_df_comm_i387"
14330   [(set (match_operand:DF 0 "register_operand" "=f")
14331         (match_operator:DF 3 "binary_fp_operator"
14332                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14333                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14334   "TARGET_80387
14335    && COMMUTATIVE_ARITH_P (operands[3])
14336    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14337   "* return output_387_binary_op (insn, operands);"
14338   [(set (attr "type") 
14339         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14340            (const_string "fmul")
14341            (const_string "fop")))
14342    (set_attr "mode" "DF")])
14343
14344 (define_insn "*fop_df_1_mixed"
14345   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14346         (match_operator:DF 3 "binary_fp_operator"
14347                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14348                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14349   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14350    && !COMMUTATIVE_ARITH_P (operands[3])
14351    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14352   "* return output_387_binary_op (insn, operands);"
14353   [(set (attr "type") 
14354         (cond [(and (eq_attr "alternative" "2")
14355                     (match_operand:SF 3 "mult_operator" ""))
14356                  (const_string "ssemul")
14357                (and (eq_attr "alternative" "2")
14358                     (match_operand:SF 3 "div_operator" ""))
14359                  (const_string "ssediv")
14360                (eq_attr "alternative" "2")
14361                  (const_string "sseadd")
14362                (match_operand:DF 3 "mult_operator" "") 
14363                  (const_string "fmul")
14364                (match_operand:DF 3 "div_operator" "") 
14365                  (const_string "fdiv")
14366               ]
14367               (const_string "fop")))
14368    (set_attr "mode" "DF")])
14369
14370 (define_insn "*fop_df_1_sse"
14371   [(set (match_operand:DF 0 "register_operand" "=Y")
14372         (match_operator:DF 3 "binary_fp_operator"
14373                         [(match_operand:DF 1 "register_operand" "0")
14374                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14375   "TARGET_SSE2 && TARGET_SSE_MATH
14376    && !COMMUTATIVE_ARITH_P (operands[3])"
14377   "* return output_387_binary_op (insn, operands);"
14378   [(set_attr "mode" "DF")
14379    (set (attr "type") 
14380         (cond [(match_operand:SF 3 "mult_operator" "")
14381                  (const_string "ssemul")
14382                (match_operand:SF 3 "div_operator" "")
14383                  (const_string "ssediv")
14384               ]
14385               (const_string "sseadd")))])
14386
14387 (define_insn "*fop_df_1_i387"
14388   [(set (match_operand:DF 0 "register_operand" "=f,f")
14389         (match_operator:DF 3 "binary_fp_operator"
14390                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14391                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14392   "TARGET_80387
14393    && !COMMUTATIVE_ARITH_P (operands[3])
14394    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14395   "* return output_387_binary_op (insn, operands);"
14396   [(set (attr "type") 
14397         (cond [(match_operand:DF 3 "mult_operator" "") 
14398                  (const_string "fmul")
14399                (match_operand:DF 3 "div_operator" "")
14400                  (const_string "fdiv")
14401               ]
14402               (const_string "fop")))
14403    (set_attr "mode" "DF")])
14404
14405 ;; ??? Add SSE splitters for these!
14406 (define_insn "*fop_df_2_i387"
14407   [(set (match_operand:DF 0 "register_operand" "=f,f")
14408         (match_operator:DF 3 "binary_fp_operator"
14409            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14410             (match_operand:DF 2 "register_operand" "0,0")]))]
14411   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14412   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14413   [(set (attr "type") 
14414         (cond [(match_operand:DF 3 "mult_operator" "") 
14415                  (const_string "fmul")
14416                (match_operand:DF 3 "div_operator" "") 
14417                  (const_string "fdiv")
14418               ]
14419               (const_string "fop")))
14420    (set_attr "fp_int_src" "true")
14421    (set_attr "mode" "SI")])
14422
14423 (define_insn "*fop_df_3_i387"
14424   [(set (match_operand:DF 0 "register_operand" "=f,f")
14425         (match_operator:DF 3 "binary_fp_operator"
14426            [(match_operand:DF 1 "register_operand" "0,0")
14427             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14428   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14429   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14430   [(set (attr "type") 
14431         (cond [(match_operand:DF 3 "mult_operator" "") 
14432                  (const_string "fmul")
14433                (match_operand:DF 3 "div_operator" "") 
14434                  (const_string "fdiv")
14435               ]
14436               (const_string "fop")))
14437    (set_attr "fp_int_src" "true")
14438    (set_attr "mode" "SI")])
14439
14440 (define_insn "*fop_df_4_i387"
14441   [(set (match_operand:DF 0 "register_operand" "=f,f")
14442         (match_operator:DF 3 "binary_fp_operator"
14443            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14444             (match_operand:DF 2 "register_operand" "0,f")]))]
14445   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14446    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14447   "* return output_387_binary_op (insn, operands);"
14448   [(set (attr "type") 
14449         (cond [(match_operand:DF 3 "mult_operator" "") 
14450                  (const_string "fmul")
14451                (match_operand:DF 3 "div_operator" "") 
14452                  (const_string "fdiv")
14453               ]
14454               (const_string "fop")))
14455    (set_attr "mode" "SF")])
14456
14457 (define_insn "*fop_df_5_i387"
14458   [(set (match_operand:DF 0 "register_operand" "=f,f")
14459         (match_operator:DF 3 "binary_fp_operator"
14460           [(match_operand:DF 1 "register_operand" "0,f")
14461            (float_extend:DF
14462             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14463   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14464   "* return output_387_binary_op (insn, operands);"
14465   [(set (attr "type") 
14466         (cond [(match_operand:DF 3 "mult_operator" "") 
14467                  (const_string "fmul")
14468                (match_operand:DF 3 "div_operator" "") 
14469                  (const_string "fdiv")
14470               ]
14471               (const_string "fop")))
14472    (set_attr "mode" "SF")])
14473
14474 (define_insn "*fop_df_6_i387"
14475   [(set (match_operand:DF 0 "register_operand" "=f,f")
14476         (match_operator:DF 3 "binary_fp_operator"
14477           [(float_extend:DF
14478             (match_operand:SF 1 "register_operand" "0,f"))
14479            (float_extend:DF
14480             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14481   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14482   "* return output_387_binary_op (insn, operands);"
14483   [(set (attr "type") 
14484         (cond [(match_operand:DF 3 "mult_operator" "") 
14485                  (const_string "fmul")
14486                (match_operand:DF 3 "div_operator" "") 
14487                  (const_string "fdiv")
14488               ]
14489               (const_string "fop")))
14490    (set_attr "mode" "SF")])
14491
14492 (define_insn "*fop_xf_comm_i387"
14493   [(set (match_operand:XF 0 "register_operand" "=f")
14494         (match_operator:XF 3 "binary_fp_operator"
14495                         [(match_operand:XF 1 "register_operand" "%0")
14496                          (match_operand:XF 2 "register_operand" "f")]))]
14497   "TARGET_80387
14498    && COMMUTATIVE_ARITH_P (operands[3])"
14499   "* return output_387_binary_op (insn, operands);"
14500   [(set (attr "type") 
14501         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14502            (const_string "fmul")
14503            (const_string "fop")))
14504    (set_attr "mode" "XF")])
14505
14506 (define_insn "*fop_xf_1_i387"
14507   [(set (match_operand:XF 0 "register_operand" "=f,f")
14508         (match_operator:XF 3 "binary_fp_operator"
14509                         [(match_operand:XF 1 "register_operand" "0,f")
14510                          (match_operand:XF 2 "register_operand" "f,0")]))]
14511   "TARGET_80387
14512    && !COMMUTATIVE_ARITH_P (operands[3])"
14513   "* return 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 "mode" "XF")])
14522
14523 (define_insn "*fop_xf_2_i387"
14524   [(set (match_operand:XF 0 "register_operand" "=f,f")
14525         (match_operator:XF 3 "binary_fp_operator"
14526            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14527             (match_operand:XF 2 "register_operand" "0,0")]))]
14528   "TARGET_80387 && TARGET_USE_FIOP"
14529   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14530   [(set (attr "type") 
14531         (cond [(match_operand:XF 3 "mult_operator" "") 
14532                  (const_string "fmul")
14533                (match_operand:XF 3 "div_operator" "") 
14534                  (const_string "fdiv")
14535               ]
14536               (const_string "fop")))
14537    (set_attr "fp_int_src" "true")
14538    (set_attr "mode" "SI")])
14539
14540 (define_insn "*fop_xf_3_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,0")
14544            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14545   "TARGET_80387 && TARGET_USE_FIOP"
14546   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14547   [(set (attr "type") 
14548         (cond [(match_operand:XF 3 "mult_operator" "") 
14549                  (const_string "fmul")
14550                (match_operand:XF 3 "div_operator" "") 
14551                  (const_string "fdiv")
14552               ]
14553               (const_string "fop")))
14554    (set_attr "fp_int_src" "true")
14555    (set_attr "mode" "SI")])
14556
14557 (define_insn "*fop_xf_4_i387"
14558   [(set (match_operand:XF 0 "register_operand" "=f,f")
14559         (match_operator:XF 3 "binary_fp_operator"
14560            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14561             (match_operand:XF 2 "register_operand" "0,f")]))]
14562   "TARGET_80387"
14563   "* return output_387_binary_op (insn, operands);"
14564   [(set (attr "type") 
14565         (cond [(match_operand:XF 3 "mult_operator" "") 
14566                  (const_string "fmul")
14567                (match_operand:XF 3 "div_operator" "") 
14568                  (const_string "fdiv")
14569               ]
14570               (const_string "fop")))
14571    (set_attr "mode" "SF")])
14572
14573 (define_insn "*fop_xf_5_i387"
14574   [(set (match_operand:XF 0 "register_operand" "=f,f")
14575         (match_operator:XF 3 "binary_fp_operator"
14576           [(match_operand:XF 1 "register_operand" "0,f")
14577            (float_extend:XF
14578             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14579   "TARGET_80387"
14580   "* return output_387_binary_op (insn, operands);"
14581   [(set (attr "type") 
14582         (cond [(match_operand:XF 3 "mult_operator" "") 
14583                  (const_string "fmul")
14584                (match_operand:XF 3 "div_operator" "") 
14585                  (const_string "fdiv")
14586               ]
14587               (const_string "fop")))
14588    (set_attr "mode" "SF")])
14589
14590 (define_insn "*fop_xf_6_i387"
14591   [(set (match_operand:XF 0 "register_operand" "=f,f")
14592         (match_operator:XF 3 "binary_fp_operator"
14593           [(float_extend:XF
14594             (match_operand 1 "register_operand" "0,f"))
14595            (float_extend:XF
14596             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14597   "TARGET_80387"
14598   "* return output_387_binary_op (insn, operands);"
14599   [(set (attr "type") 
14600         (cond [(match_operand:XF 3 "mult_operator" "") 
14601                  (const_string "fmul")
14602                (match_operand:XF 3 "div_operator" "") 
14603                  (const_string "fdiv")
14604               ]
14605               (const_string "fop")))
14606    (set_attr "mode" "SF")])
14607
14608 (define_split
14609   [(set (match_operand 0 "register_operand" "")
14610         (match_operator 3 "binary_fp_operator"
14611            [(float (match_operand:SI 1 "register_operand" ""))
14612             (match_operand 2 "register_operand" "")]))]
14613   "TARGET_80387 && reload_completed
14614    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14615   [(const_int 0)]
14616
14617   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14618   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14619   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14620                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14621                                           GET_MODE (operands[3]),
14622                                           operands[4],
14623                                           operands[2])));
14624   ix86_free_from_memory (GET_MODE (operands[1]));
14625   DONE;
14626 })
14627
14628 (define_split
14629   [(set (match_operand 0 "register_operand" "")
14630         (match_operator 3 "binary_fp_operator"
14631            [(match_operand 1 "register_operand" "")
14632             (float (match_operand:SI 2 "register_operand" ""))]))]
14633   "TARGET_80387 && reload_completed
14634    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14635   [(const_int 0)]
14636 {
14637   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14638   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14639   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14640                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14641                                           GET_MODE (operands[3]),
14642                                           operands[1],
14643                                           operands[4])));
14644   ix86_free_from_memory (GET_MODE (operands[2]));
14645   DONE;
14646 })
14647 \f
14648 ;; FPU special functions.
14649
14650 (define_expand "sqrtsf2"
14651   [(set (match_operand:SF 0 "register_operand" "")
14652         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14653   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14654 {
14655   if (!TARGET_SSE_MATH)
14656     operands[1] = force_reg (SFmode, operands[1]);
14657 })
14658
14659 (define_insn "*sqrtsf2_mixed"
14660   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14661         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14662   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14663   "@
14664    fsqrt
14665    sqrtss\t{%1, %0|%0, %1}"
14666   [(set_attr "type" "fpspc,sse")
14667    (set_attr "mode" "SF,SF")
14668    (set_attr "athlon_decode" "direct,*")])
14669
14670 (define_insn "*sqrtsf2_sse"
14671   [(set (match_operand:SF 0 "register_operand" "=x")
14672         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14673   "TARGET_SSE_MATH"
14674   "sqrtss\t{%1, %0|%0, %1}"
14675   [(set_attr "type" "sse")
14676    (set_attr "mode" "SF")
14677    (set_attr "athlon_decode" "*")])
14678
14679 (define_insn "*sqrtsf2_i387"
14680   [(set (match_operand:SF 0 "register_operand" "=f")
14681         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14682   "TARGET_USE_FANCY_MATH_387"
14683   "fsqrt"
14684   [(set_attr "type" "fpspc")
14685    (set_attr "mode" "SF")
14686    (set_attr "athlon_decode" "direct")])
14687
14688 (define_expand "sqrtdf2"
14689   [(set (match_operand:DF 0 "register_operand" "")
14690         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14691   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14692 {
14693   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14694     operands[1] = force_reg (DFmode, operands[1]);
14695 })
14696
14697 (define_insn "*sqrtdf2_mixed"
14698   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14699         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14700   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14701   "@
14702    fsqrt
14703    sqrtsd\t{%1, %0|%0, %1}"
14704   [(set_attr "type" "fpspc,sse")
14705    (set_attr "mode" "DF,DF")
14706    (set_attr "athlon_decode" "direct,*")])
14707
14708 (define_insn "*sqrtdf2_sse"
14709   [(set (match_operand:DF 0 "register_operand" "=Y")
14710         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14711   "TARGET_SSE2 && TARGET_SSE_MATH"
14712   "sqrtsd\t{%1, %0|%0, %1}"
14713   [(set_attr "type" "sse")
14714    (set_attr "mode" "DF")
14715    (set_attr "athlon_decode" "*")])
14716
14717 (define_insn "*sqrtdf2_i387"
14718   [(set (match_operand:DF 0 "register_operand" "=f")
14719         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14720   "TARGET_USE_FANCY_MATH_387"
14721   "fsqrt"
14722   [(set_attr "type" "fpspc")
14723    (set_attr "mode" "DF")
14724    (set_attr "athlon_decode" "direct")])
14725
14726 (define_insn "*sqrtextendsfdf2_i387"
14727   [(set (match_operand:DF 0 "register_operand" "=f")
14728         (sqrt:DF (float_extend:DF
14729                   (match_operand:SF 1 "register_operand" "0"))))]
14730   "TARGET_USE_FANCY_MATH_387
14731    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14732   "fsqrt"
14733   [(set_attr "type" "fpspc")
14734    (set_attr "mode" "DF")
14735    (set_attr "athlon_decode" "direct")])
14736
14737 (define_insn "sqrtxf2"
14738   [(set (match_operand:XF 0 "register_operand" "=f")
14739         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14740   "TARGET_USE_FANCY_MATH_387 
14741    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14742   "fsqrt"
14743   [(set_attr "type" "fpspc")
14744    (set_attr "mode" "XF")
14745    (set_attr "athlon_decode" "direct")])
14746
14747 (define_insn "*sqrtextendsfxf2_i387"
14748   [(set (match_operand:XF 0 "register_operand" "=f")
14749         (sqrt:XF (float_extend:XF
14750                   (match_operand:SF 1 "register_operand" "0"))))]
14751   "TARGET_USE_FANCY_MATH_387"
14752   "fsqrt"
14753   [(set_attr "type" "fpspc")
14754    (set_attr "mode" "XF")
14755    (set_attr "athlon_decode" "direct")])
14756
14757 (define_insn "*sqrtextenddfxf2_i387"
14758   [(set (match_operand:XF 0 "register_operand" "=f")
14759         (sqrt:XF (float_extend:XF
14760                   (match_operand:DF 1 "register_operand" "0"))))]
14761   "TARGET_USE_FANCY_MATH_387"
14762   "fsqrt"
14763   [(set_attr "type" "fpspc")
14764    (set_attr "mode" "XF")
14765    (set_attr "athlon_decode" "direct")])
14766
14767 (define_insn "fpremxf4"
14768   [(set (match_operand:XF 0 "register_operand" "=f")
14769         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14770                     (match_operand:XF 3 "register_operand" "1")]
14771                    UNSPEC_FPREM_F))
14772    (set (match_operand:XF 1 "register_operand" "=u")
14773         (unspec:XF [(match_dup 2) (match_dup 3)]
14774                    UNSPEC_FPREM_U))
14775    (set (reg:CCFP FPSR_REG)
14776         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14777   "TARGET_USE_FANCY_MATH_387
14778    && flag_unsafe_math_optimizations"
14779   "fprem"
14780   [(set_attr "type" "fpspc")
14781    (set_attr "mode" "XF")])
14782
14783 (define_expand "fmodsf3"
14784   [(use (match_operand:SF 0 "register_operand" ""))
14785    (use (match_operand:SF 1 "register_operand" ""))
14786    (use (match_operand:SF 2 "register_operand" ""))]
14787   "TARGET_USE_FANCY_MATH_387
14788    && flag_unsafe_math_optimizations"
14789 {
14790   rtx label = gen_label_rtx ();
14791
14792   rtx op1 = gen_reg_rtx (XFmode);
14793   rtx op2 = gen_reg_rtx (XFmode);
14794
14795   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14796   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14797
14798   emit_label (label);
14799
14800   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14801   ix86_emit_fp_unordered_jump (label);
14802
14803   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14804   DONE;
14805 })
14806
14807 (define_expand "fmoddf3"
14808   [(use (match_operand:DF 0 "register_operand" ""))
14809    (use (match_operand:DF 1 "register_operand" ""))
14810    (use (match_operand:DF 2 "register_operand" ""))]
14811   "TARGET_USE_FANCY_MATH_387
14812    && flag_unsafe_math_optimizations"
14813 {
14814   rtx label = gen_label_rtx ();
14815
14816   rtx op1 = gen_reg_rtx (XFmode);
14817   rtx op2 = gen_reg_rtx (XFmode);
14818
14819   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14820   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14821
14822   emit_label (label);
14823
14824   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14825   ix86_emit_fp_unordered_jump (label);
14826
14827   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14828   DONE;
14829 })
14830
14831 (define_expand "fmodxf3"
14832   [(use (match_operand:XF 0 "register_operand" ""))
14833    (use (match_operand:XF 1 "register_operand" ""))
14834    (use (match_operand:XF 2 "register_operand" ""))]
14835   "TARGET_USE_FANCY_MATH_387
14836    && flag_unsafe_math_optimizations"
14837 {
14838   rtx label = gen_label_rtx ();
14839
14840   emit_label (label);
14841
14842   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14843                            operands[1], operands[2]));
14844   ix86_emit_fp_unordered_jump (label);
14845
14846   emit_move_insn (operands[0], operands[1]);
14847   DONE;
14848 })
14849
14850 (define_insn "fprem1xf4"
14851   [(set (match_operand:XF 0 "register_operand" "=f")
14852         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14853                     (match_operand:XF 3 "register_operand" "1")]
14854                    UNSPEC_FPREM1_F))
14855    (set (match_operand:XF 1 "register_operand" "=u")
14856         (unspec:XF [(match_dup 2) (match_dup 3)]
14857                    UNSPEC_FPREM1_U))
14858    (set (reg:CCFP FPSR_REG)
14859         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14860   "TARGET_USE_FANCY_MATH_387
14861    && flag_unsafe_math_optimizations"
14862   "fprem1"
14863   [(set_attr "type" "fpspc")
14864    (set_attr "mode" "XF")])
14865
14866 (define_expand "dremsf3"
14867   [(use (match_operand:SF 0 "register_operand" ""))
14868    (use (match_operand:SF 1 "register_operand" ""))
14869    (use (match_operand:SF 2 "register_operand" ""))]
14870   "TARGET_USE_FANCY_MATH_387
14871    && flag_unsafe_math_optimizations"
14872 {
14873   rtx label = gen_label_rtx ();
14874
14875   rtx op1 = gen_reg_rtx (XFmode);
14876   rtx op2 = gen_reg_rtx (XFmode);
14877
14878   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14879   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14880
14881   emit_label (label);
14882
14883   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14884   ix86_emit_fp_unordered_jump (label);
14885
14886   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14887   DONE;
14888 })
14889
14890 (define_expand "dremdf3"
14891   [(use (match_operand:DF 0 "register_operand" ""))
14892    (use (match_operand:DF 1 "register_operand" ""))
14893    (use (match_operand:DF 2 "register_operand" ""))]
14894   "TARGET_USE_FANCY_MATH_387
14895    && flag_unsafe_math_optimizations"
14896 {
14897   rtx label = gen_label_rtx ();
14898
14899   rtx op1 = gen_reg_rtx (XFmode);
14900   rtx op2 = gen_reg_rtx (XFmode);
14901
14902   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14903   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14904
14905   emit_label (label);
14906
14907   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14908   ix86_emit_fp_unordered_jump (label);
14909
14910   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14911   DONE;
14912 })
14913
14914 (define_expand "dremxf3"
14915   [(use (match_operand:XF 0 "register_operand" ""))
14916    (use (match_operand:XF 1 "register_operand" ""))
14917    (use (match_operand:XF 2 "register_operand" ""))]
14918   "TARGET_USE_FANCY_MATH_387
14919    && flag_unsafe_math_optimizations"
14920 {
14921   rtx label = gen_label_rtx ();
14922
14923   emit_label (label);
14924
14925   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14926                             operands[1], operands[2]));
14927   ix86_emit_fp_unordered_jump (label);
14928
14929   emit_move_insn (operands[0], operands[1]);
14930   DONE;
14931 })
14932
14933 (define_insn "*sindf2"
14934   [(set (match_operand:DF 0 "register_operand" "=f")
14935         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14936   "TARGET_USE_FANCY_MATH_387
14937    && flag_unsafe_math_optimizations"
14938   "fsin"
14939   [(set_attr "type" "fpspc")
14940    (set_attr "mode" "DF")])
14941
14942 (define_insn "*sinsf2"
14943   [(set (match_operand:SF 0 "register_operand" "=f")
14944         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14945   "TARGET_USE_FANCY_MATH_387
14946    && flag_unsafe_math_optimizations"
14947   "fsin"
14948   [(set_attr "type" "fpspc")
14949    (set_attr "mode" "SF")])
14950
14951 (define_insn "*sinextendsfdf2"
14952   [(set (match_operand:DF 0 "register_operand" "=f")
14953         (unspec:DF [(float_extend:DF
14954                      (match_operand:SF 1 "register_operand" "0"))]
14955                    UNSPEC_SIN))]
14956   "TARGET_USE_FANCY_MATH_387
14957    && flag_unsafe_math_optimizations"
14958   "fsin"
14959   [(set_attr "type" "fpspc")
14960    (set_attr "mode" "DF")])
14961
14962 (define_insn "*sinxf2"
14963   [(set (match_operand:XF 0 "register_operand" "=f")
14964         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14965   "TARGET_USE_FANCY_MATH_387
14966    && flag_unsafe_math_optimizations"
14967   "fsin"
14968   [(set_attr "type" "fpspc")
14969    (set_attr "mode" "XF")])
14970
14971 (define_insn "*cosdf2"
14972   [(set (match_operand:DF 0 "register_operand" "=f")
14973         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14974   "TARGET_USE_FANCY_MATH_387
14975    && flag_unsafe_math_optimizations"
14976   "fcos"
14977   [(set_attr "type" "fpspc")
14978    (set_attr "mode" "DF")])
14979
14980 (define_insn "*cossf2"
14981   [(set (match_operand:SF 0 "register_operand" "=f")
14982         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14983   "TARGET_USE_FANCY_MATH_387
14984    && flag_unsafe_math_optimizations"
14985   "fcos"
14986   [(set_attr "type" "fpspc")
14987    (set_attr "mode" "SF")])
14988
14989 (define_insn "*cosextendsfdf2"
14990   [(set (match_operand:DF 0 "register_operand" "=f")
14991         (unspec:DF [(float_extend:DF
14992                      (match_operand:SF 1 "register_operand" "0"))]
14993                    UNSPEC_COS))]
14994   "TARGET_USE_FANCY_MATH_387
14995    && flag_unsafe_math_optimizations"
14996   "fcos"
14997   [(set_attr "type" "fpspc")
14998    (set_attr "mode" "DF")])
14999
15000 (define_insn "*cosxf2"
15001   [(set (match_operand:XF 0 "register_operand" "=f")
15002         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15003   "TARGET_USE_FANCY_MATH_387
15004    && flag_unsafe_math_optimizations"
15005   "fcos"
15006   [(set_attr "type" "fpspc")
15007    (set_attr "mode" "XF")])
15008
15009 ;; With sincos pattern defined, sin and cos builtin function will be
15010 ;; expanded to sincos pattern with one of its outputs left unused. 
15011 ;; Cse pass  will detected, if two sincos patterns can be combined,
15012 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15013 ;; depending on the unused output.
15014
15015 (define_insn "sincosdf3"
15016   [(set (match_operand:DF 0 "register_operand" "=f")
15017         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15018                    UNSPEC_SINCOS_COS))
15019    (set (match_operand:DF 1 "register_operand" "=u")
15020         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15021   "TARGET_USE_FANCY_MATH_387
15022    && flag_unsafe_math_optimizations"
15023   "fsincos"
15024   [(set_attr "type" "fpspc")
15025    (set_attr "mode" "DF")])
15026
15027 (define_split
15028   [(set (match_operand:DF 0 "register_operand" "")
15029         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15030                    UNSPEC_SINCOS_COS))
15031    (set (match_operand:DF 1 "register_operand" "")
15032         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15033   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15034    && !reload_completed && !reload_in_progress"
15035   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15036   "")
15037
15038 (define_split
15039   [(set (match_operand:DF 0 "register_operand" "")
15040         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15041                    UNSPEC_SINCOS_COS))
15042    (set (match_operand:DF 1 "register_operand" "")
15043         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15044   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15045    && !reload_completed && !reload_in_progress"
15046   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15047   "")
15048
15049 (define_insn "sincossf3"
15050   [(set (match_operand:SF 0 "register_operand" "=f")
15051         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15052                    UNSPEC_SINCOS_COS))
15053    (set (match_operand:SF 1 "register_operand" "=u")
15054         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15055   "TARGET_USE_FANCY_MATH_387
15056    && flag_unsafe_math_optimizations"
15057   "fsincos"
15058   [(set_attr "type" "fpspc")
15059    (set_attr "mode" "SF")])
15060
15061 (define_split
15062   [(set (match_operand:SF 0 "register_operand" "")
15063         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15064                    UNSPEC_SINCOS_COS))
15065    (set (match_operand:SF 1 "register_operand" "")
15066         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15067   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15068    && !reload_completed && !reload_in_progress"
15069   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15070   "")
15071
15072 (define_split
15073   [(set (match_operand:SF 0 "register_operand" "")
15074         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15075                    UNSPEC_SINCOS_COS))
15076    (set (match_operand:SF 1 "register_operand" "")
15077         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15078   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15079    && !reload_completed && !reload_in_progress"
15080   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15081   "")
15082
15083 (define_insn "*sincosextendsfdf3"
15084   [(set (match_operand:DF 0 "register_operand" "=f")
15085         (unspec:DF [(float_extend:DF
15086                      (match_operand:SF 2 "register_operand" "0"))]
15087                    UNSPEC_SINCOS_COS))
15088    (set (match_operand:DF 1 "register_operand" "=u")
15089         (unspec:DF [(float_extend:DF
15090                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15091   "TARGET_USE_FANCY_MATH_387
15092    && flag_unsafe_math_optimizations"
15093   "fsincos"
15094   [(set_attr "type" "fpspc")
15095    (set_attr "mode" "DF")])
15096
15097 (define_split
15098   [(set (match_operand:DF 0 "register_operand" "")
15099         (unspec:DF [(float_extend:DF
15100                      (match_operand:SF 2 "register_operand" ""))]
15101                    UNSPEC_SINCOS_COS))
15102    (set (match_operand:DF 1 "register_operand" "")
15103         (unspec:DF [(float_extend:DF
15104                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15105   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15106    && !reload_completed && !reload_in_progress"
15107   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15108                                    (match_dup 2))] UNSPEC_SIN))]
15109   "")
15110
15111 (define_split
15112   [(set (match_operand:DF 0 "register_operand" "")
15113         (unspec:DF [(float_extend:DF
15114                      (match_operand:SF 2 "register_operand" ""))]
15115                    UNSPEC_SINCOS_COS))
15116    (set (match_operand:DF 1 "register_operand" "")
15117         (unspec:DF [(float_extend:DF
15118                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15119   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15120    && !reload_completed && !reload_in_progress"
15121   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15122                                    (match_dup 2))] UNSPEC_COS))]
15123   "")
15124
15125 (define_insn "sincosxf3"
15126   [(set (match_operand:XF 0 "register_operand" "=f")
15127         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15128                    UNSPEC_SINCOS_COS))
15129    (set (match_operand:XF 1 "register_operand" "=u")
15130         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15131   "TARGET_USE_FANCY_MATH_387
15132    && flag_unsafe_math_optimizations"
15133   "fsincos"
15134   [(set_attr "type" "fpspc")
15135    (set_attr "mode" "XF")])
15136
15137 (define_split
15138   [(set (match_operand:XF 0 "register_operand" "")
15139         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15140                    UNSPEC_SINCOS_COS))
15141    (set (match_operand:XF 1 "register_operand" "")
15142         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15143   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15144    && !reload_completed && !reload_in_progress"
15145   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15146   "")
15147
15148 (define_split
15149   [(set (match_operand:XF 0 "register_operand" "")
15150         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15151                    UNSPEC_SINCOS_COS))
15152    (set (match_operand:XF 1 "register_operand" "")
15153         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15154   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15155    && !reload_completed && !reload_in_progress"
15156   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15157   "")
15158
15159 (define_insn "*tandf3_1"
15160   [(set (match_operand:DF 0 "register_operand" "=f")
15161         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15162                    UNSPEC_TAN_ONE))
15163    (set (match_operand:DF 1 "register_operand" "=u")
15164         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15165   "TARGET_USE_FANCY_MATH_387
15166    && flag_unsafe_math_optimizations"
15167   "fptan"
15168   [(set_attr "type" "fpspc")
15169    (set_attr "mode" "DF")])
15170
15171 ;; optimize sequence: fptan
15172 ;;                    fstp    %st(0)
15173 ;;                    fld1
15174 ;; into fptan insn.
15175
15176 (define_peephole2
15177   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15178                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15179                              UNSPEC_TAN_ONE))
15180              (set (match_operand:DF 1 "register_operand" "")
15181                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15182    (set (match_dup 0)
15183         (match_operand:DF 3 "immediate_operand" ""))]
15184   "standard_80387_constant_p (operands[3]) == 2"
15185   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15186              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15187   "")
15188
15189 (define_expand "tandf2"
15190   [(parallel [(set (match_dup 2)
15191                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15192                               UNSPEC_TAN_ONE))
15193               (set (match_operand:DF 0 "register_operand" "")
15194                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15195   "TARGET_USE_FANCY_MATH_387
15196    && flag_unsafe_math_optimizations"
15197 {
15198   operands[2] = gen_reg_rtx (DFmode);
15199 })
15200
15201 (define_insn "*tansf3_1"
15202   [(set (match_operand:SF 0 "register_operand" "=f")
15203         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15204                    UNSPEC_TAN_ONE))
15205    (set (match_operand:SF 1 "register_operand" "=u")
15206         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15207   "TARGET_USE_FANCY_MATH_387
15208    && flag_unsafe_math_optimizations"
15209   "fptan"
15210   [(set_attr "type" "fpspc")
15211    (set_attr "mode" "SF")])
15212
15213 ;; optimize sequence: fptan
15214 ;;                    fstp    %st(0)
15215 ;;                    fld1
15216 ;; into fptan insn.
15217
15218 (define_peephole2
15219   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15220                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15221                              UNSPEC_TAN_ONE))
15222              (set (match_operand:SF 1 "register_operand" "")
15223                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15224    (set (match_dup 0)
15225         (match_operand:SF 3 "immediate_operand" ""))]
15226   "standard_80387_constant_p (operands[3]) == 2"
15227   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15228              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15229   "")
15230
15231 (define_expand "tansf2"
15232   [(parallel [(set (match_dup 2)
15233                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15234                               UNSPEC_TAN_ONE))
15235               (set (match_operand:SF 0 "register_operand" "")
15236                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15237   "TARGET_USE_FANCY_MATH_387
15238    && flag_unsafe_math_optimizations"
15239 {
15240   operands[2] = gen_reg_rtx (SFmode);
15241 })
15242
15243 (define_insn "*tanxf3_1"
15244   [(set (match_operand:XF 0 "register_operand" "=f")
15245         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15246                    UNSPEC_TAN_ONE))
15247    (set (match_operand:XF 1 "register_operand" "=u")
15248         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15249   "TARGET_USE_FANCY_MATH_387
15250    && flag_unsafe_math_optimizations"
15251   "fptan"
15252   [(set_attr "type" "fpspc")
15253    (set_attr "mode" "XF")])
15254
15255 ;; optimize sequence: fptan
15256 ;;                    fstp    %st(0)
15257 ;;                    fld1
15258 ;; into fptan insn.
15259
15260 (define_peephole2
15261   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15262                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15263                              UNSPEC_TAN_ONE))
15264              (set (match_operand:XF 1 "register_operand" "")
15265                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15266    (set (match_dup 0)
15267         (match_operand:XF 3 "immediate_operand" ""))]
15268   "standard_80387_constant_p (operands[3]) == 2"
15269   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15270              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15271   "")
15272
15273 (define_expand "tanxf2"
15274   [(parallel [(set (match_dup 2)
15275                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15276                               UNSPEC_TAN_ONE))
15277               (set (match_operand:XF 0 "register_operand" "")
15278                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15279   "TARGET_USE_FANCY_MATH_387
15280    && flag_unsafe_math_optimizations"
15281 {
15282   operands[2] = gen_reg_rtx (XFmode);
15283 })
15284
15285 (define_insn "atan2df3_1"
15286   [(set (match_operand:DF 0 "register_operand" "=f")
15287         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15288                     (match_operand:DF 1 "register_operand" "u")]
15289                    UNSPEC_FPATAN))
15290    (clobber (match_scratch:DF 3 "=1"))]
15291   "TARGET_USE_FANCY_MATH_387
15292    && flag_unsafe_math_optimizations"
15293   "fpatan"
15294   [(set_attr "type" "fpspc")
15295    (set_attr "mode" "DF")])
15296
15297 (define_expand "atan2df3"
15298   [(use (match_operand:DF 0 "register_operand" "=f"))
15299    (use (match_operand:DF 2 "register_operand" "0"))
15300    (use (match_operand:DF 1 "register_operand" "u"))]
15301   "TARGET_USE_FANCY_MATH_387
15302    && flag_unsafe_math_optimizations"
15303 {
15304   rtx copy = gen_reg_rtx (DFmode);
15305   emit_move_insn (copy, operands[1]);
15306   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15307   DONE;
15308 })
15309
15310 (define_expand "atandf2"
15311   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15312                    (unspec:DF [(match_dup 2)
15313                                (match_operand:DF 1 "register_operand" "")]
15314                     UNSPEC_FPATAN))
15315               (clobber (match_scratch:DF 3 ""))])]
15316   "TARGET_USE_FANCY_MATH_387
15317    && flag_unsafe_math_optimizations"
15318 {
15319   operands[2] = gen_reg_rtx (DFmode);
15320   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15321 })
15322
15323 (define_insn "atan2sf3_1"
15324   [(set (match_operand:SF 0 "register_operand" "=f")
15325         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15326                     (match_operand:SF 1 "register_operand" "u")]
15327                    UNSPEC_FPATAN))
15328    (clobber (match_scratch:SF 3 "=1"))]
15329   "TARGET_USE_FANCY_MATH_387
15330    && flag_unsafe_math_optimizations"
15331   "fpatan"
15332   [(set_attr "type" "fpspc")
15333    (set_attr "mode" "SF")])
15334
15335 (define_expand "atan2sf3"
15336   [(use (match_operand:SF 0 "register_operand" "=f"))
15337    (use (match_operand:SF 2 "register_operand" "0"))
15338    (use (match_operand:SF 1 "register_operand" "u"))]
15339   "TARGET_USE_FANCY_MATH_387
15340    && flag_unsafe_math_optimizations"
15341 {
15342   rtx copy = gen_reg_rtx (SFmode);
15343   emit_move_insn (copy, operands[1]);
15344   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15345   DONE;
15346 })
15347
15348 (define_expand "atansf2"
15349   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15350                    (unspec:SF [(match_dup 2)
15351                                (match_operand:SF 1 "register_operand" "")]
15352                     UNSPEC_FPATAN))
15353               (clobber (match_scratch:SF 3 ""))])]
15354   "TARGET_USE_FANCY_MATH_387
15355    && flag_unsafe_math_optimizations"
15356 {
15357   operands[2] = gen_reg_rtx (SFmode);
15358   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15359 })
15360
15361 (define_insn "atan2xf3_1"
15362   [(set (match_operand:XF 0 "register_operand" "=f")
15363         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15364                     (match_operand:XF 1 "register_operand" "u")]
15365                    UNSPEC_FPATAN))
15366    (clobber (match_scratch:XF 3 "=1"))]
15367   "TARGET_USE_FANCY_MATH_387
15368    && flag_unsafe_math_optimizations"
15369   "fpatan"
15370   [(set_attr "type" "fpspc")
15371    (set_attr "mode" "XF")])
15372
15373 (define_expand "atan2xf3"
15374   [(use (match_operand:XF 0 "register_operand" "=f"))
15375    (use (match_operand:XF 2 "register_operand" "0"))
15376    (use (match_operand:XF 1 "register_operand" "u"))]
15377   "TARGET_USE_FANCY_MATH_387
15378    && flag_unsafe_math_optimizations"
15379 {
15380   rtx copy = gen_reg_rtx (XFmode);
15381   emit_move_insn (copy, operands[1]);
15382   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15383   DONE;
15384 })
15385
15386 (define_expand "atanxf2"
15387   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15388                    (unspec:XF [(match_dup 2)
15389                                (match_operand:XF 1 "register_operand" "")]
15390                     UNSPEC_FPATAN))
15391               (clobber (match_scratch:XF 3 ""))])]
15392   "TARGET_USE_FANCY_MATH_387
15393    && flag_unsafe_math_optimizations"
15394 {
15395   operands[2] = gen_reg_rtx (XFmode);
15396   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15397 })
15398
15399 (define_expand "asindf2"
15400   [(set (match_dup 2)
15401         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15402    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15403    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15404    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15405    (parallel [(set (match_dup 7)
15406                    (unspec:XF [(match_dup 6) (match_dup 2)]
15407                               UNSPEC_FPATAN))
15408               (clobber (match_scratch:XF 8 ""))])
15409    (set (match_operand:DF 0 "register_operand" "")
15410         (float_truncate:DF (match_dup 7)))]
15411   "TARGET_USE_FANCY_MATH_387
15412    && flag_unsafe_math_optimizations"
15413 {
15414   int i;
15415
15416   for (i=2; i<8; i++)
15417     operands[i] = gen_reg_rtx (XFmode);
15418
15419   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15420 })
15421
15422 (define_expand "asinsf2"
15423   [(set (match_dup 2)
15424         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15425    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15426    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15427    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15428    (parallel [(set (match_dup 7)
15429                    (unspec:XF [(match_dup 6) (match_dup 2)]
15430                               UNSPEC_FPATAN))
15431               (clobber (match_scratch:XF 8 ""))])
15432    (set (match_operand:SF 0 "register_operand" "")
15433         (float_truncate:SF (match_dup 7)))]
15434   "TARGET_USE_FANCY_MATH_387
15435    && flag_unsafe_math_optimizations"
15436 {
15437   int i;
15438
15439   for (i=2; i<8; i++)
15440     operands[i] = gen_reg_rtx (XFmode);
15441
15442   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15443 })
15444
15445 (define_expand "asinxf2"
15446   [(set (match_dup 2)
15447         (mult:XF (match_operand:XF 1 "register_operand" "")
15448                  (match_dup 1)))
15449    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15450    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15451    (parallel [(set (match_operand:XF 0 "register_operand" "")
15452                    (unspec:XF [(match_dup 5) (match_dup 1)]
15453                               UNSPEC_FPATAN))
15454               (clobber (match_scratch:XF 6 ""))])]
15455   "TARGET_USE_FANCY_MATH_387
15456    && flag_unsafe_math_optimizations"
15457 {
15458   int i;
15459
15460   for (i=2; i<6; i++)
15461     operands[i] = gen_reg_rtx (XFmode);
15462
15463   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15464 })
15465
15466 (define_expand "acosdf2"
15467   [(set (match_dup 2)
15468         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15469    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15470    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15471    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15472    (parallel [(set (match_dup 7)
15473                    (unspec:XF [(match_dup 2) (match_dup 6)]
15474                               UNSPEC_FPATAN))
15475               (clobber (match_scratch:XF 8 ""))])
15476    (set (match_operand:DF 0 "register_operand" "")
15477         (float_truncate:DF (match_dup 7)))]
15478   "TARGET_USE_FANCY_MATH_387
15479    && flag_unsafe_math_optimizations"
15480 {
15481   int i;
15482
15483   for (i=2; i<8; i++)
15484     operands[i] = gen_reg_rtx (XFmode);
15485
15486   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15487 })
15488
15489 (define_expand "acossf2"
15490   [(set (match_dup 2)
15491         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15492    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15493    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15494    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15495    (parallel [(set (match_dup 7)
15496                    (unspec:XF [(match_dup 2) (match_dup 6)]
15497                               UNSPEC_FPATAN))
15498               (clobber (match_scratch:XF 8 ""))])
15499    (set (match_operand:SF 0 "register_operand" "")
15500         (float_truncate:SF (match_dup 7)))]
15501   "TARGET_USE_FANCY_MATH_387
15502    && flag_unsafe_math_optimizations"
15503 {
15504   int i;
15505
15506   for (i=2; i<8; i++)
15507     operands[i] = gen_reg_rtx (XFmode);
15508
15509   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15510 })
15511
15512 (define_expand "acosxf2"
15513   [(set (match_dup 2)
15514         (mult:XF (match_operand:XF 1 "register_operand" "")
15515                  (match_dup 1)))
15516    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15517    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15518    (parallel [(set (match_operand:XF 0 "register_operand" "")
15519                    (unspec:XF [(match_dup 1) (match_dup 5)]
15520                               UNSPEC_FPATAN))
15521               (clobber (match_scratch:XF 6 ""))])]
15522   "TARGET_USE_FANCY_MATH_387
15523    && flag_unsafe_math_optimizations"
15524 {
15525   int i;
15526
15527   for (i=2; i<6; i++)
15528     operands[i] = gen_reg_rtx (XFmode);
15529
15530   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15531 })
15532
15533 (define_insn "fyl2x_xf3"
15534   [(set (match_operand:XF 0 "register_operand" "=f")
15535         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15536                     (match_operand:XF 1 "register_operand" "u")]
15537                    UNSPEC_FYL2X))
15538    (clobber (match_scratch:XF 3 "=1"))]
15539   "TARGET_USE_FANCY_MATH_387
15540    && flag_unsafe_math_optimizations"
15541   "fyl2x"
15542   [(set_attr "type" "fpspc")
15543    (set_attr "mode" "XF")])
15544
15545 (define_expand "logsf2"
15546   [(set (match_dup 2)
15547         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15548    (parallel [(set (match_dup 4)
15549                    (unspec:XF [(match_dup 2)
15550                                (match_dup 3)] UNSPEC_FYL2X))
15551               (clobber (match_scratch:XF 5 ""))])
15552    (set (match_operand:SF 0 "register_operand" "")
15553         (float_truncate:SF (match_dup 4)))]
15554   "TARGET_USE_FANCY_MATH_387
15555    && flag_unsafe_math_optimizations"
15556 {
15557   rtx temp;
15558
15559   operands[2] = gen_reg_rtx (XFmode);
15560   operands[3] = gen_reg_rtx (XFmode);
15561   operands[4] = gen_reg_rtx (XFmode);
15562
15563   temp = standard_80387_constant_rtx (4); /* fldln2 */
15564   emit_move_insn (operands[3], temp);
15565 })
15566
15567 (define_expand "logdf2"
15568   [(set (match_dup 2)
15569         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15570    (parallel [(set (match_dup 4)
15571                    (unspec:XF [(match_dup 2)
15572                                (match_dup 3)] UNSPEC_FYL2X))
15573               (clobber (match_scratch:XF 5 ""))])
15574    (set (match_operand:DF 0 "register_operand" "")
15575         (float_truncate:DF (match_dup 4)))]
15576   "TARGET_USE_FANCY_MATH_387
15577    && flag_unsafe_math_optimizations"
15578 {
15579   rtx temp;
15580
15581   operands[2] = gen_reg_rtx (XFmode);
15582   operands[3] = gen_reg_rtx (XFmode);
15583   operands[4] = gen_reg_rtx (XFmode);
15584
15585   temp = standard_80387_constant_rtx (4); /* fldln2 */
15586   emit_move_insn (operands[3], temp);
15587 })
15588
15589 (define_expand "logxf2"
15590   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15591                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15592                                (match_dup 2)] UNSPEC_FYL2X))
15593               (clobber (match_scratch:XF 3 ""))])]
15594   "TARGET_USE_FANCY_MATH_387
15595    && flag_unsafe_math_optimizations"
15596 {
15597   rtx temp;
15598
15599   operands[2] = gen_reg_rtx (XFmode);
15600   temp = standard_80387_constant_rtx (4); /* fldln2 */
15601   emit_move_insn (operands[2], temp);
15602 })
15603
15604 (define_expand "log10sf2"
15605   [(set (match_dup 2)
15606         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15607    (parallel [(set (match_dup 4)
15608                    (unspec:XF [(match_dup 2)
15609                                (match_dup 3)] UNSPEC_FYL2X))
15610               (clobber (match_scratch:XF 5 ""))])
15611    (set (match_operand:SF 0 "register_operand" "")
15612         (float_truncate:SF (match_dup 4)))]
15613   "TARGET_USE_FANCY_MATH_387
15614    && flag_unsafe_math_optimizations"
15615 {
15616   rtx temp;
15617
15618   operands[2] = gen_reg_rtx (XFmode);
15619   operands[3] = gen_reg_rtx (XFmode);
15620   operands[4] = gen_reg_rtx (XFmode);
15621
15622   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15623   emit_move_insn (operands[3], temp);
15624 })
15625
15626 (define_expand "log10df2"
15627   [(set (match_dup 2)
15628         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15629    (parallel [(set (match_dup 4)
15630                    (unspec:XF [(match_dup 2)
15631                                (match_dup 3)] UNSPEC_FYL2X))
15632               (clobber (match_scratch:XF 5 ""))])
15633    (set (match_operand:DF 0 "register_operand" "")
15634         (float_truncate:DF (match_dup 4)))]
15635   "TARGET_USE_FANCY_MATH_387
15636    && flag_unsafe_math_optimizations"
15637 {
15638   rtx temp;
15639
15640   operands[2] = gen_reg_rtx (XFmode);
15641   operands[3] = gen_reg_rtx (XFmode);
15642   operands[4] = gen_reg_rtx (XFmode);
15643
15644   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15645   emit_move_insn (operands[3], temp);
15646 })
15647
15648 (define_expand "log10xf2"
15649   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15650                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15651                                (match_dup 2)] UNSPEC_FYL2X))
15652               (clobber (match_scratch:XF 3 ""))])]
15653   "TARGET_USE_FANCY_MATH_387
15654    && flag_unsafe_math_optimizations"
15655 {
15656   rtx temp;
15657
15658   operands[2] = gen_reg_rtx (XFmode);
15659   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15660   emit_move_insn (operands[2], temp);
15661 })
15662
15663 (define_expand "log2sf2"
15664   [(set (match_dup 2)
15665         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15666    (parallel [(set (match_dup 4)
15667                    (unspec:XF [(match_dup 2)
15668                                (match_dup 3)] UNSPEC_FYL2X))
15669               (clobber (match_scratch:XF 5 ""))])
15670    (set (match_operand:SF 0 "register_operand" "")
15671         (float_truncate:SF (match_dup 4)))]
15672   "TARGET_USE_FANCY_MATH_387
15673    && flag_unsafe_math_optimizations"
15674 {
15675   operands[2] = gen_reg_rtx (XFmode);
15676   operands[3] = gen_reg_rtx (XFmode);
15677   operands[4] = gen_reg_rtx (XFmode);
15678
15679   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15680 })
15681
15682 (define_expand "log2df2"
15683   [(set (match_dup 2)
15684         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15685    (parallel [(set (match_dup 4)
15686                    (unspec:XF [(match_dup 2)
15687                                (match_dup 3)] UNSPEC_FYL2X))
15688               (clobber (match_scratch:XF 5 ""))])
15689    (set (match_operand:DF 0 "register_operand" "")
15690         (float_truncate:DF (match_dup 4)))]
15691   "TARGET_USE_FANCY_MATH_387
15692    && flag_unsafe_math_optimizations"
15693 {
15694   operands[2] = gen_reg_rtx (XFmode);
15695   operands[3] = gen_reg_rtx (XFmode);
15696   operands[4] = gen_reg_rtx (XFmode);
15697
15698   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15699 })
15700
15701 (define_expand "log2xf2"
15702   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15703                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15704                                (match_dup 2)] UNSPEC_FYL2X))
15705               (clobber (match_scratch:XF 3 ""))])]
15706   "TARGET_USE_FANCY_MATH_387
15707    && flag_unsafe_math_optimizations"
15708 {
15709   operands[2] = gen_reg_rtx (XFmode);
15710   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15711 })
15712
15713 (define_insn "fyl2xp1_xf3"
15714   [(set (match_operand:XF 0 "register_operand" "=f")
15715         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15716                     (match_operand:XF 1 "register_operand" "u")]
15717                    UNSPEC_FYL2XP1))
15718    (clobber (match_scratch:XF 3 "=1"))]
15719   "TARGET_USE_FANCY_MATH_387
15720    && flag_unsafe_math_optimizations"
15721   "fyl2xp1"
15722   [(set_attr "type" "fpspc")
15723    (set_attr "mode" "XF")])
15724
15725 (define_expand "log1psf2"
15726   [(use (match_operand:XF 0 "register_operand" ""))
15727    (use (match_operand:XF 1 "register_operand" ""))]
15728   "TARGET_USE_FANCY_MATH_387
15729    && flag_unsafe_math_optimizations"
15730 {
15731   rtx op0 = gen_reg_rtx (XFmode);
15732   rtx op1 = gen_reg_rtx (XFmode);
15733
15734   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15735   ix86_emit_i387_log1p (op0, op1);
15736   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15737   DONE;
15738 })
15739
15740 (define_expand "log1pdf2"
15741   [(use (match_operand:XF 0 "register_operand" ""))
15742    (use (match_operand:XF 1 "register_operand" ""))]
15743   "TARGET_USE_FANCY_MATH_387
15744    && flag_unsafe_math_optimizations"
15745 {
15746   rtx op0 = gen_reg_rtx (XFmode);
15747   rtx op1 = gen_reg_rtx (XFmode);
15748
15749   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15750   ix86_emit_i387_log1p (op0, op1);
15751   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15752   DONE;
15753 })
15754
15755 (define_expand "log1pxf2"
15756   [(use (match_operand:XF 0 "register_operand" ""))
15757    (use (match_operand:XF 1 "register_operand" ""))]
15758   "TARGET_USE_FANCY_MATH_387
15759    && flag_unsafe_math_optimizations"
15760 {
15761   ix86_emit_i387_log1p (operands[0], operands[1]);
15762   DONE;
15763 })
15764
15765 (define_insn "*fxtractxf3"
15766   [(set (match_operand:XF 0 "register_operand" "=f")
15767         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15768                    UNSPEC_XTRACT_FRACT))
15769    (set (match_operand:XF 1 "register_operand" "=u")
15770         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15771   "TARGET_USE_FANCY_MATH_387
15772    && flag_unsafe_math_optimizations"
15773   "fxtract"
15774   [(set_attr "type" "fpspc")
15775    (set_attr "mode" "XF")])
15776
15777 (define_expand "logbsf2"
15778   [(set (match_dup 2)
15779         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15780    (parallel [(set (match_dup 3)
15781                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15782               (set (match_dup 4)
15783                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15784    (set (match_operand:SF 0 "register_operand" "")
15785         (float_truncate:SF (match_dup 4)))]
15786   "TARGET_USE_FANCY_MATH_387
15787    && flag_unsafe_math_optimizations"
15788 {
15789   operands[2] = gen_reg_rtx (XFmode);
15790   operands[3] = gen_reg_rtx (XFmode);
15791   operands[4] = gen_reg_rtx (XFmode);
15792 })
15793
15794 (define_expand "logbdf2"
15795   [(set (match_dup 2)
15796         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15797    (parallel [(set (match_dup 3)
15798                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15799               (set (match_dup 4)
15800                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15801    (set (match_operand:DF 0 "register_operand" "")
15802         (float_truncate:DF (match_dup 4)))]
15803   "TARGET_USE_FANCY_MATH_387
15804    && flag_unsafe_math_optimizations"
15805 {
15806   operands[2] = gen_reg_rtx (XFmode);
15807   operands[3] = gen_reg_rtx (XFmode);
15808   operands[4] = gen_reg_rtx (XFmode);
15809 })
15810
15811 (define_expand "logbxf2"
15812   [(parallel [(set (match_dup 2)
15813                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15814                               UNSPEC_XTRACT_FRACT))
15815               (set (match_operand:XF 0 "register_operand" "")
15816                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15817   "TARGET_USE_FANCY_MATH_387
15818    && flag_unsafe_math_optimizations"
15819 {
15820   operands[2] = gen_reg_rtx (XFmode);
15821 })
15822
15823 (define_expand "ilogbsi2"
15824   [(parallel [(set (match_dup 2)
15825                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15826                               UNSPEC_XTRACT_FRACT))
15827               (set (match_operand:XF 3 "register_operand" "")
15828                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15829    (parallel [(set (match_operand:SI 0 "register_operand" "")
15830                    (fix:SI (match_dup 3)))
15831               (clobber (reg:CC FLAGS_REG))])]
15832   "TARGET_USE_FANCY_MATH_387
15833    && flag_unsafe_math_optimizations"
15834 {
15835   operands[2] = gen_reg_rtx (XFmode);
15836   operands[3] = gen_reg_rtx (XFmode);
15837 })
15838
15839 (define_insn "*f2xm1xf2"
15840   [(set (match_operand:XF 0 "register_operand" "=f")
15841         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15842          UNSPEC_F2XM1))]
15843   "TARGET_USE_FANCY_MATH_387
15844    && flag_unsafe_math_optimizations"
15845   "f2xm1"
15846   [(set_attr "type" "fpspc")
15847    (set_attr "mode" "XF")])
15848
15849 (define_insn "*fscalexf4"
15850   [(set (match_operand:XF 0 "register_operand" "=f")
15851         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15852                     (match_operand:XF 3 "register_operand" "1")]
15853                    UNSPEC_FSCALE_FRACT))
15854    (set (match_operand:XF 1 "register_operand" "=u")
15855         (unspec:XF [(match_dup 2) (match_dup 3)]
15856                    UNSPEC_FSCALE_EXP))]
15857   "TARGET_USE_FANCY_MATH_387
15858    && flag_unsafe_math_optimizations"
15859   "fscale"
15860   [(set_attr "type" "fpspc")
15861    (set_attr "mode" "XF")])
15862
15863 (define_expand "expsf2"
15864   [(set (match_dup 2)
15865         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15866    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15867    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15868    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15869    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15870    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15871    (parallel [(set (match_dup 10)
15872                    (unspec:XF [(match_dup 9) (match_dup 5)]
15873                               UNSPEC_FSCALE_FRACT))
15874               (set (match_dup 11)
15875                    (unspec:XF [(match_dup 9) (match_dup 5)]
15876                               UNSPEC_FSCALE_EXP))])
15877    (set (match_operand:SF 0 "register_operand" "")
15878         (float_truncate:SF (match_dup 10)))]
15879   "TARGET_USE_FANCY_MATH_387
15880    && flag_unsafe_math_optimizations"
15881 {
15882   rtx temp;
15883   int i;
15884
15885   for (i=2; i<12; i++)
15886     operands[i] = gen_reg_rtx (XFmode);
15887   temp = standard_80387_constant_rtx (5); /* fldl2e */
15888   emit_move_insn (operands[3], temp);
15889   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15890 })
15891
15892 (define_expand "expdf2"
15893   [(set (match_dup 2)
15894         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15895    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15896    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15897    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15898    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15899    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15900    (parallel [(set (match_dup 10)
15901                    (unspec:XF [(match_dup 9) (match_dup 5)]
15902                               UNSPEC_FSCALE_FRACT))
15903               (set (match_dup 11)
15904                    (unspec:XF [(match_dup 9) (match_dup 5)]
15905                               UNSPEC_FSCALE_EXP))])
15906    (set (match_operand:DF 0 "register_operand" "")
15907         (float_truncate:DF (match_dup 10)))]
15908   "TARGET_USE_FANCY_MATH_387
15909    && flag_unsafe_math_optimizations"
15910 {
15911   rtx temp;
15912   int i;
15913
15914   for (i=2; i<12; i++)
15915     operands[i] = gen_reg_rtx (XFmode);
15916   temp = standard_80387_constant_rtx (5); /* fldl2e */
15917   emit_move_insn (operands[3], temp);
15918   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15919 })
15920
15921 (define_expand "expxf2"
15922   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15923                                (match_dup 2)))
15924    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15925    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15926    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15927    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15928    (parallel [(set (match_operand:XF 0 "register_operand" "")
15929                    (unspec:XF [(match_dup 8) (match_dup 4)]
15930                               UNSPEC_FSCALE_FRACT))
15931               (set (match_dup 9)
15932                    (unspec:XF [(match_dup 8) (match_dup 4)]
15933                               UNSPEC_FSCALE_EXP))])]
15934   "TARGET_USE_FANCY_MATH_387
15935    && flag_unsafe_math_optimizations"
15936 {
15937   rtx temp;
15938   int i;
15939
15940   for (i=2; i<10; i++)
15941     operands[i] = gen_reg_rtx (XFmode);
15942   temp = standard_80387_constant_rtx (5); /* fldl2e */
15943   emit_move_insn (operands[2], temp);
15944   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15945 })
15946
15947 (define_expand "exp10sf2"
15948   [(set (match_dup 2)
15949         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15950    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15951    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15952    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15953    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15954    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15955    (parallel [(set (match_dup 10)
15956                    (unspec:XF [(match_dup 9) (match_dup 5)]
15957                               UNSPEC_FSCALE_FRACT))
15958               (set (match_dup 11)
15959                    (unspec:XF [(match_dup 9) (match_dup 5)]
15960                               UNSPEC_FSCALE_EXP))])
15961    (set (match_operand:SF 0 "register_operand" "")
15962         (float_truncate:SF (match_dup 10)))]
15963   "TARGET_USE_FANCY_MATH_387
15964    && flag_unsafe_math_optimizations"
15965 {
15966   rtx temp;
15967   int i;
15968
15969   for (i=2; i<12; i++)
15970     operands[i] = gen_reg_rtx (XFmode);
15971   temp = standard_80387_constant_rtx (6); /* fldl2t */
15972   emit_move_insn (operands[3], temp);
15973   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15974 })
15975
15976 (define_expand "exp10df2"
15977   [(set (match_dup 2)
15978         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15979    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15980    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15981    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15982    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15983    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15984    (parallel [(set (match_dup 10)
15985                    (unspec:XF [(match_dup 9) (match_dup 5)]
15986                               UNSPEC_FSCALE_FRACT))
15987               (set (match_dup 11)
15988                    (unspec:XF [(match_dup 9) (match_dup 5)]
15989                               UNSPEC_FSCALE_EXP))])
15990    (set (match_operand:DF 0 "register_operand" "")
15991         (float_truncate:DF (match_dup 10)))]
15992   "TARGET_USE_FANCY_MATH_387
15993    && flag_unsafe_math_optimizations"
15994 {
15995   rtx temp;
15996   int i;
15997
15998   for (i=2; i<12; i++)
15999     operands[i] = gen_reg_rtx (XFmode);
16000   temp = standard_80387_constant_rtx (6); /* fldl2t */
16001   emit_move_insn (operands[3], temp);
16002   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16003 })
16004
16005 (define_expand "exp10xf2"
16006   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16007                                (match_dup 2)))
16008    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16009    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16010    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16011    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16012    (parallel [(set (match_operand:XF 0 "register_operand" "")
16013                    (unspec:XF [(match_dup 8) (match_dup 4)]
16014                               UNSPEC_FSCALE_FRACT))
16015               (set (match_dup 9)
16016                    (unspec:XF [(match_dup 8) (match_dup 4)]
16017                               UNSPEC_FSCALE_EXP))])]
16018   "TARGET_USE_FANCY_MATH_387
16019    && flag_unsafe_math_optimizations"
16020 {
16021   rtx temp;
16022   int i;
16023
16024   for (i=2; i<10; i++)
16025     operands[i] = gen_reg_rtx (XFmode);
16026   temp = standard_80387_constant_rtx (6); /* fldl2t */
16027   emit_move_insn (operands[2], temp);
16028   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16029 })
16030
16031 (define_expand "exp2sf2"
16032   [(set (match_dup 2)
16033         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16034    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16035    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16036    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16037    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16038    (parallel [(set (match_dup 8)
16039                    (unspec:XF [(match_dup 7) (match_dup 3)]
16040                               UNSPEC_FSCALE_FRACT))
16041               (set (match_dup 9)
16042                    (unspec:XF [(match_dup 7) (match_dup 3)]
16043                               UNSPEC_FSCALE_EXP))])
16044    (set (match_operand:SF 0 "register_operand" "")
16045         (float_truncate:SF (match_dup 8)))]
16046   "TARGET_USE_FANCY_MATH_387
16047    && flag_unsafe_math_optimizations"
16048 {
16049   int i;
16050
16051   for (i=2; i<10; i++)
16052     operands[i] = gen_reg_rtx (XFmode);
16053   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16054 })
16055
16056 (define_expand "exp2df2"
16057   [(set (match_dup 2)
16058         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16059    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16060    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16061    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16062    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16063    (parallel [(set (match_dup 8)
16064                    (unspec:XF [(match_dup 7) (match_dup 3)]
16065                               UNSPEC_FSCALE_FRACT))
16066               (set (match_dup 9)
16067                    (unspec:XF [(match_dup 7) (match_dup 3)]
16068                               UNSPEC_FSCALE_EXP))])
16069    (set (match_operand:DF 0 "register_operand" "")
16070         (float_truncate:DF (match_dup 8)))]
16071   "TARGET_USE_FANCY_MATH_387
16072    && flag_unsafe_math_optimizations"
16073 {
16074   int i;
16075
16076   for (i=2; i<10; i++)
16077     operands[i] = gen_reg_rtx (XFmode);
16078   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16079 })
16080
16081 (define_expand "exp2xf2"
16082   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16083    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16084    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16085    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16086    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16087    (parallel [(set (match_operand:XF 0 "register_operand" "")
16088                    (unspec:XF [(match_dup 7) (match_dup 3)]
16089                               UNSPEC_FSCALE_FRACT))
16090               (set (match_dup 8)
16091                    (unspec:XF [(match_dup 7) (match_dup 3)]
16092                               UNSPEC_FSCALE_EXP))])]
16093   "TARGET_USE_FANCY_MATH_387
16094    && flag_unsafe_math_optimizations"
16095 {
16096   int i;
16097
16098   for (i=2; i<9; i++)
16099     operands[i] = gen_reg_rtx (XFmode);
16100   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16101 })
16102
16103 (define_expand "expm1df2"
16104   [(set (match_dup 2)
16105         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16106    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16107    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16108    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16109    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16110    (parallel [(set (match_dup 8)
16111                    (unspec:XF [(match_dup 7) (match_dup 5)]
16112                               UNSPEC_FSCALE_FRACT))
16113                    (set (match_dup 9)
16114                    (unspec:XF [(match_dup 7) (match_dup 5)]
16115                               UNSPEC_FSCALE_EXP))])
16116    (parallel [(set (match_dup 11)
16117                    (unspec:XF [(match_dup 10) (match_dup 9)]
16118                               UNSPEC_FSCALE_FRACT))
16119               (set (match_dup 12)
16120                    (unspec:XF [(match_dup 10) (match_dup 9)]
16121                               UNSPEC_FSCALE_EXP))])
16122    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16123    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16124    (set (match_operand:DF 0 "register_operand" "")
16125         (float_truncate:DF (match_dup 14)))]
16126   "TARGET_USE_FANCY_MATH_387
16127    && flag_unsafe_math_optimizations"
16128 {
16129   rtx temp;
16130   int i;
16131
16132   for (i=2; i<15; i++)
16133     operands[i] = gen_reg_rtx (XFmode);
16134   temp = standard_80387_constant_rtx (5); /* fldl2e */
16135   emit_move_insn (operands[3], temp);
16136   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16137 })
16138
16139 (define_expand "expm1sf2"
16140   [(set (match_dup 2)
16141         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16142    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16143    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16144    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16145    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16146    (parallel [(set (match_dup 8)
16147                    (unspec:XF [(match_dup 7) (match_dup 5)]
16148                               UNSPEC_FSCALE_FRACT))
16149                    (set (match_dup 9)
16150                    (unspec:XF [(match_dup 7) (match_dup 5)]
16151                               UNSPEC_FSCALE_EXP))])
16152    (parallel [(set (match_dup 11)
16153                    (unspec:XF [(match_dup 10) (match_dup 9)]
16154                               UNSPEC_FSCALE_FRACT))
16155               (set (match_dup 12)
16156                    (unspec:XF [(match_dup 10) (match_dup 9)]
16157                               UNSPEC_FSCALE_EXP))])
16158    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16159    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16160    (set (match_operand:SF 0 "register_operand" "")
16161         (float_truncate:SF (match_dup 14)))]
16162   "TARGET_USE_FANCY_MATH_387
16163    && flag_unsafe_math_optimizations"
16164 {
16165   rtx temp;
16166   int i;
16167
16168   for (i=2; i<15; i++)
16169     operands[i] = gen_reg_rtx (XFmode);
16170   temp = standard_80387_constant_rtx (5); /* fldl2e */
16171   emit_move_insn (operands[3], temp);
16172   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16173 })
16174
16175 (define_expand "expm1xf2"
16176   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16177                                (match_dup 2)))
16178    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16179    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16180    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16181    (parallel [(set (match_dup 7)
16182                    (unspec:XF [(match_dup 6) (match_dup 4)]
16183                               UNSPEC_FSCALE_FRACT))
16184                    (set (match_dup 8)
16185                    (unspec:XF [(match_dup 6) (match_dup 4)]
16186                               UNSPEC_FSCALE_EXP))])
16187    (parallel [(set (match_dup 10)
16188                    (unspec:XF [(match_dup 9) (match_dup 8)]
16189                               UNSPEC_FSCALE_FRACT))
16190               (set (match_dup 11)
16191                    (unspec:XF [(match_dup 9) (match_dup 8)]
16192                               UNSPEC_FSCALE_EXP))])
16193    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16194    (set (match_operand:XF 0 "register_operand" "")
16195         (plus:XF (match_dup 12) (match_dup 7)))]
16196   "TARGET_USE_FANCY_MATH_387
16197    && flag_unsafe_math_optimizations"
16198 {
16199   rtx temp;
16200   int i;
16201
16202   for (i=2; i<13; i++)
16203     operands[i] = gen_reg_rtx (XFmode);
16204   temp = standard_80387_constant_rtx (5); /* fldl2e */
16205   emit_move_insn (operands[2], temp);
16206   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16207 })
16208 \f
16209
16210 (define_insn "frndintxf2"
16211   [(set (match_operand:XF 0 "register_operand" "=f")
16212         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16213          UNSPEC_FRNDINT))]
16214   "TARGET_USE_FANCY_MATH_387
16215    && flag_unsafe_math_optimizations"
16216   "frndint"
16217   [(set_attr "type" "fpspc")
16218    (set_attr "mode" "XF")])
16219
16220 (define_expand "rintdf2"
16221   [(use (match_operand:DF 0 "register_operand" ""))
16222    (use (match_operand:DF 1 "register_operand" ""))]
16223   "TARGET_USE_FANCY_MATH_387
16224    && flag_unsafe_math_optimizations"
16225 {
16226   rtx op0 = gen_reg_rtx (XFmode);
16227   rtx op1 = gen_reg_rtx (XFmode);
16228
16229   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16230   emit_insn (gen_frndintxf2 (op0, op1));
16231
16232   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16233   DONE;
16234 })
16235
16236 (define_expand "rintsf2"
16237   [(use (match_operand:SF 0 "register_operand" ""))
16238    (use (match_operand:SF 1 "register_operand" ""))]
16239   "TARGET_USE_FANCY_MATH_387
16240    && flag_unsafe_math_optimizations"
16241 {
16242   rtx op0 = gen_reg_rtx (XFmode);
16243   rtx op1 = gen_reg_rtx (XFmode);
16244
16245   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16246   emit_insn (gen_frndintxf2 (op0, op1));
16247
16248   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16249   DONE;
16250 })
16251
16252 (define_expand "rintxf2"
16253   [(use (match_operand:XF 0 "register_operand" ""))
16254    (use (match_operand:XF 1 "register_operand" ""))]
16255   "TARGET_USE_FANCY_MATH_387
16256    && flag_unsafe_math_optimizations"
16257 {
16258   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16259   DONE;
16260 })
16261
16262 (define_insn "frndintxf2_floor"
16263   [(set (match_operand:XF 0 "register_operand" "=f")
16264         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16265          UNSPEC_FRNDINT_FLOOR))
16266    (use (match_operand:HI 2 "memory_operand" "m"))
16267    (use (match_operand:HI 3 "memory_operand" "m"))]
16268   "TARGET_USE_FANCY_MATH_387
16269    && flag_unsafe_math_optimizations"
16270   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16271   [(set_attr "type" "frndint")
16272    (set_attr "i387_cw" "floor")
16273    (set_attr "mode" "XF")])
16274
16275 (define_expand "floordf2"
16276   [(use (match_operand:DF 0 "register_operand" ""))
16277    (use (match_operand:DF 1 "register_operand" ""))]
16278   "TARGET_USE_FANCY_MATH_387
16279    && flag_unsafe_math_optimizations"
16280 {
16281   rtx op0 = gen_reg_rtx (XFmode);
16282   rtx op1 = gen_reg_rtx (XFmode);
16283   rtx op2 = assign_386_stack_local (HImode, 1);
16284   rtx op3 = assign_386_stack_local (HImode, 2);
16285         
16286   ix86_optimize_mode_switching = 1;
16287
16288   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16289   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16290
16291   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16292   DONE;
16293 })
16294
16295 (define_expand "floorsf2"
16296   [(use (match_operand:SF 0 "register_operand" ""))
16297    (use (match_operand:SF 1 "register_operand" ""))]
16298   "TARGET_USE_FANCY_MATH_387
16299    && flag_unsafe_math_optimizations"
16300 {
16301   rtx op0 = gen_reg_rtx (XFmode);
16302   rtx op1 = gen_reg_rtx (XFmode);
16303   rtx op2 = assign_386_stack_local (HImode, 1);
16304   rtx op3 = assign_386_stack_local (HImode, 2);
16305         
16306   ix86_optimize_mode_switching = 1;
16307
16308   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16309   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16310
16311   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16312   DONE;
16313 })
16314
16315 (define_expand "floorxf2"
16316   [(use (match_operand:XF 0 "register_operand" ""))
16317    (use (match_operand:XF 1 "register_operand" ""))]
16318   "TARGET_USE_FANCY_MATH_387
16319    && flag_unsafe_math_optimizations"
16320 {
16321   rtx op2 = assign_386_stack_local (HImode, 1);
16322   rtx op3 = assign_386_stack_local (HImode, 2);
16323         
16324   ix86_optimize_mode_switching = 1;
16325
16326   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16327   DONE;
16328 })
16329
16330 (define_insn "frndintxf2_ceil"
16331   [(set (match_operand:XF 0 "register_operand" "=f")
16332         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16333          UNSPEC_FRNDINT_CEIL))
16334    (use (match_operand:HI 2 "memory_operand" "m"))
16335    (use (match_operand:HI 3 "memory_operand" "m"))]
16336   "TARGET_USE_FANCY_MATH_387
16337    && flag_unsafe_math_optimizations"
16338   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16339   [(set_attr "type" "frndint")
16340    (set_attr "i387_cw" "ceil")
16341    (set_attr "mode" "XF")])
16342
16343 (define_expand "ceildf2"
16344   [(use (match_operand:DF 0 "register_operand" ""))
16345    (use (match_operand:DF 1 "register_operand" ""))]
16346   "TARGET_USE_FANCY_MATH_387
16347    && flag_unsafe_math_optimizations"
16348 {
16349   rtx op0 = gen_reg_rtx (XFmode);
16350   rtx op1 = gen_reg_rtx (XFmode);
16351   rtx op2 = assign_386_stack_local (HImode, 1);
16352   rtx op3 = assign_386_stack_local (HImode, 2);
16353         
16354   ix86_optimize_mode_switching = 1;
16355
16356   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16357   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16358
16359   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16360   DONE;
16361 })
16362
16363 (define_expand "ceilsf2"
16364   [(use (match_operand:SF 0 "register_operand" ""))
16365    (use (match_operand:SF 1 "register_operand" ""))]
16366   "TARGET_USE_FANCY_MATH_387
16367    && flag_unsafe_math_optimizations"
16368 {
16369   rtx op0 = gen_reg_rtx (XFmode);
16370   rtx op1 = gen_reg_rtx (XFmode);
16371   rtx op2 = assign_386_stack_local (HImode, 1);
16372   rtx op3 = assign_386_stack_local (HImode, 2);
16373         
16374   ix86_optimize_mode_switching = 1;
16375
16376   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16377   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16378
16379   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16380   DONE;
16381 })
16382
16383 (define_expand "ceilxf2"
16384   [(use (match_operand:XF 0 "register_operand" ""))
16385    (use (match_operand:XF 1 "register_operand" ""))]
16386   "TARGET_USE_FANCY_MATH_387
16387    && flag_unsafe_math_optimizations"
16388 {
16389   rtx op2 = assign_386_stack_local (HImode, 1);
16390   rtx op3 = assign_386_stack_local (HImode, 2);
16391         
16392   ix86_optimize_mode_switching = 1;
16393
16394   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16395   DONE;
16396 })
16397
16398 (define_insn "frndintxf2_trunc"
16399   [(set (match_operand:XF 0 "register_operand" "=f")
16400         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16401          UNSPEC_FRNDINT_TRUNC))
16402    (use (match_operand:HI 2 "memory_operand" "m"))
16403    (use (match_operand:HI 3 "memory_operand" "m"))]
16404   "TARGET_USE_FANCY_MATH_387
16405    && flag_unsafe_math_optimizations"
16406   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16407   [(set_attr "type" "frndint")
16408    (set_attr "i387_cw" "trunc")
16409    (set_attr "mode" "XF")])
16410
16411 (define_expand "btruncdf2"
16412   [(use (match_operand:DF 0 "register_operand" ""))
16413    (use (match_operand:DF 1 "register_operand" ""))]
16414   "TARGET_USE_FANCY_MATH_387
16415    && flag_unsafe_math_optimizations"
16416 {
16417   rtx op0 = gen_reg_rtx (XFmode);
16418   rtx op1 = gen_reg_rtx (XFmode);
16419   rtx op2 = assign_386_stack_local (HImode, 1);
16420   rtx op3 = assign_386_stack_local (HImode, 2);
16421         
16422   ix86_optimize_mode_switching = 1;
16423
16424   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16425   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16426
16427   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16428   DONE;
16429 })
16430
16431 (define_expand "btruncsf2"
16432   [(use (match_operand:SF 0 "register_operand" ""))
16433    (use (match_operand:SF 1 "register_operand" ""))]
16434   "TARGET_USE_FANCY_MATH_387
16435    && flag_unsafe_math_optimizations"
16436 {
16437   rtx op0 = gen_reg_rtx (XFmode);
16438   rtx op1 = gen_reg_rtx (XFmode);
16439   rtx op2 = assign_386_stack_local (HImode, 1);
16440   rtx op3 = assign_386_stack_local (HImode, 2);
16441         
16442   ix86_optimize_mode_switching = 1;
16443
16444   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16445   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16446
16447   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16448   DONE;
16449 })
16450
16451 (define_expand "btruncxf2"
16452   [(use (match_operand:XF 0 "register_operand" ""))
16453    (use (match_operand:XF 1 "register_operand" ""))]
16454   "TARGET_USE_FANCY_MATH_387
16455    && flag_unsafe_math_optimizations"
16456 {
16457   rtx op2 = assign_386_stack_local (HImode, 1);
16458   rtx op3 = assign_386_stack_local (HImode, 2);
16459         
16460   ix86_optimize_mode_switching = 1;
16461
16462   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16463   DONE;
16464 })
16465
16466 (define_insn "frndintxf2_mask_pm"
16467   [(set (match_operand:XF 0 "register_operand" "=f")
16468         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16469          UNSPEC_FRNDINT_MASK_PM))
16470    (use (match_operand:HI 2 "memory_operand" "m"))
16471    (use (match_operand:HI 3 "memory_operand" "m"))]
16472   "TARGET_USE_FANCY_MATH_387
16473    && flag_unsafe_math_optimizations"
16474   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16475   [(set_attr "type" "frndint")
16476    (set_attr "i387_cw" "mask_pm")
16477    (set_attr "mode" "XF")])
16478
16479 (define_expand "nearbyintdf2"
16480   [(use (match_operand:DF 0 "register_operand" ""))
16481    (use (match_operand:DF 1 "register_operand" ""))]
16482   "TARGET_USE_FANCY_MATH_387
16483    && flag_unsafe_math_optimizations"
16484 {
16485   rtx op0 = gen_reg_rtx (XFmode);
16486   rtx op1 = gen_reg_rtx (XFmode);
16487   rtx op2 = assign_386_stack_local (HImode, 1);
16488   rtx op3 = assign_386_stack_local (HImode, 2);
16489         
16490   ix86_optimize_mode_switching = 1;
16491
16492   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16493   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16494
16495   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16496   DONE;
16497 })
16498
16499 (define_expand "nearbyintsf2"
16500   [(use (match_operand:SF 0 "register_operand" ""))
16501    (use (match_operand:SF 1 "register_operand" ""))]
16502   "TARGET_USE_FANCY_MATH_387
16503    && flag_unsafe_math_optimizations"
16504 {
16505   rtx op0 = gen_reg_rtx (XFmode);
16506   rtx op1 = gen_reg_rtx (XFmode);
16507   rtx op2 = assign_386_stack_local (HImode, 1);
16508   rtx op3 = assign_386_stack_local (HImode, 2);
16509         
16510   ix86_optimize_mode_switching = 1;
16511
16512   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16513   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16514
16515   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16516   DONE;
16517 })
16518
16519 (define_expand "nearbyintxf2"
16520   [(use (match_operand:XF 0 "register_operand" ""))
16521    (use (match_operand:XF 1 "register_operand" ""))]
16522   "TARGET_USE_FANCY_MATH_387
16523    && flag_unsafe_math_optimizations"
16524 {
16525   rtx op2 = assign_386_stack_local (HImode, 1);
16526   rtx op3 = assign_386_stack_local (HImode, 2);
16527         
16528   ix86_optimize_mode_switching = 1;
16529
16530   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16531                                      op2, op3));
16532   DONE;
16533 })
16534
16535 \f
16536 ;; Block operation instructions
16537
16538 (define_insn "cld"
16539  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16540  ""
16541  "cld"
16542   [(set_attr "type" "cld")])
16543
16544 (define_expand "movmemsi"
16545   [(use (match_operand:BLK 0 "memory_operand" ""))
16546    (use (match_operand:BLK 1 "memory_operand" ""))
16547    (use (match_operand:SI 2 "nonmemory_operand" ""))
16548    (use (match_operand:SI 3 "const_int_operand" ""))]
16549   "! optimize_size"
16550 {
16551  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16552    DONE;
16553  else
16554    FAIL;
16555 })
16556
16557 (define_expand "movmemdi"
16558   [(use (match_operand:BLK 0 "memory_operand" ""))
16559    (use (match_operand:BLK 1 "memory_operand" ""))
16560    (use (match_operand:DI 2 "nonmemory_operand" ""))
16561    (use (match_operand:DI 3 "const_int_operand" ""))]
16562   "TARGET_64BIT"
16563 {
16564  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16565    DONE;
16566  else
16567    FAIL;
16568 })
16569
16570 ;; Most CPUs don't like single string operations
16571 ;; Handle this case here to simplify previous expander.
16572
16573 (define_expand "strmov"
16574   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16575    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16576    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16577               (clobber (reg:CC FLAGS_REG))])
16578    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16579               (clobber (reg:CC FLAGS_REG))])]
16580   ""
16581 {
16582   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16583
16584   /* If .md ever supports :P for Pmode, these can be directly
16585      in the pattern above.  */
16586   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16587   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16588
16589   if (TARGET_SINGLE_STRINGOP || optimize_size)
16590     {
16591       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16592                                       operands[2], operands[3],
16593                                       operands[5], operands[6]));
16594       DONE;
16595     }
16596
16597   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16598 })
16599
16600 (define_expand "strmov_singleop"
16601   [(parallel [(set (match_operand 1 "memory_operand" "")
16602                    (match_operand 3 "memory_operand" ""))
16603               (set (match_operand 0 "register_operand" "")
16604                    (match_operand 4 "" ""))
16605               (set (match_operand 2 "register_operand" "")
16606                    (match_operand 5 "" ""))
16607               (use (reg:SI DIRFLAG_REG))])]
16608   "TARGET_SINGLE_STRINGOP || optimize_size"
16609   "")
16610
16611 (define_insn "*strmovdi_rex_1"
16612   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16613         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16614    (set (match_operand:DI 0 "register_operand" "=D")
16615         (plus:DI (match_dup 2)
16616                  (const_int 8)))
16617    (set (match_operand:DI 1 "register_operand" "=S")
16618         (plus:DI (match_dup 3)
16619                  (const_int 8)))
16620    (use (reg:SI DIRFLAG_REG))]
16621   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16622   "movsq"
16623   [(set_attr "type" "str")
16624    (set_attr "mode" "DI")
16625    (set_attr "memory" "both")])
16626
16627 (define_insn "*strmovsi_1"
16628   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16629         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16630    (set (match_operand:SI 0 "register_operand" "=D")
16631         (plus:SI (match_dup 2)
16632                  (const_int 4)))
16633    (set (match_operand:SI 1 "register_operand" "=S")
16634         (plus:SI (match_dup 3)
16635                  (const_int 4)))
16636    (use (reg:SI DIRFLAG_REG))]
16637   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16638   "{movsl|movsd}"
16639   [(set_attr "type" "str")
16640    (set_attr "mode" "SI")
16641    (set_attr "memory" "both")])
16642
16643 (define_insn "*strmovsi_rex_1"
16644   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16645         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16646    (set (match_operand:DI 0 "register_operand" "=D")
16647         (plus:DI (match_dup 2)
16648                  (const_int 4)))
16649    (set (match_operand:DI 1 "register_operand" "=S")
16650         (plus:DI (match_dup 3)
16651                  (const_int 4)))
16652    (use (reg:SI DIRFLAG_REG))]
16653   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16654   "{movsl|movsd}"
16655   [(set_attr "type" "str")
16656    (set_attr "mode" "SI")
16657    (set_attr "memory" "both")])
16658
16659 (define_insn "*strmovhi_1"
16660   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16661         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16662    (set (match_operand:SI 0 "register_operand" "=D")
16663         (plus:SI (match_dup 2)
16664                  (const_int 2)))
16665    (set (match_operand:SI 1 "register_operand" "=S")
16666         (plus:SI (match_dup 3)
16667                  (const_int 2)))
16668    (use (reg:SI DIRFLAG_REG))]
16669   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16670   "movsw"
16671   [(set_attr "type" "str")
16672    (set_attr "memory" "both")
16673    (set_attr "mode" "HI")])
16674
16675 (define_insn "*strmovhi_rex_1"
16676   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16677         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16678    (set (match_operand:DI 0 "register_operand" "=D")
16679         (plus:DI (match_dup 2)
16680                  (const_int 2)))
16681    (set (match_operand:DI 1 "register_operand" "=S")
16682         (plus:DI (match_dup 3)
16683                  (const_int 2)))
16684    (use (reg:SI DIRFLAG_REG))]
16685   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16686   "movsw"
16687   [(set_attr "type" "str")
16688    (set_attr "memory" "both")
16689    (set_attr "mode" "HI")])
16690
16691 (define_insn "*strmovqi_1"
16692   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16693         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16694    (set (match_operand:SI 0 "register_operand" "=D")
16695         (plus:SI (match_dup 2)
16696                  (const_int 1)))
16697    (set (match_operand:SI 1 "register_operand" "=S")
16698         (plus:SI (match_dup 3)
16699                  (const_int 1)))
16700    (use (reg:SI DIRFLAG_REG))]
16701   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16702   "movsb"
16703   [(set_attr "type" "str")
16704    (set_attr "memory" "both")
16705    (set_attr "mode" "QI")])
16706
16707 (define_insn "*strmovqi_rex_1"
16708   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16709         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16710    (set (match_operand:DI 0 "register_operand" "=D")
16711         (plus:DI (match_dup 2)
16712                  (const_int 1)))
16713    (set (match_operand:DI 1 "register_operand" "=S")
16714         (plus:DI (match_dup 3)
16715                  (const_int 1)))
16716    (use (reg:SI DIRFLAG_REG))]
16717   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16718   "movsb"
16719   [(set_attr "type" "str")
16720    (set_attr "memory" "both")
16721    (set_attr "mode" "QI")])
16722
16723 (define_expand "rep_mov"
16724   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16725               (set (match_operand 0 "register_operand" "")
16726                    (match_operand 5 "" ""))
16727               (set (match_operand 2 "register_operand" "")
16728                    (match_operand 6 "" ""))
16729               (set (match_operand 1 "memory_operand" "")
16730                    (match_operand 3 "memory_operand" ""))
16731               (use (match_dup 4))
16732               (use (reg:SI DIRFLAG_REG))])]
16733   ""
16734   "")
16735
16736 (define_insn "*rep_movdi_rex64"
16737   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16738    (set (match_operand:DI 0 "register_operand" "=D") 
16739         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16740                             (const_int 3))
16741                  (match_operand:DI 3 "register_operand" "0")))
16742    (set (match_operand:DI 1 "register_operand" "=S") 
16743         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16744                  (match_operand:DI 4 "register_operand" "1")))
16745    (set (mem:BLK (match_dup 3))
16746         (mem:BLK (match_dup 4)))
16747    (use (match_dup 5))
16748    (use (reg:SI DIRFLAG_REG))]
16749   "TARGET_64BIT"
16750   "{rep\;movsq|rep movsq}"
16751   [(set_attr "type" "str")
16752    (set_attr "prefix_rep" "1")
16753    (set_attr "memory" "both")
16754    (set_attr "mode" "DI")])
16755
16756 (define_insn "*rep_movsi"
16757   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16758    (set (match_operand:SI 0 "register_operand" "=D") 
16759         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16760                             (const_int 2))
16761                  (match_operand:SI 3 "register_operand" "0")))
16762    (set (match_operand:SI 1 "register_operand" "=S") 
16763         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16764                  (match_operand:SI 4 "register_operand" "1")))
16765    (set (mem:BLK (match_dup 3))
16766         (mem:BLK (match_dup 4)))
16767    (use (match_dup 5))
16768    (use (reg:SI DIRFLAG_REG))]
16769   "!TARGET_64BIT"
16770   "{rep\;movsl|rep movsd}"
16771   [(set_attr "type" "str")
16772    (set_attr "prefix_rep" "1")
16773    (set_attr "memory" "both")
16774    (set_attr "mode" "SI")])
16775
16776 (define_insn "*rep_movsi_rex64"
16777   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16778    (set (match_operand:DI 0 "register_operand" "=D") 
16779         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16780                             (const_int 2))
16781                  (match_operand:DI 3 "register_operand" "0")))
16782    (set (match_operand:DI 1 "register_operand" "=S") 
16783         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16784                  (match_operand:DI 4 "register_operand" "1")))
16785    (set (mem:BLK (match_dup 3))
16786         (mem:BLK (match_dup 4)))
16787    (use (match_dup 5))
16788    (use (reg:SI DIRFLAG_REG))]
16789   "TARGET_64BIT"
16790   "{rep\;movsl|rep movsd}"
16791   [(set_attr "type" "str")
16792    (set_attr "prefix_rep" "1")
16793    (set_attr "memory" "both")
16794    (set_attr "mode" "SI")])
16795
16796 (define_insn "*rep_movqi"
16797   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16798    (set (match_operand:SI 0 "register_operand" "=D") 
16799         (plus:SI (match_operand:SI 3 "register_operand" "0")
16800                  (match_operand:SI 5 "register_operand" "2")))
16801    (set (match_operand:SI 1 "register_operand" "=S") 
16802         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16803    (set (mem:BLK (match_dup 3))
16804         (mem:BLK (match_dup 4)))
16805    (use (match_dup 5))
16806    (use (reg:SI DIRFLAG_REG))]
16807   "!TARGET_64BIT"
16808   "{rep\;movsb|rep movsb}"
16809   [(set_attr "type" "str")
16810    (set_attr "prefix_rep" "1")
16811    (set_attr "memory" "both")
16812    (set_attr "mode" "SI")])
16813
16814 (define_insn "*rep_movqi_rex64"
16815   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16816    (set (match_operand:DI 0 "register_operand" "=D") 
16817         (plus:DI (match_operand:DI 3 "register_operand" "0")
16818                  (match_operand:DI 5 "register_operand" "2")))
16819    (set (match_operand:DI 1 "register_operand" "=S") 
16820         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16821    (set (mem:BLK (match_dup 3))
16822         (mem:BLK (match_dup 4)))
16823    (use (match_dup 5))
16824    (use (reg:SI DIRFLAG_REG))]
16825   "TARGET_64BIT"
16826   "{rep\;movsb|rep movsb}"
16827   [(set_attr "type" "str")
16828    (set_attr "prefix_rep" "1")
16829    (set_attr "memory" "both")
16830    (set_attr "mode" "SI")])
16831
16832 (define_expand "clrmemsi"
16833    [(use (match_operand:BLK 0 "memory_operand" ""))
16834     (use (match_operand:SI 1 "nonmemory_operand" ""))
16835     (use (match_operand 2 "const_int_operand" ""))]
16836   ""
16837 {
16838  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16839    DONE;
16840  else
16841    FAIL;
16842 })
16843
16844 (define_expand "clrmemdi"
16845    [(use (match_operand:BLK 0 "memory_operand" ""))
16846     (use (match_operand:DI 1 "nonmemory_operand" ""))
16847     (use (match_operand 2 "const_int_operand" ""))]
16848   "TARGET_64BIT"
16849 {
16850  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16851    DONE;
16852  else
16853    FAIL;
16854 })
16855
16856 ;; Most CPUs don't like single string operations
16857 ;; Handle this case here to simplify previous expander.
16858
16859 (define_expand "strset"
16860   [(set (match_operand 1 "memory_operand" "")
16861         (match_operand 2 "register_operand" ""))
16862    (parallel [(set (match_operand 0 "register_operand" "")
16863                    (match_dup 3))
16864               (clobber (reg:CC FLAGS_REG))])]
16865   ""
16866 {
16867   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16868     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16869
16870   /* If .md ever supports :P for Pmode, this can be directly
16871      in the pattern above.  */
16872   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16873                               GEN_INT (GET_MODE_SIZE (GET_MODE
16874                                                       (operands[2]))));
16875   if (TARGET_SINGLE_STRINGOP || optimize_size)
16876     {
16877       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16878                                       operands[3]));
16879       DONE;
16880     }
16881 })
16882
16883 (define_expand "strset_singleop"
16884   [(parallel [(set (match_operand 1 "memory_operand" "")
16885                    (match_operand 2 "register_operand" ""))
16886               (set (match_operand 0 "register_operand" "")
16887                    (match_operand 3 "" ""))
16888               (use (reg:SI DIRFLAG_REG))])]
16889   "TARGET_SINGLE_STRINGOP || optimize_size"
16890   "")
16891
16892 (define_insn "*strsetdi_rex_1"
16893   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16894         (match_operand:DI 2 "register_operand" "a"))
16895    (set (match_operand:DI 0 "register_operand" "=D")
16896         (plus:DI (match_dup 1)
16897                  (const_int 8)))
16898    (use (reg:SI DIRFLAG_REG))]
16899   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16900   "stosq"
16901   [(set_attr "type" "str")
16902    (set_attr "memory" "store")
16903    (set_attr "mode" "DI")])
16904
16905 (define_insn "*strsetsi_1"
16906   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16907         (match_operand:SI 2 "register_operand" "a"))
16908    (set (match_operand:SI 0 "register_operand" "=D")
16909         (plus:SI (match_dup 1)
16910                  (const_int 4)))
16911    (use (reg:SI DIRFLAG_REG))]
16912   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16913   "{stosl|stosd}"
16914   [(set_attr "type" "str")
16915    (set_attr "memory" "store")
16916    (set_attr "mode" "SI")])
16917
16918 (define_insn "*strsetsi_rex_1"
16919   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16920         (match_operand:SI 2 "register_operand" "a"))
16921    (set (match_operand:DI 0 "register_operand" "=D")
16922         (plus:DI (match_dup 1)
16923                  (const_int 4)))
16924    (use (reg:SI DIRFLAG_REG))]
16925   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16926   "{stosl|stosd}"
16927   [(set_attr "type" "str")
16928    (set_attr "memory" "store")
16929    (set_attr "mode" "SI")])
16930
16931 (define_insn "*strsethi_1"
16932   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16933         (match_operand:HI 2 "register_operand" "a"))
16934    (set (match_operand:SI 0 "register_operand" "=D")
16935         (plus:SI (match_dup 1)
16936                  (const_int 2)))
16937    (use (reg:SI DIRFLAG_REG))]
16938   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16939   "stosw"
16940   [(set_attr "type" "str")
16941    (set_attr "memory" "store")
16942    (set_attr "mode" "HI")])
16943
16944 (define_insn "*strsethi_rex_1"
16945   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16946         (match_operand:HI 2 "register_operand" "a"))
16947    (set (match_operand:DI 0 "register_operand" "=D")
16948         (plus:DI (match_dup 1)
16949                  (const_int 2)))
16950    (use (reg:SI DIRFLAG_REG))]
16951   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16952   "stosw"
16953   [(set_attr "type" "str")
16954    (set_attr "memory" "store")
16955    (set_attr "mode" "HI")])
16956
16957 (define_insn "*strsetqi_1"
16958   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16959         (match_operand:QI 2 "register_operand" "a"))
16960    (set (match_operand:SI 0 "register_operand" "=D")
16961         (plus:SI (match_dup 1)
16962                  (const_int 1)))
16963    (use (reg:SI DIRFLAG_REG))]
16964   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16965   "stosb"
16966   [(set_attr "type" "str")
16967    (set_attr "memory" "store")
16968    (set_attr "mode" "QI")])
16969
16970 (define_insn "*strsetqi_rex_1"
16971   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16972         (match_operand:QI 2 "register_operand" "a"))
16973    (set (match_operand:DI 0 "register_operand" "=D")
16974         (plus:DI (match_dup 1)
16975                  (const_int 1)))
16976    (use (reg:SI DIRFLAG_REG))]
16977   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16978   "stosb"
16979   [(set_attr "type" "str")
16980    (set_attr "memory" "store")
16981    (set_attr "mode" "QI")])
16982
16983 (define_expand "rep_stos"
16984   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16985               (set (match_operand 0 "register_operand" "")
16986                    (match_operand 4 "" ""))
16987               (set (match_operand 2 "memory_operand" "") (const_int 0))
16988               (use (match_operand 3 "register_operand" ""))
16989               (use (match_dup 1))
16990               (use (reg:SI DIRFLAG_REG))])]
16991   ""
16992   "")
16993
16994 (define_insn "*rep_stosdi_rex64"
16995   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16996    (set (match_operand:DI 0 "register_operand" "=D") 
16997         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16998                             (const_int 3))
16999                  (match_operand:DI 3 "register_operand" "0")))
17000    (set (mem:BLK (match_dup 3))
17001         (const_int 0))
17002    (use (match_operand:DI 2 "register_operand" "a"))
17003    (use (match_dup 4))
17004    (use (reg:SI DIRFLAG_REG))]
17005   "TARGET_64BIT"
17006   "{rep\;stosq|rep stosq}"
17007   [(set_attr "type" "str")
17008    (set_attr "prefix_rep" "1")
17009    (set_attr "memory" "store")
17010    (set_attr "mode" "DI")])
17011
17012 (define_insn "*rep_stossi"
17013   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17014    (set (match_operand:SI 0 "register_operand" "=D") 
17015         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17016                             (const_int 2))
17017                  (match_operand:SI 3 "register_operand" "0")))
17018    (set (mem:BLK (match_dup 3))
17019         (const_int 0))
17020    (use (match_operand:SI 2 "register_operand" "a"))
17021    (use (match_dup 4))
17022    (use (reg:SI DIRFLAG_REG))]
17023   "!TARGET_64BIT"
17024   "{rep\;stosl|rep stosd}"
17025   [(set_attr "type" "str")
17026    (set_attr "prefix_rep" "1")
17027    (set_attr "memory" "store")
17028    (set_attr "mode" "SI")])
17029
17030 (define_insn "*rep_stossi_rex64"
17031   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17032    (set (match_operand:DI 0 "register_operand" "=D") 
17033         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17034                             (const_int 2))
17035                  (match_operand:DI 3 "register_operand" "0")))
17036    (set (mem:BLK (match_dup 3))
17037         (const_int 0))
17038    (use (match_operand:SI 2 "register_operand" "a"))
17039    (use (match_dup 4))
17040    (use (reg:SI DIRFLAG_REG))]
17041   "TARGET_64BIT"
17042   "{rep\;stosl|rep stosd}"
17043   [(set_attr "type" "str")
17044    (set_attr "prefix_rep" "1")
17045    (set_attr "memory" "store")
17046    (set_attr "mode" "SI")])
17047
17048 (define_insn "*rep_stosqi"
17049   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17050    (set (match_operand:SI 0 "register_operand" "=D") 
17051         (plus:SI (match_operand:SI 3 "register_operand" "0")
17052                  (match_operand:SI 4 "register_operand" "1")))
17053    (set (mem:BLK (match_dup 3))
17054         (const_int 0))
17055    (use (match_operand:QI 2 "register_operand" "a"))
17056    (use (match_dup 4))
17057    (use (reg:SI DIRFLAG_REG))]
17058   "!TARGET_64BIT"
17059   "{rep\;stosb|rep stosb}"
17060   [(set_attr "type" "str")
17061    (set_attr "prefix_rep" "1")
17062    (set_attr "memory" "store")
17063    (set_attr "mode" "QI")])
17064
17065 (define_insn "*rep_stosqi_rex64"
17066   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17067    (set (match_operand:DI 0 "register_operand" "=D") 
17068         (plus:DI (match_operand:DI 3 "register_operand" "0")
17069                  (match_operand:DI 4 "register_operand" "1")))
17070    (set (mem:BLK (match_dup 3))
17071         (const_int 0))
17072    (use (match_operand:QI 2 "register_operand" "a"))
17073    (use (match_dup 4))
17074    (use (reg:SI DIRFLAG_REG))]
17075   "TARGET_64BIT"
17076   "{rep\;stosb|rep stosb}"
17077   [(set_attr "type" "str")
17078    (set_attr "prefix_rep" "1")
17079    (set_attr "memory" "store")
17080    (set_attr "mode" "QI")])
17081
17082 (define_expand "cmpstrsi"
17083   [(set (match_operand:SI 0 "register_operand" "")
17084         (compare:SI (match_operand:BLK 1 "general_operand" "")
17085                     (match_operand:BLK 2 "general_operand" "")))
17086    (use (match_operand 3 "general_operand" ""))
17087    (use (match_operand 4 "immediate_operand" ""))]
17088   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17089 {
17090   rtx addr1, addr2, out, outlow, count, countreg, align;
17091
17092   /* Can't use this if the user has appropriated esi or edi.  */
17093   if (global_regs[4] || global_regs[5])
17094     FAIL;
17095
17096   out = operands[0];
17097   if (GET_CODE (out) != REG)
17098     out = gen_reg_rtx (SImode);
17099
17100   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17101   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17102   if (addr1 != XEXP (operands[1], 0))
17103     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17104   if (addr2 != XEXP (operands[2], 0))
17105     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17106
17107   count = operands[3];
17108   countreg = ix86_zero_extend_to_Pmode (count);
17109
17110   /* %%% Iff we are testing strict equality, we can use known alignment
17111      to good advantage.  This may be possible with combine, particularly
17112      once cc0 is dead.  */
17113   align = operands[4];
17114
17115   emit_insn (gen_cld ());
17116   if (GET_CODE (count) == CONST_INT)
17117     {
17118       if (INTVAL (count) == 0)
17119         {
17120           emit_move_insn (operands[0], const0_rtx);
17121           DONE;
17122         }
17123       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17124                                     operands[1], operands[2]));
17125     }
17126   else
17127     {
17128       if (TARGET_64BIT)
17129         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17130       else
17131         emit_insn (gen_cmpsi_1 (countreg, countreg));
17132       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17133                                  operands[1], operands[2]));
17134     }
17135
17136   outlow = gen_lowpart (QImode, out);
17137   emit_insn (gen_cmpintqi (outlow));
17138   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17139
17140   if (operands[0] != out)
17141     emit_move_insn (operands[0], out);
17142
17143   DONE;
17144 })
17145
17146 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17147
17148 (define_expand "cmpintqi"
17149   [(set (match_dup 1)
17150         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17151    (set (match_dup 2)
17152         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17153    (parallel [(set (match_operand:QI 0 "register_operand" "")
17154                    (minus:QI (match_dup 1)
17155                              (match_dup 2)))
17156               (clobber (reg:CC FLAGS_REG))])]
17157   ""
17158   "operands[1] = gen_reg_rtx (QImode);
17159    operands[2] = gen_reg_rtx (QImode);")
17160
17161 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17162 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17163
17164 (define_expand "cmpstrqi_nz_1"
17165   [(parallel [(set (reg:CC FLAGS_REG)
17166                    (compare:CC (match_operand 4 "memory_operand" "")
17167                                (match_operand 5 "memory_operand" "")))
17168               (use (match_operand 2 "register_operand" ""))
17169               (use (match_operand:SI 3 "immediate_operand" ""))
17170               (use (reg:SI DIRFLAG_REG))
17171               (clobber (match_operand 0 "register_operand" ""))
17172               (clobber (match_operand 1 "register_operand" ""))
17173               (clobber (match_dup 2))])]
17174   ""
17175   "")
17176
17177 (define_insn "*cmpstrqi_nz_1"
17178   [(set (reg:CC FLAGS_REG)
17179         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17180                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17181    (use (match_operand:SI 6 "register_operand" "2"))
17182    (use (match_operand:SI 3 "immediate_operand" "i"))
17183    (use (reg:SI DIRFLAG_REG))
17184    (clobber (match_operand:SI 0 "register_operand" "=S"))
17185    (clobber (match_operand:SI 1 "register_operand" "=D"))
17186    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17187   "!TARGET_64BIT"
17188   "repz{\;| }cmpsb"
17189   [(set_attr "type" "str")
17190    (set_attr "mode" "QI")
17191    (set_attr "prefix_rep" "1")])
17192
17193 (define_insn "*cmpstrqi_nz_rex_1"
17194   [(set (reg:CC FLAGS_REG)
17195         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17196                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17197    (use (match_operand:DI 6 "register_operand" "2"))
17198    (use (match_operand:SI 3 "immediate_operand" "i"))
17199    (use (reg:SI DIRFLAG_REG))
17200    (clobber (match_operand:DI 0 "register_operand" "=S"))
17201    (clobber (match_operand:DI 1 "register_operand" "=D"))
17202    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17203   "TARGET_64BIT"
17204   "repz{\;| }cmpsb"
17205   [(set_attr "type" "str")
17206    (set_attr "mode" "QI")
17207    (set_attr "prefix_rep" "1")])
17208
17209 ;; The same, but the count is not known to not be zero.
17210
17211 (define_expand "cmpstrqi_1"
17212   [(parallel [(set (reg:CC FLAGS_REG)
17213                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17214                                      (const_int 0))
17215                   (compare:CC (match_operand 4 "memory_operand" "")
17216                               (match_operand 5 "memory_operand" ""))
17217                   (const_int 0)))
17218               (use (match_operand:SI 3 "immediate_operand" ""))
17219               (use (reg:CC FLAGS_REG))
17220               (use (reg:SI DIRFLAG_REG))
17221               (clobber (match_operand 0 "register_operand" ""))
17222               (clobber (match_operand 1 "register_operand" ""))
17223               (clobber (match_dup 2))])]
17224   ""
17225   "")
17226
17227 (define_insn "*cmpstrqi_1"
17228   [(set (reg:CC FLAGS_REG)
17229         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17230                              (const_int 0))
17231           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17232                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17233           (const_int 0)))
17234    (use (match_operand:SI 3 "immediate_operand" "i"))
17235    (use (reg:CC FLAGS_REG))
17236    (use (reg:SI DIRFLAG_REG))
17237    (clobber (match_operand:SI 0 "register_operand" "=S"))
17238    (clobber (match_operand:SI 1 "register_operand" "=D"))
17239    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17240   "!TARGET_64BIT"
17241   "repz{\;| }cmpsb"
17242   [(set_attr "type" "str")
17243    (set_attr "mode" "QI")
17244    (set_attr "prefix_rep" "1")])
17245
17246 (define_insn "*cmpstrqi_rex_1"
17247   [(set (reg:CC FLAGS_REG)
17248         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17249                              (const_int 0))
17250           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17251                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17252           (const_int 0)))
17253    (use (match_operand:SI 3 "immediate_operand" "i"))
17254    (use (reg:CC FLAGS_REG))
17255    (use (reg:SI DIRFLAG_REG))
17256    (clobber (match_operand:DI 0 "register_operand" "=S"))
17257    (clobber (match_operand:DI 1 "register_operand" "=D"))
17258    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17259   "TARGET_64BIT"
17260   "repz{\;| }cmpsb"
17261   [(set_attr "type" "str")
17262    (set_attr "mode" "QI")
17263    (set_attr "prefix_rep" "1")])
17264
17265 (define_expand "strlensi"
17266   [(set (match_operand:SI 0 "register_operand" "")
17267         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17268                     (match_operand:QI 2 "immediate_operand" "")
17269                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17270   ""
17271 {
17272  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17273    DONE;
17274  else
17275    FAIL;
17276 })
17277
17278 (define_expand "strlendi"
17279   [(set (match_operand:DI 0 "register_operand" "")
17280         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17281                     (match_operand:QI 2 "immediate_operand" "")
17282                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17283   ""
17284 {
17285  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17286    DONE;
17287  else
17288    FAIL;
17289 })
17290
17291 (define_expand "strlenqi_1"
17292   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17293               (use (reg:SI DIRFLAG_REG))
17294               (clobber (match_operand 1 "register_operand" ""))
17295               (clobber (reg:CC FLAGS_REG))])]
17296   ""
17297   "")
17298
17299 (define_insn "*strlenqi_1"
17300   [(set (match_operand:SI 0 "register_operand" "=&c")
17301         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17302                     (match_operand:QI 2 "register_operand" "a")
17303                     (match_operand:SI 3 "immediate_operand" "i")
17304                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17305    (use (reg:SI DIRFLAG_REG))
17306    (clobber (match_operand:SI 1 "register_operand" "=D"))
17307    (clobber (reg:CC FLAGS_REG))]
17308   "!TARGET_64BIT"
17309   "repnz{\;| }scasb"
17310   [(set_attr "type" "str")
17311    (set_attr "mode" "QI")
17312    (set_attr "prefix_rep" "1")])
17313
17314 (define_insn "*strlenqi_rex_1"
17315   [(set (match_operand:DI 0 "register_operand" "=&c")
17316         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17317                     (match_operand:QI 2 "register_operand" "a")
17318                     (match_operand:DI 3 "immediate_operand" "i")
17319                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17320    (use (reg:SI DIRFLAG_REG))
17321    (clobber (match_operand:DI 1 "register_operand" "=D"))
17322    (clobber (reg:CC FLAGS_REG))]
17323   "TARGET_64BIT"
17324   "repnz{\;| }scasb"
17325   [(set_attr "type" "str")
17326    (set_attr "mode" "QI")
17327    (set_attr "prefix_rep" "1")])
17328
17329 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17330 ;; handled in combine, but it is not currently up to the task.
17331 ;; When used for their truth value, the cmpstr* expanders generate
17332 ;; code like this:
17333 ;;
17334 ;;   repz cmpsb
17335 ;;   seta       %al
17336 ;;   setb       %dl
17337 ;;   cmpb       %al, %dl
17338 ;;   jcc        label
17339 ;;
17340 ;; The intermediate three instructions are unnecessary.
17341
17342 ;; This one handles cmpstr*_nz_1...
17343 (define_peephole2
17344   [(parallel[
17345      (set (reg:CC FLAGS_REG)
17346           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17347                       (mem:BLK (match_operand 5 "register_operand" ""))))
17348      (use (match_operand 6 "register_operand" ""))
17349      (use (match_operand:SI 3 "immediate_operand" ""))
17350      (use (reg:SI DIRFLAG_REG))
17351      (clobber (match_operand 0 "register_operand" ""))
17352      (clobber (match_operand 1 "register_operand" ""))
17353      (clobber (match_operand 2 "register_operand" ""))])
17354    (set (match_operand:QI 7 "register_operand" "")
17355         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17356    (set (match_operand:QI 8 "register_operand" "")
17357         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17358    (set (reg FLAGS_REG)
17359         (compare (match_dup 7) (match_dup 8)))
17360   ]
17361   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17362   [(parallel[
17363      (set (reg:CC FLAGS_REG)
17364           (compare:CC (mem:BLK (match_dup 4))
17365                       (mem:BLK (match_dup 5))))
17366      (use (match_dup 6))
17367      (use (match_dup 3))
17368      (use (reg:SI DIRFLAG_REG))
17369      (clobber (match_dup 0))
17370      (clobber (match_dup 1))
17371      (clobber (match_dup 2))])]
17372   "")
17373
17374 ;; ...and this one handles cmpstr*_1.
17375 (define_peephole2
17376   [(parallel[
17377      (set (reg:CC FLAGS_REG)
17378           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17379                                (const_int 0))
17380             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17381                         (mem:BLK (match_operand 5 "register_operand" "")))
17382             (const_int 0)))
17383      (use (match_operand:SI 3 "immediate_operand" ""))
17384      (use (reg:CC FLAGS_REG))
17385      (use (reg:SI DIRFLAG_REG))
17386      (clobber (match_operand 0 "register_operand" ""))
17387      (clobber (match_operand 1 "register_operand" ""))
17388      (clobber (match_operand 2 "register_operand" ""))])
17389    (set (match_operand:QI 7 "register_operand" "")
17390         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17391    (set (match_operand:QI 8 "register_operand" "")
17392         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17393    (set (reg FLAGS_REG)
17394         (compare (match_dup 7) (match_dup 8)))
17395   ]
17396   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17397   [(parallel[
17398      (set (reg:CC FLAGS_REG)
17399           (if_then_else:CC (ne (match_dup 6)
17400                                (const_int 0))
17401             (compare:CC (mem:BLK (match_dup 4))
17402                         (mem:BLK (match_dup 5)))
17403             (const_int 0)))
17404      (use (match_dup 3))
17405      (use (reg:CC FLAGS_REG))
17406      (use (reg:SI DIRFLAG_REG))
17407      (clobber (match_dup 0))
17408      (clobber (match_dup 1))
17409      (clobber (match_dup 2))])]
17410   "")
17411
17412
17413 \f
17414 ;; Conditional move instructions.
17415
17416 (define_expand "movdicc"
17417   [(set (match_operand:DI 0 "register_operand" "")
17418         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17419                          (match_operand:DI 2 "general_operand" "")
17420                          (match_operand:DI 3 "general_operand" "")))]
17421   "TARGET_64BIT"
17422   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17423
17424 (define_insn "x86_movdicc_0_m1_rex64"
17425   [(set (match_operand:DI 0 "register_operand" "=r")
17426         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17427           (const_int -1)
17428           (const_int 0)))
17429    (clobber (reg:CC FLAGS_REG))]
17430   "TARGET_64BIT"
17431   "sbb{q}\t%0, %0"
17432   ; Since we don't have the proper number of operands for an alu insn,
17433   ; fill in all the blanks.
17434   [(set_attr "type" "alu")
17435    (set_attr "pent_pair" "pu")
17436    (set_attr "memory" "none")
17437    (set_attr "imm_disp" "false")
17438    (set_attr "mode" "DI")
17439    (set_attr "length_immediate" "0")])
17440
17441 (define_insn "movdicc_c_rex64"
17442   [(set (match_operand:DI 0 "register_operand" "=r,r")
17443         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17444                                 [(reg FLAGS_REG) (const_int 0)])
17445                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17446                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17447   "TARGET_64BIT && TARGET_CMOVE
17448    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17449   "@
17450    cmov%O2%C1\t{%2, %0|%0, %2}
17451    cmov%O2%c1\t{%3, %0|%0, %3}"
17452   [(set_attr "type" "icmov")
17453    (set_attr "mode" "DI")])
17454
17455 (define_expand "movsicc"
17456   [(set (match_operand:SI 0 "register_operand" "")
17457         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17458                          (match_operand:SI 2 "general_operand" "")
17459                          (match_operand:SI 3 "general_operand" "")))]
17460   ""
17461   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17462
17463 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17464 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17465 ;; So just document what we're doing explicitly.
17466
17467 (define_insn "x86_movsicc_0_m1"
17468   [(set (match_operand:SI 0 "register_operand" "=r")
17469         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17470           (const_int -1)
17471           (const_int 0)))
17472    (clobber (reg:CC FLAGS_REG))]
17473   ""
17474   "sbb{l}\t%0, %0"
17475   ; Since we don't have the proper number of operands for an alu insn,
17476   ; fill in all the blanks.
17477   [(set_attr "type" "alu")
17478    (set_attr "pent_pair" "pu")
17479    (set_attr "memory" "none")
17480    (set_attr "imm_disp" "false")
17481    (set_attr "mode" "SI")
17482    (set_attr "length_immediate" "0")])
17483
17484 (define_insn "*movsicc_noc"
17485   [(set (match_operand:SI 0 "register_operand" "=r,r")
17486         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17487                                 [(reg FLAGS_REG) (const_int 0)])
17488                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17489                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17490   "TARGET_CMOVE
17491    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17492   "@
17493    cmov%O2%C1\t{%2, %0|%0, %2}
17494    cmov%O2%c1\t{%3, %0|%0, %3}"
17495   [(set_attr "type" "icmov")
17496    (set_attr "mode" "SI")])
17497
17498 (define_expand "movhicc"
17499   [(set (match_operand:HI 0 "register_operand" "")
17500         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17501                          (match_operand:HI 2 "general_operand" "")
17502                          (match_operand:HI 3 "general_operand" "")))]
17503   "TARGET_HIMODE_MATH"
17504   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17505
17506 (define_insn "*movhicc_noc"
17507   [(set (match_operand:HI 0 "register_operand" "=r,r")
17508         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17509                                 [(reg FLAGS_REG) (const_int 0)])
17510                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17511                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17512   "TARGET_CMOVE
17513    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17514   "@
17515    cmov%O2%C1\t{%2, %0|%0, %2}
17516    cmov%O2%c1\t{%3, %0|%0, %3}"
17517   [(set_attr "type" "icmov")
17518    (set_attr "mode" "HI")])
17519
17520 (define_expand "movqicc"
17521   [(set (match_operand:QI 0 "register_operand" "")
17522         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17523                          (match_operand:QI 2 "general_operand" "")
17524                          (match_operand:QI 3 "general_operand" "")))]
17525   "TARGET_QIMODE_MATH"
17526   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17527
17528 (define_insn_and_split "*movqicc_noc"
17529   [(set (match_operand:QI 0 "register_operand" "=r,r")
17530         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17531                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17532                       (match_operand:QI 2 "register_operand" "r,0")
17533                       (match_operand:QI 3 "register_operand" "0,r")))]
17534   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17535   "#"
17536   "&& reload_completed"
17537   [(set (match_dup 0)
17538         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17539                       (match_dup 2)
17540                       (match_dup 3)))]
17541   "operands[0] = gen_lowpart (SImode, operands[0]);
17542    operands[2] = gen_lowpart (SImode, operands[2]);
17543    operands[3] = gen_lowpart (SImode, operands[3]);"
17544   [(set_attr "type" "icmov")
17545    (set_attr "mode" "SI")])
17546
17547 (define_expand "movsfcc"
17548   [(set (match_operand:SF 0 "register_operand" "")
17549         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17550                          (match_operand:SF 2 "register_operand" "")
17551                          (match_operand:SF 3 "register_operand" "")))]
17552   "TARGET_CMOVE"
17553   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17554
17555 (define_insn "*movsfcc_1"
17556   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17557         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17558                                 [(reg FLAGS_REG) (const_int 0)])
17559                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17560                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17561   "TARGET_CMOVE
17562    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17563   "@
17564    fcmov%F1\t{%2, %0|%0, %2}
17565    fcmov%f1\t{%3, %0|%0, %3}
17566    cmov%O2%C1\t{%2, %0|%0, %2}
17567    cmov%O2%c1\t{%3, %0|%0, %3}"
17568   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17569    (set_attr "mode" "SF,SF,SI,SI")])
17570
17571 (define_expand "movdfcc"
17572   [(set (match_operand:DF 0 "register_operand" "")
17573         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17574                          (match_operand:DF 2 "register_operand" "")
17575                          (match_operand:DF 3 "register_operand" "")))]
17576   "TARGET_CMOVE"
17577   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17578
17579 (define_insn "*movdfcc_1"
17580   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17581         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17582                                 [(reg FLAGS_REG) (const_int 0)])
17583                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17584                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17585   "!TARGET_64BIT && TARGET_CMOVE
17586    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17587   "@
17588    fcmov%F1\t{%2, %0|%0, %2}
17589    fcmov%f1\t{%3, %0|%0, %3}
17590    #
17591    #"
17592   [(set_attr "type" "fcmov,fcmov,multi,multi")
17593    (set_attr "mode" "DF")])
17594
17595 (define_insn "*movdfcc_1_rex64"
17596   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17597         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17598                                 [(reg FLAGS_REG) (const_int 0)])
17599                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17600                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17601   "TARGET_64BIT && TARGET_CMOVE
17602    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17603   "@
17604    fcmov%F1\t{%2, %0|%0, %2}
17605    fcmov%f1\t{%3, %0|%0, %3}
17606    cmov%O2%C1\t{%2, %0|%0, %2}
17607    cmov%O2%c1\t{%3, %0|%0, %3}"
17608   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17609    (set_attr "mode" "DF")])
17610
17611 (define_split
17612   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17613         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17614                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17615                       (match_operand:DF 2 "nonimmediate_operand" "")
17616                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17617   "!TARGET_64BIT && reload_completed"
17618   [(set (match_dup 2)
17619         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17620                       (match_dup 5)
17621                       (match_dup 7)))
17622    (set (match_dup 3)
17623         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17624                       (match_dup 6)
17625                       (match_dup 8)))]
17626   "split_di (operands+2, 1, operands+5, operands+6);
17627    split_di (operands+3, 1, operands+7, operands+8);
17628    split_di (operands, 1, operands+2, operands+3);")
17629
17630 (define_expand "movxfcc"
17631   [(set (match_operand:XF 0 "register_operand" "")
17632         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17633                          (match_operand:XF 2 "register_operand" "")
17634                          (match_operand:XF 3 "register_operand" "")))]
17635   "TARGET_CMOVE"
17636   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17637
17638 (define_insn "*movxfcc_1"
17639   [(set (match_operand:XF 0 "register_operand" "=f,f")
17640         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17641                                 [(reg FLAGS_REG) (const_int 0)])
17642                       (match_operand:XF 2 "register_operand" "f,0")
17643                       (match_operand:XF 3 "register_operand" "0,f")))]
17644   "TARGET_CMOVE"
17645   "@
17646    fcmov%F1\t{%2, %0|%0, %2}
17647    fcmov%f1\t{%3, %0|%0, %3}"
17648   [(set_attr "type" "fcmov")
17649    (set_attr "mode" "XF")])
17650
17651 (define_expand "minsf3"
17652   [(parallel [
17653      (set (match_operand:SF 0 "register_operand" "")
17654           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17655                                (match_operand:SF 2 "nonimmediate_operand" ""))
17656                            (match_dup 1)
17657                            (match_dup 2)))
17658      (clobber (reg:CC FLAGS_REG))])]
17659   "TARGET_SSE"
17660   "")
17661
17662 (define_insn "*minsf"
17663   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17664         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17665                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17666                          (match_dup 1)
17667                          (match_dup 2)))
17668    (clobber (reg:CC FLAGS_REG))]
17669   "TARGET_SSE && TARGET_IEEE_FP"
17670   "#")
17671
17672 (define_insn "*minsf_nonieee"
17673   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17674         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17675                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17676                          (match_dup 1)
17677                          (match_dup 2)))
17678    (clobber (reg:CC FLAGS_REG))]
17679   "TARGET_SSE && !TARGET_IEEE_FP
17680    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17681   "#")
17682
17683 (define_split
17684   [(set (match_operand:SF 0 "register_operand" "")
17685         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17686                              (match_operand:SF 2 "nonimmediate_operand" ""))
17687                          (match_operand:SF 3 "register_operand" "")
17688                          (match_operand:SF 4 "nonimmediate_operand" "")))
17689    (clobber (reg:CC FLAGS_REG))]
17690   "SSE_REG_P (operands[0]) && reload_completed
17691    && ((operands_match_p (operands[1], operands[3])
17692         && operands_match_p (operands[2], operands[4]))
17693        || (operands_match_p (operands[1], operands[4])
17694            && operands_match_p (operands[2], operands[3])))"
17695   [(set (match_dup 0)
17696         (if_then_else:SF (lt (match_dup 1)
17697                              (match_dup 2))
17698                          (match_dup 1)
17699                          (match_dup 2)))])
17700
17701 ;; Conditional addition patterns
17702 (define_expand "addqicc"
17703   [(match_operand:QI 0 "register_operand" "")
17704    (match_operand 1 "comparison_operator" "")
17705    (match_operand:QI 2 "register_operand" "")
17706    (match_operand:QI 3 "const_int_operand" "")]
17707   ""
17708   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17709
17710 (define_expand "addhicc"
17711   [(match_operand:HI 0 "register_operand" "")
17712    (match_operand 1 "comparison_operator" "")
17713    (match_operand:HI 2 "register_operand" "")
17714    (match_operand:HI 3 "const_int_operand" "")]
17715   ""
17716   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17717
17718 (define_expand "addsicc"
17719   [(match_operand:SI 0 "register_operand" "")
17720    (match_operand 1 "comparison_operator" "")
17721    (match_operand:SI 2 "register_operand" "")
17722    (match_operand:SI 3 "const_int_operand" "")]
17723   ""
17724   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17725
17726 (define_expand "adddicc"
17727   [(match_operand:DI 0 "register_operand" "")
17728    (match_operand 1 "comparison_operator" "")
17729    (match_operand:DI 2 "register_operand" "")
17730    (match_operand:DI 3 "const_int_operand" "")]
17731   "TARGET_64BIT"
17732   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17733
17734 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17735
17736 (define_split
17737   [(set (match_operand:SF 0 "fp_register_operand" "")
17738         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17739                              (match_operand:SF 2 "register_operand" ""))
17740                          (match_operand:SF 3 "register_operand" "")
17741                          (match_operand:SF 4 "register_operand" "")))
17742    (clobber (reg:CC FLAGS_REG))]
17743   "reload_completed
17744    && ((operands_match_p (operands[1], operands[3])
17745         && operands_match_p (operands[2], operands[4]))
17746        || (operands_match_p (operands[1], operands[4])
17747            && operands_match_p (operands[2], operands[3])))"
17748   [(set (reg:CCFP FLAGS_REG)
17749         (compare:CCFP (match_dup 2)
17750                       (match_dup 1)))
17751    (set (match_dup 0)
17752         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17753                          (match_dup 1)
17754                          (match_dup 2)))])
17755
17756 (define_insn "*minsf_sse"
17757   [(set (match_operand:SF 0 "register_operand" "=x")
17758         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17759                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17760                          (match_dup 1)
17761                          (match_dup 2)))]
17762   "TARGET_SSE && reload_completed"
17763   "minss\t{%2, %0|%0, %2}"
17764   [(set_attr "type" "sse")
17765    (set_attr "mode" "SF")])
17766
17767 (define_expand "mindf3"
17768   [(parallel [
17769      (set (match_operand:DF 0 "register_operand" "")
17770           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17771                                (match_operand:DF 2 "nonimmediate_operand" ""))
17772                            (match_dup 1)
17773                            (match_dup 2)))
17774      (clobber (reg:CC FLAGS_REG))])]
17775   "TARGET_SSE2 && TARGET_SSE_MATH"
17776   "#")
17777
17778 (define_insn "*mindf"
17779   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17780         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17781                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17782                          (match_dup 1)
17783                          (match_dup 2)))
17784    (clobber (reg:CC FLAGS_REG))]
17785   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17786   "#")
17787
17788 (define_insn "*mindf_nonieee"
17789   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17790         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17791                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17792                          (match_dup 1)
17793                          (match_dup 2)))
17794    (clobber (reg:CC FLAGS_REG))]
17795   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17796    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17797   "#")
17798
17799 (define_split
17800   [(set (match_operand:DF 0 "register_operand" "")
17801         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17802                              (match_operand:DF 2 "nonimmediate_operand" ""))
17803                          (match_operand:DF 3 "register_operand" "")
17804                          (match_operand:DF 4 "nonimmediate_operand" "")))
17805    (clobber (reg:CC FLAGS_REG))]
17806   "SSE_REG_P (operands[0]) && reload_completed
17807    && ((operands_match_p (operands[1], operands[3])
17808         && operands_match_p (operands[2], operands[4]))
17809        || (operands_match_p (operands[1], operands[4])
17810            && operands_match_p (operands[2], operands[3])))"
17811   [(set (match_dup 0)
17812         (if_then_else:DF (lt (match_dup 1)
17813                              (match_dup 2))
17814                          (match_dup 1)
17815                          (match_dup 2)))])
17816
17817 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17818 (define_split
17819   [(set (match_operand:DF 0 "fp_register_operand" "")
17820         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17821                              (match_operand:DF 2 "register_operand" ""))
17822                          (match_operand:DF 3 "register_operand" "")
17823                          (match_operand:DF 4 "register_operand" "")))
17824    (clobber (reg:CC FLAGS_REG))]
17825   "reload_completed
17826    && ((operands_match_p (operands[1], operands[3])
17827         && operands_match_p (operands[2], operands[4]))
17828        || (operands_match_p (operands[1], operands[4])
17829            && operands_match_p (operands[2], operands[3])))"
17830   [(set (reg:CCFP FLAGS_REG)
17831         (compare:CCFP (match_dup 2)
17832                       (match_dup 1)))
17833    (set (match_dup 0)
17834         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17835                          (match_dup 1)
17836                          (match_dup 2)))])
17837
17838 (define_insn "*mindf_sse"
17839   [(set (match_operand:DF 0 "register_operand" "=Y")
17840         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17841                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17842                          (match_dup 1)
17843                          (match_dup 2)))]
17844   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17845   "minsd\t{%2, %0|%0, %2}"
17846   [(set_attr "type" "sse")
17847    (set_attr "mode" "DF")])
17848
17849 (define_expand "maxsf3"
17850   [(parallel [
17851      (set (match_operand:SF 0 "register_operand" "")
17852           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17853                                (match_operand:SF 2 "nonimmediate_operand" ""))
17854                            (match_dup 1)
17855                            (match_dup 2)))
17856      (clobber (reg:CC FLAGS_REG))])]
17857   "TARGET_SSE"
17858   "#")
17859
17860 (define_insn "*maxsf"
17861   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17862         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17863                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17864                          (match_dup 1)
17865                          (match_dup 2)))
17866    (clobber (reg:CC FLAGS_REG))]
17867   "TARGET_SSE && TARGET_IEEE_FP"
17868   "#")
17869
17870 (define_insn "*maxsf_nonieee"
17871   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17872         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17873                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17874                          (match_dup 1)
17875                          (match_dup 2)))
17876    (clobber (reg:CC FLAGS_REG))]
17877   "TARGET_SSE && !TARGET_IEEE_FP
17878    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17879   "#")
17880
17881 (define_split
17882   [(set (match_operand:SF 0 "register_operand" "")
17883         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17884                              (match_operand:SF 2 "nonimmediate_operand" ""))
17885                          (match_operand:SF 3 "register_operand" "")
17886                          (match_operand:SF 4 "nonimmediate_operand" "")))
17887    (clobber (reg:CC FLAGS_REG))]
17888   "SSE_REG_P (operands[0]) && reload_completed
17889    && ((operands_match_p (operands[1], operands[3])
17890         && operands_match_p (operands[2], operands[4]))
17891        || (operands_match_p (operands[1], operands[4])
17892            && operands_match_p (operands[2], operands[3])))"
17893   [(set (match_dup 0)
17894         (if_then_else:SF (gt (match_dup 1)
17895                              (match_dup 2))
17896                          (match_dup 1)
17897                          (match_dup 2)))])
17898
17899 (define_split
17900   [(set (match_operand:SF 0 "fp_register_operand" "")
17901         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17902                              (match_operand:SF 2 "register_operand" ""))
17903                          (match_operand:SF 3 "register_operand" "")
17904                          (match_operand:SF 4 "register_operand" "")))
17905    (clobber (reg:CC FLAGS_REG))]
17906   "reload_completed
17907    && ((operands_match_p (operands[1], operands[3])
17908         && operands_match_p (operands[2], operands[4]))
17909        || (operands_match_p (operands[1], operands[4])
17910            && operands_match_p (operands[2], operands[3])))"
17911   [(set (reg:CCFP FLAGS_REG)
17912         (compare:CCFP (match_dup 1)
17913                       (match_dup 2)))
17914    (set (match_dup 0)
17915         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17916                          (match_dup 1)
17917                          (match_dup 2)))])
17918
17919 (define_insn "*maxsf_sse"
17920   [(set (match_operand:SF 0 "register_operand" "=x")
17921         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17922                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17923                          (match_dup 1)
17924                          (match_dup 2)))]
17925   "TARGET_SSE && reload_completed"
17926   "maxss\t{%2, %0|%0, %2}"
17927   [(set_attr "type" "sse")
17928    (set_attr "mode" "SF")])
17929
17930 (define_expand "maxdf3"
17931   [(parallel [
17932      (set (match_operand:DF 0 "register_operand" "")
17933           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17934                                (match_operand:DF 2 "nonimmediate_operand" ""))
17935                            (match_dup 1)
17936                            (match_dup 2)))
17937      (clobber (reg:CC FLAGS_REG))])]
17938   "TARGET_SSE2 && TARGET_SSE_MATH"
17939   "#")
17940
17941 (define_insn "*maxdf"
17942   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17943         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17944                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17945                          (match_dup 1)
17946                          (match_dup 2)))
17947    (clobber (reg:CC FLAGS_REG))]
17948   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17949   "#")
17950
17951 (define_insn "*maxdf_nonieee"
17952   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17953         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17954                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17955                          (match_dup 1)
17956                          (match_dup 2)))
17957    (clobber (reg:CC FLAGS_REG))]
17958   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17959    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17960   "#")
17961
17962 (define_split
17963   [(set (match_operand:DF 0 "register_operand" "")
17964         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17965                              (match_operand:DF 2 "nonimmediate_operand" ""))
17966                          (match_operand:DF 3 "register_operand" "")
17967                          (match_operand:DF 4 "nonimmediate_operand" "")))
17968    (clobber (reg:CC FLAGS_REG))]
17969   "SSE_REG_P (operands[0]) && reload_completed
17970    && ((operands_match_p (operands[1], operands[3])
17971         && operands_match_p (operands[2], operands[4]))
17972        || (operands_match_p (operands[1], operands[4])
17973            && operands_match_p (operands[2], operands[3])))"
17974   [(set (match_dup 0)
17975         (if_then_else:DF (gt (match_dup 1)
17976                              (match_dup 2))
17977                          (match_dup 1)
17978                          (match_dup 2)))])
17979
17980 (define_split
17981   [(set (match_operand:DF 0 "fp_register_operand" "")
17982         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17983                              (match_operand:DF 2 "register_operand" ""))
17984                          (match_operand:DF 3 "register_operand" "")
17985                          (match_operand:DF 4 "register_operand" "")))
17986    (clobber (reg:CC FLAGS_REG))]
17987   "reload_completed
17988    && ((operands_match_p (operands[1], operands[3])
17989         && operands_match_p (operands[2], operands[4]))
17990        || (operands_match_p (operands[1], operands[4])
17991            && operands_match_p (operands[2], operands[3])))"
17992   [(set (reg:CCFP FLAGS_REG)
17993         (compare:CCFP (match_dup 1)
17994                       (match_dup 2)))
17995    (set (match_dup 0)
17996         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17997                          (match_dup 1)
17998                          (match_dup 2)))])
17999
18000 (define_insn "*maxdf_sse"
18001   [(set (match_operand:DF 0 "register_operand" "=Y")
18002         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18003                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18004                          (match_dup 1)
18005                          (match_dup 2)))]
18006   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18007   "maxsd\t{%2, %0|%0, %2}"
18008   [(set_attr "type" "sse")
18009    (set_attr "mode" "DF")])
18010 \f
18011 ;; Misc patterns (?)
18012
18013 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18014 ;; Otherwise there will be nothing to keep
18015 ;; 
18016 ;; [(set (reg ebp) (reg esp))]
18017 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18018 ;;  (clobber (eflags)]
18019 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18020 ;;
18021 ;; in proper program order.
18022 (define_insn "pro_epilogue_adjust_stack_1"
18023   [(set (match_operand:SI 0 "register_operand" "=r,r")
18024         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18025                  (match_operand:SI 2 "immediate_operand" "i,i")))
18026    (clobber (reg:CC FLAGS_REG))
18027    (clobber (mem:BLK (scratch)))]
18028   "!TARGET_64BIT"
18029 {
18030   switch (get_attr_type (insn))
18031     {
18032     case TYPE_IMOV:
18033       return "mov{l}\t{%1, %0|%0, %1}";
18034
18035     case TYPE_ALU:
18036       if (GET_CODE (operands[2]) == CONST_INT
18037           && (INTVAL (operands[2]) == 128
18038               || (INTVAL (operands[2]) < 0
18039                   && INTVAL (operands[2]) != -128)))
18040         {
18041           operands[2] = GEN_INT (-INTVAL (operands[2]));
18042           return "sub{l}\t{%2, %0|%0, %2}";
18043         }
18044       return "add{l}\t{%2, %0|%0, %2}";
18045
18046     case TYPE_LEA:
18047       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18048       return "lea{l}\t{%a2, %0|%0, %a2}";
18049
18050     default:
18051       abort ();
18052     }
18053 }
18054   [(set (attr "type")
18055         (cond [(eq_attr "alternative" "0")
18056                  (const_string "alu")
18057                (match_operand:SI 2 "const0_operand" "")
18058                  (const_string "imov")
18059               ]
18060               (const_string "lea")))
18061    (set_attr "mode" "SI")])
18062
18063 (define_insn "pro_epilogue_adjust_stack_rex64"
18064   [(set (match_operand:DI 0 "register_operand" "=r,r")
18065         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18066                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18067    (clobber (reg:CC FLAGS_REG))
18068    (clobber (mem:BLK (scratch)))]
18069   "TARGET_64BIT"
18070 {
18071   switch (get_attr_type (insn))
18072     {
18073     case TYPE_IMOV:
18074       return "mov{q}\t{%1, %0|%0, %1}";
18075
18076     case TYPE_ALU:
18077       if (GET_CODE (operands[2]) == CONST_INT
18078           /* Avoid overflows.  */
18079           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18080           && (INTVAL (operands[2]) == 128
18081               || (INTVAL (operands[2]) < 0
18082                   && INTVAL (operands[2]) != -128)))
18083         {
18084           operands[2] = GEN_INT (-INTVAL (operands[2]));
18085           return "sub{q}\t{%2, %0|%0, %2}";
18086         }
18087       return "add{q}\t{%2, %0|%0, %2}";
18088
18089     case TYPE_LEA:
18090       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18091       return "lea{q}\t{%a2, %0|%0, %a2}";
18092
18093     default:
18094       abort ();
18095     }
18096 }
18097   [(set (attr "type")
18098         (cond [(eq_attr "alternative" "0")
18099                  (const_string "alu")
18100                (match_operand:DI 2 "const0_operand" "")
18101                  (const_string "imov")
18102               ]
18103               (const_string "lea")))
18104    (set_attr "mode" "DI")])
18105
18106 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18107   [(set (match_operand:DI 0 "register_operand" "=r,r")
18108         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18109                  (match_operand:DI 3 "immediate_operand" "i,i")))
18110    (use (match_operand:DI 2 "register_operand" "r,r"))
18111    (clobber (reg:CC FLAGS_REG))
18112    (clobber (mem:BLK (scratch)))]
18113   "TARGET_64BIT"
18114 {
18115   switch (get_attr_type (insn))
18116     {
18117     case TYPE_ALU:
18118       return "add{q}\t{%2, %0|%0, %2}";
18119
18120     case TYPE_LEA:
18121       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18122       return "lea{q}\t{%a2, %0|%0, %a2}";
18123
18124     default:
18125       abort ();
18126     }
18127 }
18128   [(set_attr "type" "alu,lea")
18129    (set_attr "mode" "DI")])
18130
18131 ;; Placeholder for the conditional moves.  This one is split either to SSE
18132 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18133 ;; fact is that compares supported by the cmp??ss instructions are exactly
18134 ;; swapped of those supported by cmove sequence.
18135 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18136 ;; supported by i387 comparisons and we do need to emit two conditional moves
18137 ;; in tandem.
18138
18139 (define_insn "sse_movsfcc"
18140   [(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")
18141         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18142                         [(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")
18143                          (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")])
18144                       (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")
18145                       (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")))
18146    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18147    (clobber (reg:CC FLAGS_REG))]
18148   "TARGET_SSE
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_movsfcc_eq"
18161   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18162         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18163                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18164                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18165                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18166    (clobber (match_scratch:SF 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 (define_insn "sse_movdfcc"
18173   [(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")
18174         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18175                         [(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")
18176                          (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")])
18177                       (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")
18178                       (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")))
18179    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18180    (clobber (reg:CC FLAGS_REG))]
18181   "TARGET_SSE2
18182    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18183    /* Avoid combine from being smart and converting min/max
18184       instruction patterns into conditional moves.  */
18185    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18186         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18187        || !rtx_equal_p (operands[4], operands[2])
18188        || !rtx_equal_p (operands[5], operands[3]))
18189    && (!TARGET_IEEE_FP
18190        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18191   "#")
18192
18193 (define_insn "sse_movdfcc_eq"
18194   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18195         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18196                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18197                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18198                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18199    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18200    (clobber (reg:CC FLAGS_REG))]
18201   "TARGET_SSE
18202    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18203   "#")
18204
18205 ;; For non-sse moves just expand the usual cmove sequence.
18206 (define_split
18207   [(set (match_operand 0 "register_operand" "")
18208         (if_then_else (match_operator 1 "comparison_operator"
18209                         [(match_operand 4 "nonimmediate_operand" "")
18210                          (match_operand 5 "register_operand" "")])
18211                       (match_operand 2 "nonimmediate_operand" "")
18212                       (match_operand 3 "nonimmediate_operand" "")))
18213    (clobber (match_operand 6 "" ""))
18214    (clobber (reg:CC FLAGS_REG))]
18215   "!SSE_REG_P (operands[0]) && reload_completed
18216    && (GET_MODE (operands[0]) == SFmode
18217        || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
18218   [(const_int 0)]
18219 {
18220    ix86_compare_op0 = operands[5];
18221    ix86_compare_op1 = operands[4];
18222    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18223                                  VOIDmode, operands[5], operands[4]);
18224    ix86_expand_fp_movcc (operands);
18225    DONE;
18226 })
18227
18228 ;; Split SSE based conditional move into sequence:
18229 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18230 ;; and   op2, op0   -  zero op2 if comparison was false
18231 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18232 ;; or    op2, op0   -  get the nonzero one into the result.
18233 (define_split
18234   [(set (match_operand:SF 0 "register_operand" "")
18235         (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18236                            [(match_operand:SF 4 "register_operand" "")
18237                             (match_operand:SF 5 "nonimmediate_operand" "")])
18238                          (match_operand:SF 2 "register_operand" "")
18239                          (match_operand:SF 3 "register_operand" "")))
18240    (clobber (match_operand 6 "" ""))
18241    (clobber (reg:CC FLAGS_REG))]
18242   "SSE_REG_P (operands[0]) && reload_completed"
18243   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18244    (set (match_dup 2) (and:V4SF (match_dup 2)
18245                                 (match_dup 8)))
18246    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18247                                           (match_dup 3)))
18248    (set (match_dup 0) (ior:V4SF (match_dup 6)
18249                                 (match_dup 7)))]
18250 {
18251   /* If op2 == op3, op3 would be clobbered before it is used.  */
18252   if (operands_match_p (operands[2], operands[3]))
18253     {
18254       emit_move_insn (operands[0], operands[2]);
18255       DONE;
18256     }
18257
18258   PUT_MODE (operands[1], GET_MODE (operands[0]));
18259   if (operands_match_p (operands[0], operands[4]))
18260     operands[6] = operands[4], operands[7] = operands[2];
18261   else
18262     operands[6] = operands[2], operands[7] = operands[4];
18263   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18264   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18265   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18266   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18267   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18268   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18269 })
18270
18271 (define_split
18272   [(set (match_operand:DF 0 "register_operand" "")
18273         (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18274                            [(match_operand:DF 4 "register_operand" "")
18275                             (match_operand:DF 5 "nonimmediate_operand" "")])
18276                          (match_operand:DF 2 "register_operand" "")
18277                          (match_operand:DF 3 "register_operand" "")))
18278    (clobber (match_operand 6 "" ""))
18279    (clobber (reg:CC FLAGS_REG))]
18280   "SSE_REG_P (operands[0]) && reload_completed"
18281   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18282    (set (match_dup 2) (and:V2DF (match_dup 2)
18283                                 (match_dup 8)))
18284    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18285                                           (match_dup 3)))
18286    (set (match_dup 0) (ior:V2DF (match_dup 6)
18287                                 (match_dup 7)))]
18288 {
18289   if (GET_MODE (operands[2]) == DFmode
18290       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18291     {
18292       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18293       emit_insn (gen_sse2_unpcklpd (op, op, op));
18294       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18295       emit_insn (gen_sse2_unpcklpd (op, op, op));
18296     }
18297
18298   /* If op2 == op3, op3 would be clobbered before it is used.  */
18299   if (operands_match_p (operands[2], operands[3]))
18300     {
18301       emit_move_insn (operands[0], operands[2]);
18302       DONE;
18303     }
18304
18305   PUT_MODE (operands[1], GET_MODE (operands[0]));
18306   if (operands_match_p (operands[0], operands[4]))
18307     operands[6] = operands[4], operands[7] = operands[2];
18308   else
18309     operands[6] = operands[2], operands[7] = operands[4];
18310   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18311   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18312   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18313   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18314   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18315   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18316 })
18317
18318 ;; Special case of conditional move we can handle effectively.
18319 ;; Do not brother with the integer/floating point case, since these are
18320 ;; bot considerably slower, unlike in the generic case.
18321 (define_insn "*sse_movsfcc_const0_1"
18322   [(set (match_operand:SF 0 "register_operand" "=&x")
18323         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18324                         [(match_operand:SF 4 "register_operand" "0")
18325                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18326                       (match_operand:SF 2 "register_operand" "x")
18327                       (match_operand:SF 3 "const0_operand" "X")))]
18328   "TARGET_SSE"
18329   "#")
18330
18331 (define_insn "*sse_movsfcc_const0_2"
18332   [(set (match_operand:SF 0 "register_operand" "=&x")
18333         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18334                         [(match_operand:SF 4 "register_operand" "0")
18335                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18336                       (match_operand:SF 2 "const0_operand" "X")
18337                       (match_operand:SF 3 "register_operand" "x")))]
18338   "TARGET_SSE"
18339   "#")
18340
18341 (define_insn "*sse_movsfcc_const0_3"
18342   [(set (match_operand:SF 0 "register_operand" "=&x")
18343         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18344                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18345                          (match_operand:SF 5 "register_operand" "0")])
18346                       (match_operand:SF 2 "register_operand" "x")
18347                       (match_operand:SF 3 "const0_operand" "X")))]
18348   "TARGET_SSE"
18349   "#")
18350
18351 (define_insn "*sse_movsfcc_const0_4"
18352   [(set (match_operand:SF 0 "register_operand" "=&x")
18353         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18354                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18355                          (match_operand:SF 5 "register_operand" "0")])
18356                       (match_operand:SF 2 "const0_operand" "X")
18357                       (match_operand:SF 3 "register_operand" "x")))]
18358   "TARGET_SSE"
18359   "#")
18360
18361 (define_insn "*sse_movdfcc_const0_1"
18362   [(set (match_operand:DF 0 "register_operand" "=&Y")
18363         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18364                         [(match_operand:DF 4 "register_operand" "0")
18365                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18366                       (match_operand:DF 2 "register_operand" "Y")
18367                       (match_operand:DF 3 "const0_operand" "X")))]
18368   "TARGET_SSE2"
18369   "#")
18370
18371 (define_insn "*sse_movdfcc_const0_2"
18372   [(set (match_operand:DF 0 "register_operand" "=&Y")
18373         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18374                         [(match_operand:DF 4 "register_operand" "0")
18375                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18376                       (match_operand:DF 2 "const0_operand" "X")
18377                       (match_operand:DF 3 "register_operand" "Y")))]
18378   "TARGET_SSE2"
18379   "#")
18380
18381 (define_insn "*sse_movdfcc_const0_3"
18382   [(set (match_operand:DF 0 "register_operand" "=&Y")
18383         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18384                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18385                          (match_operand:DF 5 "register_operand" "0")])
18386                       (match_operand:DF 2 "register_operand" "Y")
18387                       (match_operand:DF 3 "const0_operand" "X")))]
18388   "TARGET_SSE2"
18389   "#")
18390
18391 (define_insn "*sse_movdfcc_const0_4"
18392   [(set (match_operand:DF 0 "register_operand" "=&Y")
18393         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18394                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18395                          (match_operand:DF 5 "register_operand" "0")])
18396                       (match_operand:DF 2 "const0_operand" "X")
18397                       (match_operand:DF 3 "register_operand" "Y")))]
18398   "TARGET_SSE2"
18399   "#")
18400
18401 (define_split
18402   [(set (match_operand:SF 0 "register_operand" "")
18403         (if_then_else:SF (match_operator 1 "comparison_operator"
18404                            [(match_operand:SF 4 "nonimmediate_operand" "")
18405                             (match_operand:SF 5 "nonimmediate_operand" "")])
18406                          (match_operand:SF 2 "nonmemory_operand" "")
18407                          (match_operand:SF 3 "nonmemory_operand" "")))]
18408   "SSE_REG_P (operands[0]) && reload_completed
18409    && (const0_operand (operands[2], GET_MODE (operands[0]))
18410        || const0_operand (operands[3], GET_MODE (operands[0])))"
18411   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18412    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18413 {
18414   PUT_MODE (operands[1], GET_MODE (operands[0]));
18415   if (!sse_comparison_operator (operands[1], VOIDmode)
18416       || !rtx_equal_p (operands[0], operands[4]))
18417     {
18418       rtx tmp = operands[5];
18419       operands[5] = operands[4];
18420       operands[4] = tmp;
18421       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18422     }
18423   if (!rtx_equal_p (operands[0], operands[4]))
18424     abort ();
18425   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18426   if (const0_operand (operands[2], GET_MODE (operands[2])))
18427     {
18428       operands[7] = operands[3];
18429       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18430     }
18431   else
18432     {
18433       operands[7] = operands[2];
18434       operands[6] = operands[8];
18435     }
18436   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18437 })
18438
18439 (define_split
18440   [(set (match_operand:DF 0 "register_operand" "")
18441         (if_then_else:DF (match_operator 1 "comparison_operator"
18442                            [(match_operand:DF 4 "nonimmediate_operand" "")
18443                             (match_operand:DF 5 "nonimmediate_operand" "")])
18444                          (match_operand:DF 2 "nonmemory_operand" "")
18445                          (match_operand:DF 3 "nonmemory_operand" "")))]
18446   "SSE_REG_P (operands[0]) && reload_completed
18447    && (const0_operand (operands[2], GET_MODE (operands[0]))
18448        || const0_operand (operands[3], GET_MODE (operands[0])))"
18449   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18450    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18451 {
18452   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18453       && GET_MODE (operands[2]) == DFmode)
18454     {
18455       if (REG_P (operands[2]))
18456         {
18457           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18458           emit_insn (gen_sse2_unpcklpd (op, op, op));
18459         }
18460       if (REG_P (operands[3]))
18461         {
18462           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18463           emit_insn (gen_sse2_unpcklpd (op, op, op));
18464         }
18465     }
18466   PUT_MODE (operands[1], GET_MODE (operands[0]));
18467   if (!sse_comparison_operator (operands[1], VOIDmode)
18468       || !rtx_equal_p (operands[0], operands[4]))
18469     {
18470       rtx tmp = operands[5];
18471       operands[5] = operands[4];
18472       operands[4] = tmp;
18473       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18474     }
18475   if (!rtx_equal_p (operands[0], operands[4]))
18476     abort ();
18477   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18478   if (const0_operand (operands[2], GET_MODE (operands[2])))
18479     {
18480       operands[7] = operands[3];
18481       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18482     }
18483   else
18484     {
18485       operands[7] = operands[2];
18486       operands[6] = operands[8];
18487     }
18488   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18489 })
18490
18491 (define_expand "allocate_stack_worker"
18492   [(match_operand:SI 0 "register_operand" "")]
18493   "TARGET_STACK_PROBE"
18494 {
18495   if (reload_completed)
18496     {
18497       if (TARGET_64BIT)
18498         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18499       else
18500         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18501     }
18502   else
18503     {
18504       if (TARGET_64BIT)
18505         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18506       else
18507         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18508     }
18509   DONE;
18510 })
18511
18512 (define_insn "allocate_stack_worker_1"
18513   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18514     UNSPECV_STACK_PROBE)
18515    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18516    (clobber (match_scratch:SI 1 "=0"))
18517    (clobber (reg:CC FLAGS_REG))]
18518   "!TARGET_64BIT && TARGET_STACK_PROBE"
18519   "call\t__alloca"
18520   [(set_attr "type" "multi")
18521    (set_attr "length" "5")])
18522
18523 (define_expand "allocate_stack_worker_postreload"
18524   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18525                                     UNSPECV_STACK_PROBE)
18526               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18527               (clobber (match_dup 0))
18528               (clobber (reg:CC FLAGS_REG))])]
18529   ""
18530   "")
18531
18532 (define_insn "allocate_stack_worker_rex64"
18533   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18534     UNSPECV_STACK_PROBE)
18535    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18536    (clobber (match_scratch:DI 1 "=0"))
18537    (clobber (reg:CC FLAGS_REG))]
18538   "TARGET_64BIT && TARGET_STACK_PROBE"
18539   "call\t__alloca"
18540   [(set_attr "type" "multi")
18541    (set_attr "length" "5")])
18542
18543 (define_expand "allocate_stack_worker_rex64_postreload"
18544   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18545                                     UNSPECV_STACK_PROBE)
18546               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18547               (clobber (match_dup 0))
18548               (clobber (reg:CC FLAGS_REG))])]
18549   ""
18550   "")
18551
18552 (define_expand "allocate_stack"
18553   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18554                    (minus:SI (reg:SI SP_REG)
18555                              (match_operand:SI 1 "general_operand" "")))
18556               (clobber (reg:CC FLAGS_REG))])
18557    (parallel [(set (reg:SI SP_REG)
18558                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18559               (clobber (reg:CC FLAGS_REG))])]
18560   "TARGET_STACK_PROBE"
18561 {
18562 #ifdef CHECK_STACK_LIMIT
18563   if (GET_CODE (operands[1]) == CONST_INT
18564       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18565     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18566                            operands[1]));
18567   else 
18568 #endif
18569     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18570                                                             operands[1])));
18571
18572   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18573   DONE;
18574 })
18575
18576 (define_expand "builtin_setjmp_receiver"
18577   [(label_ref (match_operand 0 "" ""))]
18578   "!TARGET_64BIT && flag_pic"
18579 {
18580   emit_insn (gen_set_got (pic_offset_table_rtx));
18581   DONE;
18582 })
18583 \f
18584 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18585
18586 (define_split
18587   [(set (match_operand 0 "register_operand" "")
18588         (match_operator 3 "promotable_binary_operator"
18589            [(match_operand 1 "register_operand" "")
18590             (match_operand 2 "aligned_operand" "")]))
18591    (clobber (reg:CC FLAGS_REG))]
18592   "! TARGET_PARTIAL_REG_STALL && reload_completed
18593    && ((GET_MODE (operands[0]) == HImode 
18594         && ((!optimize_size && !TARGET_FAST_PREFIX)
18595             || GET_CODE (operands[2]) != CONST_INT
18596             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18597        || (GET_MODE (operands[0]) == QImode 
18598            && (TARGET_PROMOTE_QImode || optimize_size)))"
18599   [(parallel [(set (match_dup 0)
18600                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18601               (clobber (reg:CC FLAGS_REG))])]
18602   "operands[0] = gen_lowpart (SImode, operands[0]);
18603    operands[1] = gen_lowpart (SImode, operands[1]);
18604    if (GET_CODE (operands[3]) != ASHIFT)
18605      operands[2] = gen_lowpart (SImode, operands[2]);
18606    PUT_MODE (operands[3], SImode);")
18607
18608 ; Promote the QImode tests, as i386 has encoding of the AND
18609 ; instruction with 32-bit sign-extended immediate and thus the
18610 ; instruction size is unchanged, except in the %eax case for
18611 ; which it is increased by one byte, hence the ! optimize_size.
18612 (define_split
18613   [(set (match_operand 0 "flags_reg_operand" "")
18614         (match_operator 2 "compare_operator"
18615           [(and (match_operand 3 "aligned_operand" "")
18616                 (match_operand 4 "const_int_operand" ""))
18617            (const_int 0)]))
18618    (set (match_operand 1 "register_operand" "")
18619         (and (match_dup 3) (match_dup 4)))]
18620   "! TARGET_PARTIAL_REG_STALL && reload_completed
18621    /* Ensure that the operand will remain sign-extended immediate.  */
18622    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18623    && ! optimize_size
18624    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18625        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18626   [(parallel [(set (match_dup 0)
18627                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18628                                     (const_int 0)]))
18629               (set (match_dup 1)
18630                    (and:SI (match_dup 3) (match_dup 4)))])]
18631 {
18632   operands[4]
18633     = gen_int_mode (INTVAL (operands[4])
18634                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18635   operands[1] = gen_lowpart (SImode, operands[1]);
18636   operands[3] = gen_lowpart (SImode, operands[3]);
18637 })
18638
18639 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18640 ; the TEST instruction with 32-bit sign-extended immediate and thus
18641 ; the instruction size would at least double, which is not what we
18642 ; want even with ! optimize_size.
18643 (define_split
18644   [(set (match_operand 0 "flags_reg_operand" "")
18645         (match_operator 1 "compare_operator"
18646           [(and (match_operand:HI 2 "aligned_operand" "")
18647                 (match_operand:HI 3 "const_int_operand" ""))
18648            (const_int 0)]))]
18649   "! TARGET_PARTIAL_REG_STALL && reload_completed
18650    /* Ensure that the operand will remain sign-extended immediate.  */
18651    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18652    && ! TARGET_FAST_PREFIX
18653    && ! optimize_size"
18654   [(set (match_dup 0)
18655         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18656                          (const_int 0)]))]
18657 {
18658   operands[3]
18659     = gen_int_mode (INTVAL (operands[3])
18660                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18661   operands[2] = gen_lowpart (SImode, operands[2]);
18662 })
18663
18664 (define_split
18665   [(set (match_operand 0 "register_operand" "")
18666         (neg (match_operand 1 "register_operand" "")))
18667    (clobber (reg:CC FLAGS_REG))]
18668   "! TARGET_PARTIAL_REG_STALL && reload_completed
18669    && (GET_MODE (operands[0]) == HImode
18670        || (GET_MODE (operands[0]) == QImode 
18671            && (TARGET_PROMOTE_QImode || optimize_size)))"
18672   [(parallel [(set (match_dup 0)
18673                    (neg:SI (match_dup 1)))
18674               (clobber (reg:CC FLAGS_REG))])]
18675   "operands[0] = gen_lowpart (SImode, operands[0]);
18676    operands[1] = gen_lowpart (SImode, operands[1]);")
18677
18678 (define_split
18679   [(set (match_operand 0 "register_operand" "")
18680         (not (match_operand 1 "register_operand" "")))]
18681   "! TARGET_PARTIAL_REG_STALL && reload_completed
18682    && (GET_MODE (operands[0]) == HImode
18683        || (GET_MODE (operands[0]) == QImode 
18684            && (TARGET_PROMOTE_QImode || optimize_size)))"
18685   [(set (match_dup 0)
18686         (not:SI (match_dup 1)))]
18687   "operands[0] = gen_lowpart (SImode, operands[0]);
18688    operands[1] = gen_lowpart (SImode, operands[1]);")
18689
18690 (define_split 
18691   [(set (match_operand 0 "register_operand" "")
18692         (if_then_else (match_operator 1 "comparison_operator" 
18693                                 [(reg FLAGS_REG) (const_int 0)])
18694                       (match_operand 2 "register_operand" "")
18695                       (match_operand 3 "register_operand" "")))]
18696   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18697    && (GET_MODE (operands[0]) == HImode
18698        || (GET_MODE (operands[0]) == QImode 
18699            && (TARGET_PROMOTE_QImode || optimize_size)))"
18700   [(set (match_dup 0)
18701         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18702   "operands[0] = gen_lowpart (SImode, operands[0]);
18703    operands[2] = gen_lowpart (SImode, operands[2]);
18704    operands[3] = gen_lowpart (SImode, operands[3]);")
18705                         
18706 \f
18707 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18708 ;; transform a complex memory operation into two memory to register operations.
18709
18710 ;; Don't push memory operands
18711 (define_peephole2
18712   [(set (match_operand:SI 0 "push_operand" "")
18713         (match_operand:SI 1 "memory_operand" ""))
18714    (match_scratch:SI 2 "r")]
18715   "! optimize_size && ! TARGET_PUSH_MEMORY"
18716   [(set (match_dup 2) (match_dup 1))
18717    (set (match_dup 0) (match_dup 2))]
18718   "")
18719
18720 (define_peephole2
18721   [(set (match_operand:DI 0 "push_operand" "")
18722         (match_operand:DI 1 "memory_operand" ""))
18723    (match_scratch:DI 2 "r")]
18724   "! optimize_size && ! TARGET_PUSH_MEMORY"
18725   [(set (match_dup 2) (match_dup 1))
18726    (set (match_dup 0) (match_dup 2))]
18727   "")
18728
18729 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18730 ;; SImode pushes.
18731 (define_peephole2
18732   [(set (match_operand:SF 0 "push_operand" "")
18733         (match_operand:SF 1 "memory_operand" ""))
18734    (match_scratch:SF 2 "r")]
18735   "! optimize_size && ! TARGET_PUSH_MEMORY"
18736   [(set (match_dup 2) (match_dup 1))
18737    (set (match_dup 0) (match_dup 2))]
18738   "")
18739
18740 (define_peephole2
18741   [(set (match_operand:HI 0 "push_operand" "")
18742         (match_operand:HI 1 "memory_operand" ""))
18743    (match_scratch:HI 2 "r")]
18744   "! optimize_size && ! TARGET_PUSH_MEMORY"
18745   [(set (match_dup 2) (match_dup 1))
18746    (set (match_dup 0) (match_dup 2))]
18747   "")
18748
18749 (define_peephole2
18750   [(set (match_operand:QI 0 "push_operand" "")
18751         (match_operand:QI 1 "memory_operand" ""))
18752    (match_scratch:QI 2 "q")]
18753   "! optimize_size && ! TARGET_PUSH_MEMORY"
18754   [(set (match_dup 2) (match_dup 1))
18755    (set (match_dup 0) (match_dup 2))]
18756   "")
18757
18758 ;; Don't move an immediate directly to memory when the instruction
18759 ;; gets too big.
18760 (define_peephole2
18761   [(match_scratch:SI 1 "r")
18762    (set (match_operand:SI 0 "memory_operand" "")
18763         (const_int 0))]
18764   "! optimize_size
18765    && ! TARGET_USE_MOV0
18766    && TARGET_SPLIT_LONG_MOVES
18767    && get_attr_length (insn) >= ix86_cost->large_insn
18768    && peep2_regno_dead_p (0, FLAGS_REG)"
18769   [(parallel [(set (match_dup 1) (const_int 0))
18770               (clobber (reg:CC FLAGS_REG))])
18771    (set (match_dup 0) (match_dup 1))]
18772   "")
18773
18774 (define_peephole2
18775   [(match_scratch:HI 1 "r")
18776    (set (match_operand:HI 0 "memory_operand" "")
18777         (const_int 0))]
18778   "! optimize_size
18779    && ! TARGET_USE_MOV0
18780    && TARGET_SPLIT_LONG_MOVES
18781    && get_attr_length (insn) >= ix86_cost->large_insn
18782    && peep2_regno_dead_p (0, FLAGS_REG)"
18783   [(parallel [(set (match_dup 2) (const_int 0))
18784               (clobber (reg:CC FLAGS_REG))])
18785    (set (match_dup 0) (match_dup 1))]
18786   "operands[2] = gen_lowpart (SImode, operands[1]);")
18787
18788 (define_peephole2
18789   [(match_scratch:QI 1 "q")
18790    (set (match_operand:QI 0 "memory_operand" "")
18791         (const_int 0))]
18792   "! optimize_size
18793    && ! TARGET_USE_MOV0
18794    && TARGET_SPLIT_LONG_MOVES
18795    && get_attr_length (insn) >= ix86_cost->large_insn
18796    && peep2_regno_dead_p (0, FLAGS_REG)"
18797   [(parallel [(set (match_dup 2) (const_int 0))
18798               (clobber (reg:CC FLAGS_REG))])
18799    (set (match_dup 0) (match_dup 1))]
18800   "operands[2] = gen_lowpart (SImode, operands[1]);")
18801
18802 (define_peephole2
18803   [(match_scratch:SI 2 "r")
18804    (set (match_operand:SI 0 "memory_operand" "")
18805         (match_operand:SI 1 "immediate_operand" ""))]
18806   "! optimize_size
18807    && get_attr_length (insn) >= ix86_cost->large_insn
18808    && TARGET_SPLIT_LONG_MOVES"
18809   [(set (match_dup 2) (match_dup 1))
18810    (set (match_dup 0) (match_dup 2))]
18811   "")
18812
18813 (define_peephole2
18814   [(match_scratch:HI 2 "r")
18815    (set (match_operand:HI 0 "memory_operand" "")
18816         (match_operand:HI 1 "immediate_operand" ""))]
18817   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18818   && TARGET_SPLIT_LONG_MOVES"
18819   [(set (match_dup 2) (match_dup 1))
18820    (set (match_dup 0) (match_dup 2))]
18821   "")
18822
18823 (define_peephole2
18824   [(match_scratch:QI 2 "q")
18825    (set (match_operand:QI 0 "memory_operand" "")
18826         (match_operand:QI 1 "immediate_operand" ""))]
18827   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18828   && TARGET_SPLIT_LONG_MOVES"
18829   [(set (match_dup 2) (match_dup 1))
18830    (set (match_dup 0) (match_dup 2))]
18831   "")
18832
18833 ;; Don't compare memory with zero, load and use a test instead.
18834 (define_peephole2
18835   [(set (match_operand 0 "flags_reg_operand" "")
18836         (match_operator 1 "compare_operator"
18837           [(match_operand:SI 2 "memory_operand" "")
18838            (const_int 0)]))
18839    (match_scratch:SI 3 "r")]
18840   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18841   [(set (match_dup 3) (match_dup 2))
18842    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18843   "")
18844
18845 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18846 ;; Don't split NOTs with a displacement operand, because resulting XOR
18847 ;; will not be pairable anyway.
18848 ;;
18849 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18850 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18851 ;; so this split helps here as well.
18852 ;;
18853 ;; Note: Can't do this as a regular split because we can't get proper
18854 ;; lifetime information then.
18855
18856 (define_peephole2
18857   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18858         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18859   "!optimize_size
18860    && peep2_regno_dead_p (0, FLAGS_REG)
18861    && ((TARGET_PENTIUM 
18862         && (GET_CODE (operands[0]) != MEM
18863             || !memory_displacement_operand (operands[0], SImode)))
18864        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18865   [(parallel [(set (match_dup 0)
18866                    (xor:SI (match_dup 1) (const_int -1)))
18867               (clobber (reg:CC FLAGS_REG))])]
18868   "")
18869
18870 (define_peephole2
18871   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18872         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18873   "!optimize_size
18874    && peep2_regno_dead_p (0, FLAGS_REG)
18875    && ((TARGET_PENTIUM 
18876         && (GET_CODE (operands[0]) != MEM
18877             || !memory_displacement_operand (operands[0], HImode)))
18878        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18879   [(parallel [(set (match_dup 0)
18880                    (xor:HI (match_dup 1) (const_int -1)))
18881               (clobber (reg:CC FLAGS_REG))])]
18882   "")
18883
18884 (define_peephole2
18885   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18886         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18887   "!optimize_size
18888    && peep2_regno_dead_p (0, FLAGS_REG)
18889    && ((TARGET_PENTIUM 
18890         && (GET_CODE (operands[0]) != MEM
18891             || !memory_displacement_operand (operands[0], QImode)))
18892        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18893   [(parallel [(set (match_dup 0)
18894                    (xor:QI (match_dup 1) (const_int -1)))
18895               (clobber (reg:CC FLAGS_REG))])]
18896   "")
18897
18898 ;; Non pairable "test imm, reg" instructions can be translated to
18899 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18900 ;; byte opcode instead of two, have a short form for byte operands),
18901 ;; so do it for other CPUs as well.  Given that the value was dead,
18902 ;; this should not create any new dependencies.  Pass on the sub-word
18903 ;; versions if we're concerned about partial register stalls.
18904
18905 (define_peephole2
18906   [(set (match_operand 0 "flags_reg_operand" "")
18907         (match_operator 1 "compare_operator"
18908           [(and:SI (match_operand:SI 2 "register_operand" "")
18909                    (match_operand:SI 3 "immediate_operand" ""))
18910            (const_int 0)]))]
18911   "ix86_match_ccmode (insn, CCNOmode)
18912    && (true_regnum (operands[2]) != 0
18913        || (GET_CODE (operands[3]) == CONST_INT
18914            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18915    && peep2_reg_dead_p (1, operands[2])"
18916   [(parallel
18917      [(set (match_dup 0)
18918            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18919                             (const_int 0)]))
18920       (set (match_dup 2)
18921            (and:SI (match_dup 2) (match_dup 3)))])]
18922   "")
18923
18924 ;; We don't need to handle HImode case, because it will be promoted to SImode
18925 ;; on ! TARGET_PARTIAL_REG_STALL
18926
18927 (define_peephole2
18928   [(set (match_operand 0 "flags_reg_operand" "")
18929         (match_operator 1 "compare_operator"
18930           [(and:QI (match_operand:QI 2 "register_operand" "")
18931                    (match_operand:QI 3 "immediate_operand" ""))
18932            (const_int 0)]))]
18933   "! TARGET_PARTIAL_REG_STALL
18934    && ix86_match_ccmode (insn, CCNOmode)
18935    && true_regnum (operands[2]) != 0
18936    && peep2_reg_dead_p (1, operands[2])"
18937   [(parallel
18938      [(set (match_dup 0)
18939            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18940                             (const_int 0)]))
18941       (set (match_dup 2)
18942            (and:QI (match_dup 2) (match_dup 3)))])]
18943   "")
18944
18945 (define_peephole2
18946   [(set (match_operand 0 "flags_reg_operand" "")
18947         (match_operator 1 "compare_operator"
18948           [(and:SI
18949              (zero_extract:SI
18950                (match_operand 2 "ext_register_operand" "")
18951                (const_int 8)
18952                (const_int 8))
18953              (match_operand 3 "const_int_operand" ""))
18954            (const_int 0)]))]
18955   "! TARGET_PARTIAL_REG_STALL
18956    && ix86_match_ccmode (insn, CCNOmode)
18957    && true_regnum (operands[2]) != 0
18958    && peep2_reg_dead_p (1, operands[2])"
18959   [(parallel [(set (match_dup 0)
18960                    (match_op_dup 1
18961                      [(and:SI
18962                         (zero_extract:SI
18963                           (match_dup 2)
18964                           (const_int 8)
18965                           (const_int 8))
18966                         (match_dup 3))
18967                       (const_int 0)]))
18968               (set (zero_extract:SI (match_dup 2)
18969                                     (const_int 8)
18970                                     (const_int 8))
18971                    (and:SI 
18972                      (zero_extract:SI
18973                        (match_dup 2)
18974                        (const_int 8)
18975                        (const_int 8))
18976                      (match_dup 3)))])]
18977   "")
18978
18979 ;; Don't do logical operations with memory inputs.
18980 (define_peephole2
18981   [(match_scratch:SI 2 "r")
18982    (parallel [(set (match_operand:SI 0 "register_operand" "")
18983                    (match_operator:SI 3 "arith_or_logical_operator"
18984                      [(match_dup 0)
18985                       (match_operand:SI 1 "memory_operand" "")]))
18986               (clobber (reg:CC FLAGS_REG))])]
18987   "! optimize_size && ! TARGET_READ_MODIFY"
18988   [(set (match_dup 2) (match_dup 1))
18989    (parallel [(set (match_dup 0)
18990                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18991               (clobber (reg:CC FLAGS_REG))])]
18992   "")
18993
18994 (define_peephole2
18995   [(match_scratch:SI 2 "r")
18996    (parallel [(set (match_operand:SI 0 "register_operand" "")
18997                    (match_operator:SI 3 "arith_or_logical_operator"
18998                      [(match_operand:SI 1 "memory_operand" "")
18999                       (match_dup 0)]))
19000               (clobber (reg:CC FLAGS_REG))])]
19001   "! optimize_size && ! TARGET_READ_MODIFY"
19002   [(set (match_dup 2) (match_dup 1))
19003    (parallel [(set (match_dup 0)
19004                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19005               (clobber (reg:CC FLAGS_REG))])]
19006   "")
19007
19008 ; Don't do logical operations with memory outputs
19009 ;
19010 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19011 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19012 ; the same decoder scheduling characteristics as the original.
19013
19014 (define_peephole2
19015   [(match_scratch:SI 2 "r")
19016    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19017                    (match_operator:SI 3 "arith_or_logical_operator"
19018                      [(match_dup 0)
19019                       (match_operand:SI 1 "nonmemory_operand" "")]))
19020               (clobber (reg:CC FLAGS_REG))])]
19021   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19022   [(set (match_dup 2) (match_dup 0))
19023    (parallel [(set (match_dup 2)
19024                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19025               (clobber (reg:CC FLAGS_REG))])
19026    (set (match_dup 0) (match_dup 2))]
19027   "")
19028
19029 (define_peephole2
19030   [(match_scratch:SI 2 "r")
19031    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19032                    (match_operator:SI 3 "arith_or_logical_operator"
19033                      [(match_operand:SI 1 "nonmemory_operand" "")
19034                       (match_dup 0)]))
19035               (clobber (reg:CC FLAGS_REG))])]
19036   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19037   [(set (match_dup 2) (match_dup 0))
19038    (parallel [(set (match_dup 2)
19039                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19040               (clobber (reg:CC FLAGS_REG))])
19041    (set (match_dup 0) (match_dup 2))]
19042   "")
19043
19044 ;; Attempt to always use XOR for zeroing registers.
19045 (define_peephole2
19046   [(set (match_operand 0 "register_operand" "")
19047         (const_int 0))]
19048   "(GET_MODE (operands[0]) == QImode
19049     || GET_MODE (operands[0]) == HImode
19050     || GET_MODE (operands[0]) == SImode
19051     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19052    && (! TARGET_USE_MOV0 || optimize_size)
19053    && peep2_regno_dead_p (0, FLAGS_REG)"
19054   [(parallel [(set (match_dup 0) (const_int 0))
19055               (clobber (reg:CC FLAGS_REG))])]
19056   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19057                               operands[0]);")
19058
19059 (define_peephole2
19060   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19061         (const_int 0))]
19062   "(GET_MODE (operands[0]) == QImode
19063     || GET_MODE (operands[0]) == HImode)
19064    && (! TARGET_USE_MOV0 || optimize_size)
19065    && peep2_regno_dead_p (0, FLAGS_REG)"
19066   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19067               (clobber (reg:CC FLAGS_REG))])])
19068
19069 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19070 (define_peephole2
19071   [(set (match_operand 0 "register_operand" "")
19072         (const_int -1))]
19073   "(GET_MODE (operands[0]) == HImode
19074     || GET_MODE (operands[0]) == SImode 
19075     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19076    && (optimize_size || TARGET_PENTIUM)
19077    && peep2_regno_dead_p (0, FLAGS_REG)"
19078   [(parallel [(set (match_dup 0) (const_int -1))
19079               (clobber (reg:CC FLAGS_REG))])]
19080   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19081                               operands[0]);")
19082
19083 ;; Attempt to convert simple leas to adds. These can be created by
19084 ;; move expanders.
19085 (define_peephole2
19086   [(set (match_operand:SI 0 "register_operand" "")
19087         (plus:SI (match_dup 0)
19088                  (match_operand:SI 1 "nonmemory_operand" "")))]
19089   "peep2_regno_dead_p (0, FLAGS_REG)"
19090   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19091               (clobber (reg:CC FLAGS_REG))])]
19092   "")
19093
19094 (define_peephole2
19095   [(set (match_operand:SI 0 "register_operand" "")
19096         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19097                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19098   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19099   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19100               (clobber (reg:CC FLAGS_REG))])]
19101   "operands[2] = gen_lowpart (SImode, operands[2]);")
19102
19103 (define_peephole2
19104   [(set (match_operand:DI 0 "register_operand" "")
19105         (plus:DI (match_dup 0)
19106                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19107   "peep2_regno_dead_p (0, FLAGS_REG)"
19108   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19109               (clobber (reg:CC FLAGS_REG))])]
19110   "")
19111
19112 (define_peephole2
19113   [(set (match_operand:SI 0 "register_operand" "")
19114         (mult:SI (match_dup 0)
19115                  (match_operand:SI 1 "const_int_operand" "")))]
19116   "exact_log2 (INTVAL (operands[1])) >= 0
19117    && peep2_regno_dead_p (0, FLAGS_REG)"
19118   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19119               (clobber (reg:CC FLAGS_REG))])]
19120   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19121
19122 (define_peephole2
19123   [(set (match_operand:DI 0 "register_operand" "")
19124         (mult:DI (match_dup 0)
19125                  (match_operand:DI 1 "const_int_operand" "")))]
19126   "exact_log2 (INTVAL (operands[1])) >= 0
19127    && peep2_regno_dead_p (0, FLAGS_REG)"
19128   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19129               (clobber (reg:CC FLAGS_REG))])]
19130   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19131
19132 (define_peephole2
19133   [(set (match_operand:SI 0 "register_operand" "")
19134         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19135                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19136   "exact_log2 (INTVAL (operands[2])) >= 0
19137    && REGNO (operands[0]) == REGNO (operands[1])
19138    && peep2_regno_dead_p (0, FLAGS_REG)"
19139   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19140               (clobber (reg:CC FLAGS_REG))])]
19141   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19142
19143 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19144 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19145 ;; many CPUs it is also faster, since special hardware to avoid esp
19146 ;; dependencies is present.
19147
19148 ;; While some of these conversions may be done using splitters, we use peepholes
19149 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19150
19151 ;; Convert prologue esp subtractions to push.
19152 ;; We need register to push.  In order to keep verify_flow_info happy we have
19153 ;; two choices
19154 ;; - use scratch and clobber it in order to avoid dependencies
19155 ;; - use already live register
19156 ;; We can't use the second way right now, since there is no reliable way how to
19157 ;; verify that given register is live.  First choice will also most likely in
19158 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19159 ;; call clobbered registers are dead.  We may want to use base pointer as an
19160 ;; alternative when no register is available later.
19161
19162 (define_peephole2
19163   [(match_scratch:SI 0 "r")
19164    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19165               (clobber (reg:CC FLAGS_REG))
19166               (clobber (mem:BLK (scratch)))])]
19167   "optimize_size || !TARGET_SUB_ESP_4"
19168   [(clobber (match_dup 0))
19169    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19170               (clobber (mem:BLK (scratch)))])])
19171
19172 (define_peephole2
19173   [(match_scratch:SI 0 "r")
19174    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19175               (clobber (reg:CC FLAGS_REG))
19176               (clobber (mem:BLK (scratch)))])]
19177   "optimize_size || !TARGET_SUB_ESP_8"
19178   [(clobber (match_dup 0))
19179    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19180    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19181               (clobber (mem:BLK (scratch)))])])
19182
19183 ;; Convert esp subtractions to push.
19184 (define_peephole2
19185   [(match_scratch:SI 0 "r")
19186    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19187               (clobber (reg:CC FLAGS_REG))])]
19188   "optimize_size || !TARGET_SUB_ESP_4"
19189   [(clobber (match_dup 0))
19190    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19191
19192 (define_peephole2
19193   [(match_scratch:SI 0 "r")
19194    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19195               (clobber (reg:CC FLAGS_REG))])]
19196   "optimize_size || !TARGET_SUB_ESP_8"
19197   [(clobber (match_dup 0))
19198    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19199    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19200
19201 ;; Convert epilogue deallocator to pop.
19202 (define_peephole2
19203   [(match_scratch:SI 0 "r")
19204    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19205               (clobber (reg:CC FLAGS_REG))
19206               (clobber (mem:BLK (scratch)))])]
19207   "optimize_size || !TARGET_ADD_ESP_4"
19208   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19209               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19210               (clobber (mem:BLK (scratch)))])]
19211   "")
19212
19213 ;; Two pops case is tricky, since pop causes dependency on destination register.
19214 ;; We use two registers if available.
19215 (define_peephole2
19216   [(match_scratch:SI 0 "r")
19217    (match_scratch:SI 1 "r")
19218    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19219               (clobber (reg:CC FLAGS_REG))
19220               (clobber (mem:BLK (scratch)))])]
19221   "optimize_size || !TARGET_ADD_ESP_8"
19222   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19223               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19224               (clobber (mem:BLK (scratch)))])
19225    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19226               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19227   "")
19228
19229 (define_peephole2
19230   [(match_scratch:SI 0 "r")
19231    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19232               (clobber (reg:CC FLAGS_REG))
19233               (clobber (mem:BLK (scratch)))])]
19234   "optimize_size"
19235   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19236               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19237               (clobber (mem:BLK (scratch)))])
19238    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19239               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19240   "")
19241
19242 ;; Convert esp additions to pop.
19243 (define_peephole2
19244   [(match_scratch:SI 0 "r")
19245    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   ""
19248   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19249               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19250   "")
19251
19252 ;; Two pops case is tricky, since pop causes dependency on destination register.
19253 ;; We use two registers if available.
19254 (define_peephole2
19255   [(match_scratch:SI 0 "r")
19256    (match_scratch:SI 1 "r")
19257    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19258               (clobber (reg:CC FLAGS_REG))])]
19259   ""
19260   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19261               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19262    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19263               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19264   "")
19265
19266 (define_peephole2
19267   [(match_scratch:SI 0 "r")
19268    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19269               (clobber (reg:CC FLAGS_REG))])]
19270   "optimize_size"
19271   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19272               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19273    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19274               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19275   "")
19276 \f
19277 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19278 ;; required and register dies.  Similarly for 128 to plus -128.
19279 (define_peephole2
19280   [(set (match_operand 0 "flags_reg_operand" "")
19281         (match_operator 1 "compare_operator"
19282           [(match_operand 2 "register_operand" "")
19283            (match_operand 3 "const_int_operand" "")]))]
19284   "(INTVAL (operands[3]) == -1
19285     || INTVAL (operands[3]) == 1
19286     || INTVAL (operands[3]) == 128)
19287    && ix86_match_ccmode (insn, CCGCmode)
19288    && peep2_reg_dead_p (1, operands[2])"
19289   [(parallel [(set (match_dup 0)
19290                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19291               (clobber (match_dup 2))])]
19292   "")
19293 \f
19294 (define_peephole2
19295   [(match_scratch:DI 0 "r")
19296    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19297               (clobber (reg:CC FLAGS_REG))
19298               (clobber (mem:BLK (scratch)))])]
19299   "optimize_size || !TARGET_SUB_ESP_4"
19300   [(clobber (match_dup 0))
19301    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19302               (clobber (mem:BLK (scratch)))])])
19303
19304 (define_peephole2
19305   [(match_scratch:DI 0 "r")
19306    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19307               (clobber (reg:CC FLAGS_REG))
19308               (clobber (mem:BLK (scratch)))])]
19309   "optimize_size || !TARGET_SUB_ESP_8"
19310   [(clobber (match_dup 0))
19311    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19312    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19313               (clobber (mem:BLK (scratch)))])])
19314
19315 ;; Convert esp subtractions to push.
19316 (define_peephole2
19317   [(match_scratch:DI 0 "r")
19318    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19319               (clobber (reg:CC FLAGS_REG))])]
19320   "optimize_size || !TARGET_SUB_ESP_4"
19321   [(clobber (match_dup 0))
19322    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19323
19324 (define_peephole2
19325   [(match_scratch:DI 0 "r")
19326    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19327               (clobber (reg:CC FLAGS_REG))])]
19328   "optimize_size || !TARGET_SUB_ESP_8"
19329   [(clobber (match_dup 0))
19330    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19331    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19332
19333 ;; Convert epilogue deallocator to pop.
19334 (define_peephole2
19335   [(match_scratch:DI 0 "r")
19336    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19337               (clobber (reg:CC FLAGS_REG))
19338               (clobber (mem:BLK (scratch)))])]
19339   "optimize_size || !TARGET_ADD_ESP_4"
19340   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19341               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19342               (clobber (mem:BLK (scratch)))])]
19343   "")
19344
19345 ;; Two pops case is tricky, since pop causes dependency on destination register.
19346 ;; We use two registers if available.
19347 (define_peephole2
19348   [(match_scratch:DI 0 "r")
19349    (match_scratch:DI 1 "r")
19350    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19351               (clobber (reg:CC FLAGS_REG))
19352               (clobber (mem:BLK (scratch)))])]
19353   "optimize_size || !TARGET_ADD_ESP_8"
19354   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19355               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19356               (clobber (mem:BLK (scratch)))])
19357    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19358               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19359   "")
19360
19361 (define_peephole2
19362   [(match_scratch:DI 0 "r")
19363    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19364               (clobber (reg:CC FLAGS_REG))
19365               (clobber (mem:BLK (scratch)))])]
19366   "optimize_size"
19367   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19368               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19369               (clobber (mem:BLK (scratch)))])
19370    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19371               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19372   "")
19373
19374 ;; Convert esp additions to pop.
19375 (define_peephole2
19376   [(match_scratch:DI 0 "r")
19377    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19378               (clobber (reg:CC FLAGS_REG))])]
19379   ""
19380   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19381               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19382   "")
19383
19384 ;; Two pops case is tricky, since pop causes dependency on destination register.
19385 ;; We use two registers if available.
19386 (define_peephole2
19387   [(match_scratch:DI 0 "r")
19388    (match_scratch:DI 1 "r")
19389    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19390               (clobber (reg:CC FLAGS_REG))])]
19391   ""
19392   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19393               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19394    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19395               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19396   "")
19397
19398 (define_peephole2
19399   [(match_scratch:DI 0 "r")
19400    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19401               (clobber (reg:CC FLAGS_REG))])]
19402   "optimize_size"
19403   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19404               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19405    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19406               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19407   "")
19408 \f
19409 ;; Convert imul by three, five and nine into lea
19410 (define_peephole2
19411   [(parallel
19412     [(set (match_operand:SI 0 "register_operand" "")
19413           (mult:SI (match_operand:SI 1 "register_operand" "")
19414                    (match_operand:SI 2 "const_int_operand" "")))
19415      (clobber (reg:CC FLAGS_REG))])]
19416   "INTVAL (operands[2]) == 3
19417    || INTVAL (operands[2]) == 5
19418    || INTVAL (operands[2]) == 9"
19419   [(set (match_dup 0)
19420         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19421                  (match_dup 1)))]
19422   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19423
19424 (define_peephole2
19425   [(parallel
19426     [(set (match_operand:SI 0 "register_operand" "")
19427           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19428                    (match_operand:SI 2 "const_int_operand" "")))
19429      (clobber (reg:CC FLAGS_REG))])]
19430   "!optimize_size 
19431    && (INTVAL (operands[2]) == 3
19432        || INTVAL (operands[2]) == 5
19433        || INTVAL (operands[2]) == 9)"
19434   [(set (match_dup 0) (match_dup 1))
19435    (set (match_dup 0)
19436         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19437                  (match_dup 0)))]
19438   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19439
19440 (define_peephole2
19441   [(parallel
19442     [(set (match_operand:DI 0 "register_operand" "")
19443           (mult:DI (match_operand:DI 1 "register_operand" "")
19444                    (match_operand:DI 2 "const_int_operand" "")))
19445      (clobber (reg:CC FLAGS_REG))])]
19446   "TARGET_64BIT
19447    && (INTVAL (operands[2]) == 3
19448        || INTVAL (operands[2]) == 5
19449        || INTVAL (operands[2]) == 9)"
19450   [(set (match_dup 0)
19451         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19452                  (match_dup 1)))]
19453   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19454
19455 (define_peephole2
19456   [(parallel
19457     [(set (match_operand:DI 0 "register_operand" "")
19458           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19459                    (match_operand:DI 2 "const_int_operand" "")))
19460      (clobber (reg:CC FLAGS_REG))])]
19461   "TARGET_64BIT
19462    && !optimize_size 
19463    && (INTVAL (operands[2]) == 3
19464        || INTVAL (operands[2]) == 5
19465        || INTVAL (operands[2]) == 9)"
19466   [(set (match_dup 0) (match_dup 1))
19467    (set (match_dup 0)
19468         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19469                  (match_dup 0)))]
19470   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19471
19472 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19473 ;; imul $32bit_imm, reg, reg is direct decoded.
19474 (define_peephole2
19475   [(match_scratch:DI 3 "r")
19476    (parallel [(set (match_operand:DI 0 "register_operand" "")
19477                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19478                             (match_operand:DI 2 "immediate_operand" "")))
19479               (clobber (reg:CC FLAGS_REG))])]
19480   "TARGET_K8 && !optimize_size
19481    && (GET_CODE (operands[2]) != CONST_INT
19482        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19483   [(set (match_dup 3) (match_dup 1))
19484    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19485               (clobber (reg:CC FLAGS_REG))])]
19486 "")
19487
19488 (define_peephole2
19489   [(match_scratch:SI 3 "r")
19490    (parallel [(set (match_operand:SI 0 "register_operand" "")
19491                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19492                             (match_operand:SI 2 "immediate_operand" "")))
19493               (clobber (reg:CC FLAGS_REG))])]
19494   "TARGET_K8 && !optimize_size
19495    && (GET_CODE (operands[2]) != CONST_INT
19496        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19497   [(set (match_dup 3) (match_dup 1))
19498    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19499               (clobber (reg:CC FLAGS_REG))])]
19500 "")
19501
19502 (define_peephole2
19503   [(match_scratch:SI 3 "r")
19504    (parallel [(set (match_operand:DI 0 "register_operand" "")
19505                    (zero_extend:DI
19506                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19507                               (match_operand:SI 2 "immediate_operand" ""))))
19508               (clobber (reg:CC FLAGS_REG))])]
19509   "TARGET_K8 && !optimize_size
19510    && (GET_CODE (operands[2]) != CONST_INT
19511        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19512   [(set (match_dup 3) (match_dup 1))
19513    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19514               (clobber (reg:CC FLAGS_REG))])]
19515 "")
19516
19517 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19518 ;; Convert it into imul reg, reg
19519 ;; It would be better to force assembler to encode instruction using long
19520 ;; immediate, but there is apparently no way to do so.
19521 (define_peephole2
19522   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19523                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19524                             (match_operand:DI 2 "const_int_operand" "")))
19525               (clobber (reg:CC FLAGS_REG))])
19526    (match_scratch:DI 3 "r")]
19527   "TARGET_K8 && !optimize_size
19528    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19529   [(set (match_dup 3) (match_dup 2))
19530    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19531               (clobber (reg:CC FLAGS_REG))])]
19532 {
19533   if (!rtx_equal_p (operands[0], operands[1]))
19534     emit_move_insn (operands[0], operands[1]);
19535 })
19536
19537 (define_peephole2
19538   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19539                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19540                             (match_operand:SI 2 "const_int_operand" "")))
19541               (clobber (reg:CC FLAGS_REG))])
19542    (match_scratch:SI 3 "r")]
19543   "TARGET_K8 && !optimize_size
19544    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19545   [(set (match_dup 3) (match_dup 2))
19546    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19547               (clobber (reg:CC FLAGS_REG))])]
19548 {
19549   if (!rtx_equal_p (operands[0], operands[1]))
19550     emit_move_insn (operands[0], operands[1]);
19551 })
19552
19553 (define_peephole2
19554   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19555                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19556                             (match_operand:HI 2 "immediate_operand" "")))
19557               (clobber (reg:CC FLAGS_REG))])
19558    (match_scratch:HI 3 "r")]
19559   "TARGET_K8 && !optimize_size"
19560   [(set (match_dup 3) (match_dup 2))
19561    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19562               (clobber (reg:CC FLAGS_REG))])]
19563 {
19564   if (!rtx_equal_p (operands[0], operands[1]))
19565     emit_move_insn (operands[0], operands[1]);
19566 })
19567 \f
19568 ;; Call-value patterns last so that the wildcard operand does not
19569 ;; disrupt insn-recog's switch tables.
19570
19571 (define_insn "*call_value_pop_0"
19572   [(set (match_operand 0 "" "")
19573         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19574               (match_operand:SI 2 "" "")))
19575    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19576                             (match_operand:SI 3 "immediate_operand" "")))]
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_pop_1"
19587   [(set (match_operand 0 "" "")
19588         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19589               (match_operand:SI 2 "" "")))
19590    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19591                             (match_operand:SI 3 "immediate_operand" "i")))]
19592   "!TARGET_64BIT"
19593 {
19594   if (constant_call_address_operand (operands[1], Pmode))
19595     {
19596       if (SIBLING_CALL_P (insn))
19597         return "jmp\t%P1";
19598       else
19599         return "call\t%P1";
19600     }
19601   if (SIBLING_CALL_P (insn))
19602     return "jmp\t%A1";
19603   else
19604     return "call\t%A1";
19605 }
19606   [(set_attr "type" "callv")])
19607
19608 (define_insn "*call_value_0"
19609   [(set (match_operand 0 "" "")
19610         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19611               (match_operand:SI 2 "" "")))]
19612   "!TARGET_64BIT"
19613 {
19614   if (SIBLING_CALL_P (insn))
19615     return "jmp\t%P1";
19616   else
19617     return "call\t%P1";
19618 }
19619   [(set_attr "type" "callv")])
19620
19621 (define_insn "*call_value_0_rex64"
19622   [(set (match_operand 0 "" "")
19623         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19624               (match_operand:DI 2 "const_int_operand" "")))]
19625   "TARGET_64BIT"
19626 {
19627   if (SIBLING_CALL_P (insn))
19628     return "jmp\t%P1";
19629   else
19630     return "call\t%P1";
19631 }
19632   [(set_attr "type" "callv")])
19633
19634 (define_insn "*call_value_1"
19635   [(set (match_operand 0 "" "")
19636         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19637               (match_operand:SI 2 "" "")))]
19638   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19639 {
19640   if (constant_call_address_operand (operands[1], Pmode))
19641     return "call\t%P1";
19642   return "call\t%A1";
19643 }
19644   [(set_attr "type" "callv")])
19645
19646 (define_insn "*sibcall_value_1"
19647   [(set (match_operand 0 "" "")
19648         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19649               (match_operand:SI 2 "" "")))]
19650   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19651 {
19652   if (constant_call_address_operand (operands[1], Pmode))
19653     return "jmp\t%P1";
19654   return "jmp\t%A1";
19655 }
19656   [(set_attr "type" "callv")])
19657
19658 (define_insn "*call_value_1_rex64"
19659   [(set (match_operand 0 "" "")
19660         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19661               (match_operand:DI 2 "" "")))]
19662   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19663 {
19664   if (constant_call_address_operand (operands[1], Pmode))
19665     return "call\t%P1";
19666   return "call\t%A1";
19667 }
19668   [(set_attr "type" "callv")])
19669
19670 (define_insn "*sibcall_value_1_rex64"
19671   [(set (match_operand 0 "" "")
19672         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19673               (match_operand:DI 2 "" "")))]
19674   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19675   "jmp\t%P1"
19676   [(set_attr "type" "callv")])
19677
19678 (define_insn "*sibcall_value_1_rex64_v"
19679   [(set (match_operand 0 "" "")
19680         (call (mem:QI (reg:DI 40))
19681               (match_operand:DI 1 "" "")))]
19682   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19683   "jmp\t*%%r11"
19684   [(set_attr "type" "callv")])
19685 \f
19686 (define_insn "trap"
19687   [(trap_if (const_int 1) (const_int 5))]
19688   ""
19689   "int\t$5")
19690
19691 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19692 ;;; for the sake of bounds checking.  By emitting bounds checks as
19693 ;;; conditional traps rather than as conditional jumps around
19694 ;;; unconditional traps we avoid introducing spurious basic-block
19695 ;;; boundaries and facilitate elimination of redundant checks.  In
19696 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19697 ;;; interrupt 5.
19698 ;;; 
19699 ;;; FIXME: Static branch prediction rules for ix86 are such that
19700 ;;; forward conditional branches predict as untaken.  As implemented
19701 ;;; below, pseudo conditional traps violate that rule.  We should use
19702 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19703 ;;; section loaded at the end of the text segment and branch forward
19704 ;;; there on bounds-failure, and then jump back immediately (in case
19705 ;;; the system chooses to ignore bounds violations, or to report
19706 ;;; violations and continue execution).
19707
19708 (define_expand "conditional_trap"
19709   [(trap_if (match_operator 0 "comparison_operator"
19710              [(match_dup 2) (const_int 0)])
19711             (match_operand 1 "const_int_operand" ""))]
19712   ""
19713 {
19714   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19715                               ix86_expand_compare (GET_CODE (operands[0]),
19716                                                    NULL, NULL),
19717                               operands[1]));
19718   DONE;
19719 })
19720
19721 (define_insn "*conditional_trap_1"
19722   [(trap_if (match_operator 0 "comparison_operator"
19723              [(reg FLAGS_REG) (const_int 0)])
19724             (match_operand 1 "const_int_operand" ""))]
19725   ""
19726 {
19727   operands[2] = gen_label_rtx ();
19728   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19729   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19730                              CODE_LABEL_NUMBER (operands[2]));
19731   RET;
19732 })
19733
19734         ;; Pentium III SIMD instructions.
19735
19736 ;; Moves for SSE/MMX regs.
19737
19738 (define_insn "movv4sf_internal"
19739   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19740         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19741   "TARGET_SSE"
19742   "@
19743     xorps\t%0, %0
19744     movaps\t{%1, %0|%0, %1}
19745     movaps\t{%1, %0|%0, %1}"
19746   [(set_attr "type" "ssemov")
19747    (set_attr "mode" "V4SF")])
19748
19749 (define_split
19750   [(set (match_operand:V4SF 0 "register_operand" "")
19751         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19752   "TARGET_SSE && reload_completed"
19753   [(set (match_dup 0)
19754         (vec_merge:V4SF
19755          (vec_duplicate:V4SF (match_dup 1))
19756          (match_dup 2)
19757          (const_int 1)))]
19758 {
19759   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19760   operands[2] = CONST0_RTX (V4SFmode);
19761 })
19762
19763 (define_insn "movv4si_internal"
19764   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19765         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19766   "TARGET_SSE"
19767 {
19768   switch (which_alternative)
19769     {
19770     case 0:
19771       if (get_attr_mode (insn) == MODE_V4SF)
19772         return "xorps\t%0, %0";
19773       else
19774         return "pxor\t%0, %0";
19775     case 1:
19776     case 2:
19777       if (get_attr_mode (insn) == MODE_V4SF)
19778         return "movaps\t{%1, %0|%0, %1}";
19779       else
19780         return "movdqa\t{%1, %0|%0, %1}";
19781     default:
19782       abort ();
19783     }
19784 }
19785   [(set_attr "type" "ssemov")
19786    (set (attr "mode")
19787         (cond [(eq_attr "alternative" "0,1")
19788                  (if_then_else
19789                    (ne (symbol_ref "optimize_size")
19790                        (const_int 0))
19791                    (const_string "V4SF")
19792                    (const_string "TI"))
19793                (eq_attr "alternative" "2")
19794                  (if_then_else
19795                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19796                             (const_int 0))
19797                         (ne (symbol_ref "optimize_size")
19798                             (const_int 0)))
19799                    (const_string "V4SF")
19800                    (const_string "TI"))]
19801                (const_string "TI")))])
19802
19803 (define_insn "movv2di_internal"
19804   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19805         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19806   "TARGET_SSE"
19807 {
19808   switch (which_alternative)
19809     {
19810     case 0:
19811       if (get_attr_mode (insn) == MODE_V4SF)
19812         return "xorps\t%0, %0";
19813       else
19814         return "pxor\t%0, %0";
19815     case 1:
19816     case 2:
19817       if (get_attr_mode (insn) == MODE_V4SF)
19818         return "movaps\t{%1, %0|%0, %1}";
19819       else
19820         return "movdqa\t{%1, %0|%0, %1}";
19821     default:
19822       abort ();
19823     }
19824 }
19825   [(set_attr "type" "ssemov")
19826    (set (attr "mode")
19827         (cond [(eq_attr "alternative" "0,1")
19828                  (if_then_else
19829                    (ne (symbol_ref "optimize_size")
19830                        (const_int 0))
19831                    (const_string "V4SF")
19832                    (const_string "TI"))
19833                (eq_attr "alternative" "2")
19834                  (if_then_else
19835                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19836                             (const_int 0))
19837                         (ne (symbol_ref "optimize_size")
19838                             (const_int 0)))
19839                    (const_string "V4SF")
19840                    (const_string "TI"))]
19841                (const_string "TI")))])
19842
19843 (define_split
19844   [(set (match_operand:V2DF 0 "register_operand" "")
19845         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19846   "TARGET_SSE2 && reload_completed"
19847   [(set (match_dup 0)
19848         (vec_merge:V2DF
19849          (vec_duplicate:V2DF (match_dup 1))
19850          (match_dup 2)
19851          (const_int 1)))]
19852 {
19853   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19854   operands[2] = CONST0_RTX (V2DFmode);
19855 })
19856
19857 (define_insn "movv8qi_internal"
19858   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19859         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19860   "TARGET_MMX
19861    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19862   "@
19863     pxor\t%0, %0
19864     movq\t{%1, %0|%0, %1}
19865     movq\t{%1, %0|%0, %1}
19866     movdq2q\t{%1, %0|%0, %1}
19867     movq2dq\t{%1, %0|%0, %1}
19868     movq\t{%1, %0|%0, %1}
19869     movq\t{%1, %0|%0, %1}"
19870   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19871    (set_attr "mode" "DI")])
19872
19873 (define_insn "movv4hi_internal"
19874   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19875         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19876   "TARGET_MMX
19877    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19878   "@
19879     pxor\t%0, %0
19880     movq\t{%1, %0|%0, %1}
19881     movq\t{%1, %0|%0, %1}
19882     movdq2q\t{%1, %0|%0, %1}
19883     movq2dq\t{%1, %0|%0, %1}
19884     movq\t{%1, %0|%0, %1}
19885     movq\t{%1, %0|%0, %1}"
19886   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19887    (set_attr "mode" "DI")])
19888
19889 (define_insn "*movv2si_internal"
19890   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19891         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19892   "TARGET_MMX
19893    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19894   "@
19895     pxor\t%0, %0
19896     movq\t{%1, %0|%0, %1}
19897     movq\t{%1, %0|%0, %1}
19898     movdq2q\t{%1, %0|%0, %1}
19899     movq2dq\t{%1, %0|%0, %1}
19900     movq\t{%1, %0|%0, %1}
19901     movq\t{%1, %0|%0, %1}"
19902   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19903    (set_attr "mode" "DI")])
19904
19905 (define_insn "movv2sf_internal"
19906   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19907         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
19908   "TARGET_3DNOW
19909    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19910   "@
19911     pxor\t%0, %0
19912     movq\t{%1, %0|%0, %1}
19913     movq\t{%1, %0|%0, %1}
19914     movdq2q\t{%1, %0|%0, %1}
19915     movq2dq\t{%1, %0|%0, %1}
19916     movlps\t{%1, %0|%0, %1}
19917     movlps\t{%1, %0|%0, %1}"
19918   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19919    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
19920
19921 (define_expand "movti"
19922   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19923         (match_operand:TI 1 "nonimmediate_operand" ""))]
19924   "TARGET_SSE || TARGET_64BIT"
19925 {
19926   if (TARGET_64BIT)
19927     ix86_expand_move (TImode, operands);
19928   else
19929     ix86_expand_vector_move (TImode, operands);
19930   DONE;
19931 })
19932
19933 (define_expand "movtf"
19934   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19935         (match_operand:TF 1 "nonimmediate_operand" ""))]
19936   "TARGET_64BIT"
19937 {
19938   if (TARGET_64BIT)
19939     ix86_expand_move (TFmode, operands);
19940   else
19941     ix86_expand_vector_move (TFmode, operands);
19942   DONE;
19943 })
19944
19945 (define_insn "movv2df_internal"
19946   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19947         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19948   "TARGET_SSE2
19949    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19950 {
19951   switch (which_alternative)
19952     {
19953     case 0:
19954       if (get_attr_mode (insn) == MODE_V4SF)
19955         return "xorps\t%0, %0";
19956       else
19957         return "xorpd\t%0, %0";
19958     case 1:
19959     case 2:
19960       if (get_attr_mode (insn) == MODE_V4SF)
19961         return "movaps\t{%1, %0|%0, %1}";
19962       else
19963         return "movapd\t{%1, %0|%0, %1}";
19964     default:
19965       abort ();
19966     }
19967 }
19968   [(set_attr "type" "ssemov")
19969    (set (attr "mode")
19970         (cond [(eq_attr "alternative" "0,1")
19971                  (if_then_else
19972                    (ne (symbol_ref "optimize_size")
19973                        (const_int 0))
19974                    (const_string "V4SF")
19975                    (const_string "V2DF"))
19976                (eq_attr "alternative" "2")
19977                  (if_then_else
19978                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19979                             (const_int 0))
19980                         (ne (symbol_ref "optimize_size")
19981                             (const_int 0)))
19982                    (const_string "V4SF")
19983                    (const_string "V2DF"))]
19984                (const_string "V2DF")))])
19985
19986 (define_insn "movv8hi_internal"
19987   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19988         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19989   "TARGET_SSE2
19990    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19991 {
19992   switch (which_alternative)
19993     {
19994     case 0:
19995       if (get_attr_mode (insn) == MODE_V4SF)
19996         return "xorps\t%0, %0";
19997       else
19998         return "pxor\t%0, %0";
19999     case 1:
20000     case 2:
20001       if (get_attr_mode (insn) == MODE_V4SF)
20002         return "movaps\t{%1, %0|%0, %1}";
20003       else
20004         return "movdqa\t{%1, %0|%0, %1}";
20005     default:
20006       abort ();
20007     }
20008 }
20009   [(set_attr "type" "ssemov")
20010    (set (attr "mode")
20011         (cond [(eq_attr "alternative" "0,1")
20012                  (if_then_else
20013                    (ne (symbol_ref "optimize_size")
20014                        (const_int 0))
20015                    (const_string "V4SF")
20016                    (const_string "TI"))
20017                (eq_attr "alternative" "2")
20018                  (if_then_else
20019                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20020                             (const_int 0))
20021                         (ne (symbol_ref "optimize_size")
20022                             (const_int 0)))
20023                    (const_string "V4SF")
20024                    (const_string "TI"))]
20025                (const_string "TI")))])
20026
20027 (define_insn "movv16qi_internal"
20028   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20029         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20030   "TARGET_SSE2
20031    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20032 {
20033   switch (which_alternative)
20034     {
20035     case 0:
20036       if (get_attr_mode (insn) == MODE_V4SF)
20037         return "xorps\t%0, %0";
20038       else
20039         return "pxor\t%0, %0";
20040     case 1:
20041     case 2:
20042       if (get_attr_mode (insn) == MODE_V4SF)
20043         return "movaps\t{%1, %0|%0, %1}";
20044       else
20045         return "movdqa\t{%1, %0|%0, %1}";
20046     default:
20047       abort ();
20048     }
20049 }
20050   [(set_attr "type" "ssemov")
20051    (set (attr "mode")
20052         (cond [(eq_attr "alternative" "0,1")
20053                  (if_then_else
20054                    (ne (symbol_ref "optimize_size")
20055                        (const_int 0))
20056                    (const_string "V4SF")
20057                    (const_string "TI"))
20058                (eq_attr "alternative" "2")
20059                  (if_then_else
20060                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20061                             (const_int 0))
20062                         (ne (symbol_ref "optimize_size")
20063                             (const_int 0)))
20064                    (const_string "V4SF")
20065                    (const_string "TI"))]
20066                (const_string "TI")))])
20067
20068 (define_expand "movv2df"
20069   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20070         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20071   "TARGET_SSE2"
20072 {
20073   ix86_expand_vector_move (V2DFmode, operands);
20074   DONE;
20075 })
20076
20077 (define_expand "movv8hi"
20078   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20079         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20080   "TARGET_SSE2"
20081 {
20082   ix86_expand_vector_move (V8HImode, operands);
20083   DONE;
20084 })
20085
20086 (define_expand "movv16qi"
20087   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20088         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20089   "TARGET_SSE2"
20090 {
20091   ix86_expand_vector_move (V16QImode, operands);
20092   DONE;
20093 })
20094
20095 (define_expand "movv4sf"
20096   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20097         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20098   "TARGET_SSE"
20099 {
20100   ix86_expand_vector_move (V4SFmode, operands);
20101   DONE;
20102 })
20103
20104 (define_expand "movv4si"
20105   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20106         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20107   "TARGET_SSE"
20108 {
20109   ix86_expand_vector_move (V4SImode, operands);
20110   DONE;
20111 })
20112
20113 (define_expand "movv2di"
20114   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20115         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20116   "TARGET_SSE"
20117 {
20118   ix86_expand_vector_move (V2DImode, operands);
20119   DONE;
20120 })
20121
20122 (define_expand "movv2si"
20123   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20124         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20125   "TARGET_MMX"
20126 {
20127   ix86_expand_vector_move (V2SImode, operands);
20128   DONE;
20129 })
20130
20131 (define_expand "movv4hi"
20132   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20133         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20134   "TARGET_MMX"
20135 {
20136   ix86_expand_vector_move (V4HImode, operands);
20137   DONE;
20138 })
20139
20140 (define_expand "movv8qi"
20141   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20142         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20143   "TARGET_MMX"
20144 {
20145   ix86_expand_vector_move (V8QImode, operands);
20146   DONE;
20147 })
20148
20149 (define_expand "movv2sf"
20150   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20151         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20152    "TARGET_3DNOW"
20153 {
20154   ix86_expand_vector_move (V2SFmode, operands);
20155   DONE;
20156 })
20157
20158 (define_insn "*pushti"
20159   [(set (match_operand:TI 0 "push_operand" "=<")
20160         (match_operand:TI 1 "register_operand" "x"))]
20161   "TARGET_SSE"
20162   "#")
20163
20164 (define_insn "*pushv2df"
20165   [(set (match_operand:V2DF 0 "push_operand" "=<")
20166         (match_operand:V2DF 1 "register_operand" "x"))]
20167   "TARGET_SSE"
20168   "#")
20169
20170 (define_insn "*pushv2di"
20171   [(set (match_operand:V2DI 0 "push_operand" "=<")
20172         (match_operand:V2DI 1 "register_operand" "x"))]
20173   "TARGET_SSE2"
20174   "#")
20175
20176 (define_insn "*pushv8hi"
20177   [(set (match_operand:V8HI 0 "push_operand" "=<")
20178         (match_operand:V8HI 1 "register_operand" "x"))]
20179   "TARGET_SSE2"
20180   "#")
20181
20182 (define_insn "*pushv16qi"
20183   [(set (match_operand:V16QI 0 "push_operand" "=<")
20184         (match_operand:V16QI 1 "register_operand" "x"))]
20185   "TARGET_SSE2"
20186   "#")
20187
20188 (define_insn "*pushv4sf"
20189   [(set (match_operand:V4SF 0 "push_operand" "=<")
20190         (match_operand:V4SF 1 "register_operand" "x"))]
20191   "TARGET_SSE"
20192   "#")
20193
20194 (define_insn "*pushv4si"
20195   [(set (match_operand:V4SI 0 "push_operand" "=<")
20196         (match_operand:V4SI 1 "register_operand" "x"))]
20197   "TARGET_SSE2"
20198   "#")
20199
20200 (define_insn "*pushv2si"
20201   [(set (match_operand:V2SI 0 "push_operand" "=<")
20202         (match_operand:V2SI 1 "register_operand" "y"))]
20203   "TARGET_MMX"
20204   "#")
20205
20206 (define_insn "*pushv4hi"
20207   [(set (match_operand:V4HI 0 "push_operand" "=<")
20208         (match_operand:V4HI 1 "register_operand" "y"))]
20209   "TARGET_MMX"
20210   "#")
20211
20212 (define_insn "*pushv8qi"
20213   [(set (match_operand:V8QI 0 "push_operand" "=<")
20214         (match_operand:V8QI 1 "register_operand" "y"))]
20215   "TARGET_MMX"
20216   "#")
20217
20218 (define_insn "*pushv2sf"
20219   [(set (match_operand:V2SF 0 "push_operand" "=<")
20220         (match_operand:V2SF 1 "register_operand" "y"))]
20221   "TARGET_3DNOW"
20222   "#")
20223
20224 (define_split
20225   [(set (match_operand 0 "push_operand" "")
20226         (match_operand 1 "register_operand" ""))]
20227   "!TARGET_64BIT && reload_completed
20228    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20229   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20230    (set (match_dup 2) (match_dup 1))]
20231   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20232                                  stack_pointer_rtx);
20233    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20234
20235 (define_split
20236   [(set (match_operand 0 "push_operand" "")
20237         (match_operand 1 "register_operand" ""))]
20238   "TARGET_64BIT && reload_completed
20239    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20240   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20241    (set (match_dup 2) (match_dup 1))]
20242   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20243                                  stack_pointer_rtx);
20244    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20245
20246
20247 (define_insn "movti_internal"
20248   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20249         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20250   "TARGET_SSE && !TARGET_64BIT
20251    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20252 {
20253   switch (which_alternative)
20254     {
20255     case 0:
20256       if (get_attr_mode (insn) == MODE_V4SF)
20257         return "xorps\t%0, %0";
20258       else
20259         return "pxor\t%0, %0";
20260     case 1:
20261     case 2:
20262       if (get_attr_mode (insn) == MODE_V4SF)
20263         return "movaps\t{%1, %0|%0, %1}";
20264       else
20265         return "movdqa\t{%1, %0|%0, %1}";
20266     default:
20267       abort ();
20268     }
20269 }
20270   [(set_attr "type" "ssemov,ssemov,ssemov")
20271    (set (attr "mode")
20272         (cond [(eq_attr "alternative" "0,1")
20273                  (if_then_else
20274                    (ne (symbol_ref "optimize_size")
20275                        (const_int 0))
20276                    (const_string "V4SF")
20277                    (const_string "TI"))
20278                (eq_attr "alternative" "2")
20279                  (if_then_else
20280                    (ne (symbol_ref "optimize_size")
20281                        (const_int 0))
20282                    (const_string "V4SF")
20283                    (const_string "TI"))]
20284                (const_string "TI")))])
20285
20286 (define_insn "*movti_rex64"
20287   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20288         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20289   "TARGET_64BIT
20290    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20291 {
20292   switch (which_alternative)
20293     {
20294     case 0:
20295     case 1:
20296       return "#";
20297     case 2:
20298       if (get_attr_mode (insn) == MODE_V4SF)
20299         return "xorps\t%0, %0";
20300       else
20301         return "pxor\t%0, %0";
20302     case 3:
20303     case 4:
20304       if (get_attr_mode (insn) == MODE_V4SF)
20305         return "movaps\t{%1, %0|%0, %1}";
20306       else
20307         return "movdqa\t{%1, %0|%0, %1}";
20308     default:
20309       abort ();
20310     }
20311 }
20312   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20313    (set (attr "mode")
20314         (cond [(eq_attr "alternative" "2,3")
20315                  (if_then_else
20316                    (ne (symbol_ref "optimize_size")
20317                        (const_int 0))
20318                    (const_string "V4SF")
20319                    (const_string "TI"))
20320                (eq_attr "alternative" "4")
20321                  (if_then_else
20322                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20323                             (const_int 0))
20324                         (ne (symbol_ref "optimize_size")
20325                             (const_int 0)))
20326                    (const_string "V4SF")
20327                    (const_string "TI"))]
20328                (const_string "DI")))])
20329
20330 (define_insn "*movtf_rex64"
20331   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20332         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20333   "TARGET_64BIT
20334    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20335 {
20336   switch (which_alternative)
20337     {
20338     case 0:
20339     case 1:
20340       return "#";
20341     case 2:
20342       if (get_attr_mode (insn) == MODE_V4SF)
20343         return "xorps\t%0, %0";
20344       else
20345         return "pxor\t%0, %0";
20346     case 3:
20347     case 4:
20348       if (get_attr_mode (insn) == MODE_V4SF)
20349         return "movaps\t{%1, %0|%0, %1}";
20350       else
20351         return "movdqa\t{%1, %0|%0, %1}";
20352     default:
20353       abort ();
20354     }
20355 }
20356   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20357    (set (attr "mode")
20358         (cond [(eq_attr "alternative" "2,3")
20359                  (if_then_else
20360                    (ne (symbol_ref "optimize_size")
20361                        (const_int 0))
20362                    (const_string "V4SF")
20363                    (const_string "TI"))
20364                (eq_attr "alternative" "4")
20365                  (if_then_else
20366                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20367                             (const_int 0))
20368                         (ne (symbol_ref "optimize_size")
20369                             (const_int 0)))
20370                    (const_string "V4SF")
20371                    (const_string "TI"))]
20372                (const_string "DI")))])
20373
20374 (define_split
20375   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20376         (match_operand:TI 1 "general_operand" ""))]
20377   "reload_completed && !SSE_REG_P (operands[0])
20378    && !SSE_REG_P (operands[1])"
20379   [(const_int 0)]
20380   "ix86_split_long_move (operands); DONE;")
20381
20382 (define_split
20383   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20384         (match_operand:TF 1 "general_operand" ""))]
20385   "reload_completed && !SSE_REG_P (operands[0])
20386    && !SSE_REG_P (operands[1])"
20387   [(const_int 0)]
20388   "ix86_split_long_move (operands); DONE;")
20389
20390 ;; These two patterns are useful for specifying exactly whether to use
20391 ;; movaps or movups
20392 (define_expand "sse_movaps"
20393   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20394         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20395                      UNSPEC_MOVA))]
20396   "TARGET_SSE"
20397 {
20398   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20399     {
20400       rtx tmp = gen_reg_rtx (V4SFmode);
20401       emit_insn (gen_sse_movaps (tmp, operands[1]));
20402       emit_move_insn (operands[0], tmp);
20403       DONE;
20404     }
20405 })
20406
20407 (define_insn "*sse_movaps_1"
20408   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20409         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20410                      UNSPEC_MOVA))]
20411   "TARGET_SSE
20412    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20413   "movaps\t{%1, %0|%0, %1}"
20414   [(set_attr "type" "ssemov,ssemov")
20415    (set_attr "mode" "V4SF")])
20416
20417 (define_expand "sse_movups"
20418   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20419         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20420                      UNSPEC_MOVU))]
20421   "TARGET_SSE"
20422 {
20423   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20424     {
20425       rtx tmp = gen_reg_rtx (V4SFmode);
20426       emit_insn (gen_sse_movups (tmp, operands[1]));
20427       emit_move_insn (operands[0], tmp);
20428       DONE;
20429     }
20430 })
20431
20432 (define_insn "*sse_movups_1"
20433   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20434         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20435                      UNSPEC_MOVU))]
20436   "TARGET_SSE
20437    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20438   "movups\t{%1, %0|%0, %1}"
20439   [(set_attr "type" "ssecvt,ssecvt")
20440    (set_attr "mode" "V4SF")])
20441
20442 ;; SSE Strange Moves.
20443
20444 (define_insn "sse_movmskps"
20445   [(set (match_operand:SI 0 "register_operand" "=r")
20446         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20447                    UNSPEC_MOVMSK))]
20448   "TARGET_SSE"
20449   "movmskps\t{%1, %0|%0, %1}"
20450   [(set_attr "type" "ssecvt")
20451    (set_attr "mode" "V4SF")])
20452
20453 (define_insn "mmx_pmovmskb"
20454   [(set (match_operand:SI 0 "register_operand" "=r")
20455         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20456                    UNSPEC_MOVMSK))]
20457   "TARGET_SSE || TARGET_3DNOW_A"
20458   "pmovmskb\t{%1, %0|%0, %1}"
20459   [(set_attr "type" "ssecvt")
20460    (set_attr "mode" "V4SF")])
20461
20462
20463 (define_insn "mmx_maskmovq"
20464   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20465         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20466                       (match_operand:V8QI 2 "register_operand" "y")]
20467                      UNSPEC_MASKMOV))]
20468   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20469   ;; @@@ check ordering of operands in intel/nonintel syntax
20470   "maskmovq\t{%2, %1|%1, %2}"
20471   [(set_attr "type" "mmxcvt")
20472    (set_attr "mode" "DI")])
20473
20474 (define_insn "mmx_maskmovq_rex"
20475   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20476         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20477                       (match_operand:V8QI 2 "register_operand" "y")]
20478                      UNSPEC_MASKMOV))]
20479   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20480   ;; @@@ check ordering of operands in intel/nonintel syntax
20481   "maskmovq\t{%2, %1|%1, %2}"
20482   [(set_attr "type" "mmxcvt")
20483    (set_attr "mode" "DI")])
20484
20485 (define_insn "sse_movntv4sf"
20486   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20487         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20488                      UNSPEC_MOVNT))]
20489   "TARGET_SSE"
20490   "movntps\t{%1, %0|%0, %1}"
20491   [(set_attr "type" "ssemov")
20492    (set_attr "mode" "V4SF")])
20493
20494 (define_insn "sse_movntdi"
20495   [(set (match_operand:DI 0 "memory_operand" "=m")
20496         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20497                    UNSPEC_MOVNT))]
20498   "TARGET_SSE || TARGET_3DNOW_A"
20499   "movntq\t{%1, %0|%0, %1}"
20500   [(set_attr "type" "mmxmov")
20501    (set_attr "mode" "DI")])
20502
20503 (define_insn "sse_movhlps"
20504   [(set (match_operand:V4SF 0 "register_operand" "=x")
20505         (vec_merge:V4SF
20506          (match_operand:V4SF 1 "register_operand" "0")
20507          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20508                           (parallel [(const_int 2)
20509                                      (const_int 3)
20510                                      (const_int 0)
20511                                      (const_int 1)]))
20512          (const_int 3)))]
20513   "TARGET_SSE"
20514   "movhlps\t{%2, %0|%0, %2}"
20515   [(set_attr "type" "ssecvt")
20516    (set_attr "mode" "V4SF")])
20517
20518 (define_insn "sse_movlhps"
20519   [(set (match_operand:V4SF 0 "register_operand" "=x")
20520         (vec_merge:V4SF
20521          (match_operand:V4SF 1 "register_operand" "0")
20522          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20523                           (parallel [(const_int 2)
20524                                      (const_int 3)
20525                                      (const_int 0)
20526                                      (const_int 1)]))
20527          (const_int 12)))]
20528   "TARGET_SSE"
20529   "movlhps\t{%2, %0|%0, %2}"
20530   [(set_attr "type" "ssecvt")
20531    (set_attr "mode" "V4SF")])
20532
20533 (define_insn "sse_movhps"
20534   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20535         (vec_merge:V4SF
20536          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20537          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20538          (const_int 12)))]
20539   "TARGET_SSE
20540    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20541   "movhps\t{%2, %0|%0, %2}"
20542   [(set_attr "type" "ssecvt")
20543    (set_attr "mode" "V4SF")])
20544
20545 (define_insn "sse_movlps"
20546   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20547         (vec_merge:V4SF
20548          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20549          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20550          (const_int 3)))]
20551   "TARGET_SSE
20552    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20553   "movlps\t{%2, %0|%0, %2}"
20554   [(set_attr "type" "ssecvt")
20555    (set_attr "mode" "V4SF")])
20556
20557 (define_expand "sse_loadss"
20558   [(match_operand:V4SF 0 "register_operand" "")
20559    (match_operand:SF 1 "memory_operand" "")]
20560   "TARGET_SSE"
20561 {
20562   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20563                                CONST0_RTX (V4SFmode)));
20564   DONE;
20565 })
20566
20567 (define_insn "sse_loadss_1"
20568   [(set (match_operand:V4SF 0 "register_operand" "=x")
20569         (vec_merge:V4SF
20570          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20571          (match_operand:V4SF 2 "const0_operand" "X")
20572          (const_int 1)))]
20573   "TARGET_SSE"
20574   "movss\t{%1, %0|%0, %1}"
20575   [(set_attr "type" "ssemov")
20576    (set_attr "mode" "SF")])
20577
20578 (define_insn "sse_movss"
20579   [(set (match_operand:V4SF 0 "register_operand" "=x")
20580         (vec_merge:V4SF
20581          (match_operand:V4SF 1 "register_operand" "0")
20582          (match_operand:V4SF 2 "register_operand" "x")
20583          (const_int 14)))]
20584   "TARGET_SSE"
20585   "movss\t{%2, %0|%0, %2}"
20586   [(set_attr "type" "ssemov")
20587    (set_attr "mode" "SF")])
20588
20589 (define_insn "sse_storess"
20590   [(set (match_operand:SF 0 "memory_operand" "=m")
20591         (vec_select:SF
20592          (match_operand:V4SF 1 "register_operand" "x")
20593          (parallel [(const_int 0)])))]
20594   "TARGET_SSE"
20595   "movss\t{%1, %0|%0, %1}"
20596   [(set_attr "type" "ssemov")
20597    (set_attr "mode" "SF")])
20598
20599 (define_insn "sse_shufps"
20600   [(set (match_operand:V4SF 0 "register_operand" "=x")
20601         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20602                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20603                       (match_operand:SI 3 "immediate_operand" "i")]
20604                      UNSPEC_SHUFFLE))]
20605   "TARGET_SSE"
20606   ;; @@@ check operand order for intel/nonintel syntax
20607   "shufps\t{%3, %2, %0|%0, %2, %3}"
20608   [(set_attr "type" "ssecvt")
20609    (set_attr "mode" "V4SF")])
20610
20611
20612 ;; SSE arithmetic
20613
20614 (define_insn "addv4sf3"
20615   [(set (match_operand:V4SF 0 "register_operand" "=x")
20616         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20617                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20618   "TARGET_SSE"
20619   "addps\t{%2, %0|%0, %2}"
20620   [(set_attr "type" "sseadd")
20621    (set_attr "mode" "V4SF")])
20622
20623 (define_insn "vmaddv4sf3"
20624   [(set (match_operand:V4SF 0 "register_operand" "=x")
20625         (vec_merge:V4SF
20626          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20627                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20628          (match_dup 1)
20629          (const_int 1)))]
20630   "TARGET_SSE"
20631   "addss\t{%2, %0|%0, %2}"
20632   [(set_attr "type" "sseadd")
20633    (set_attr "mode" "SF")])
20634
20635 (define_insn "subv4sf3"
20636   [(set (match_operand:V4SF 0 "register_operand" "=x")
20637         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20638                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20639   "TARGET_SSE"
20640   "subps\t{%2, %0|%0, %2}"
20641   [(set_attr "type" "sseadd")
20642    (set_attr "mode" "V4SF")])
20643
20644 (define_insn "vmsubv4sf3"
20645   [(set (match_operand:V4SF 0 "register_operand" "=x")
20646         (vec_merge:V4SF
20647          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20648                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20649          (match_dup 1)
20650          (const_int 1)))]
20651   "TARGET_SSE"
20652   "subss\t{%2, %0|%0, %2}"
20653   [(set_attr "type" "sseadd")
20654    (set_attr "mode" "SF")])
20655
20656 ;; ??? Should probably be done by generic code instead.
20657 (define_expand "negv4sf2"
20658   [(set (match_operand:V4SF 0 "register_operand" "")
20659         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20660                   (match_dup 2)))]
20661   "TARGET_SSE"
20662 {
20663   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20664   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20665   operands[2] = force_reg (V4SFmode, vm0);
20666 })
20667
20668 (define_insn "mulv4sf3"
20669   [(set (match_operand:V4SF 0 "register_operand" "=x")
20670         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20671                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20672   "TARGET_SSE"
20673   "mulps\t{%2, %0|%0, %2}"
20674   [(set_attr "type" "ssemul")
20675    (set_attr "mode" "V4SF")])
20676
20677 (define_insn "vmmulv4sf3"
20678   [(set (match_operand:V4SF 0 "register_operand" "=x")
20679         (vec_merge:V4SF
20680          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20681                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20682          (match_dup 1)
20683          (const_int 1)))]
20684   "TARGET_SSE"
20685   "mulss\t{%2, %0|%0, %2}"
20686   [(set_attr "type" "ssemul")
20687    (set_attr "mode" "SF")])
20688
20689 (define_insn "divv4sf3"
20690   [(set (match_operand:V4SF 0 "register_operand" "=x")
20691         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20692                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20693   "TARGET_SSE"
20694   "divps\t{%2, %0|%0, %2}"
20695   [(set_attr "type" "ssediv")
20696    (set_attr "mode" "V4SF")])
20697
20698 (define_insn "vmdivv4sf3"
20699   [(set (match_operand:V4SF 0 "register_operand" "=x")
20700         (vec_merge:V4SF
20701          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20702                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20703          (match_dup 1)
20704          (const_int 1)))]
20705   "TARGET_SSE"
20706   "divss\t{%2, %0|%0, %2}"
20707   [(set_attr "type" "ssediv")
20708    (set_attr "mode" "SF")])
20709
20710
20711 ;; SSE square root/reciprocal
20712
20713 (define_insn "rcpv4sf2"
20714   [(set (match_operand:V4SF 0 "register_operand" "=x")
20715         (unspec:V4SF
20716          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20717   "TARGET_SSE"
20718   "rcpps\t{%1, %0|%0, %1}"
20719   [(set_attr "type" "sse")
20720    (set_attr "mode" "V4SF")])
20721
20722 (define_insn "vmrcpv4sf2"
20723   [(set (match_operand:V4SF 0 "register_operand" "=x")
20724         (vec_merge:V4SF
20725          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20726                       UNSPEC_RCP)
20727          (match_operand:V4SF 2 "register_operand" "0")
20728          (const_int 1)))]
20729   "TARGET_SSE"
20730   "rcpss\t{%1, %0|%0, %1}"
20731   [(set_attr "type" "sse")
20732    (set_attr "mode" "SF")])
20733
20734 (define_insn "rsqrtv4sf2"
20735   [(set (match_operand:V4SF 0 "register_operand" "=x")
20736         (unspec:V4SF
20737          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20738   "TARGET_SSE"
20739   "rsqrtps\t{%1, %0|%0, %1}"
20740   [(set_attr "type" "sse")
20741    (set_attr "mode" "V4SF")])
20742
20743 (define_insn "vmrsqrtv4sf2"
20744   [(set (match_operand:V4SF 0 "register_operand" "=x")
20745         (vec_merge:V4SF
20746          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20747                       UNSPEC_RSQRT)
20748          (match_operand:V4SF 2 "register_operand" "0")
20749          (const_int 1)))]
20750   "TARGET_SSE"
20751   "rsqrtss\t{%1, %0|%0, %1}"
20752   [(set_attr "type" "sse")
20753    (set_attr "mode" "SF")])
20754
20755 (define_insn "sqrtv4sf2"
20756   [(set (match_operand:V4SF 0 "register_operand" "=x")
20757         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20758   "TARGET_SSE"
20759   "sqrtps\t{%1, %0|%0, %1}"
20760   [(set_attr "type" "sse")
20761    (set_attr "mode" "V4SF")])
20762
20763 (define_insn "vmsqrtv4sf2"
20764   [(set (match_operand:V4SF 0 "register_operand" "=x")
20765         (vec_merge:V4SF
20766          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20767          (match_operand:V4SF 2 "register_operand" "0")
20768          (const_int 1)))]
20769   "TARGET_SSE"
20770   "sqrtss\t{%1, %0|%0, %1}"
20771   [(set_attr "type" "sse")
20772    (set_attr "mode" "SF")])
20773
20774 ;; SSE logical operations.
20775
20776 ;; SSE defines logical operations on floating point values.  This brings
20777 ;; interesting challenge to RTL representation where logicals are only valid
20778 ;; on integral types.  We deal with this by representing the floating point
20779 ;; logical as logical on arguments casted to TImode as this is what hardware
20780 ;; really does.  Unfortunately hardware requires the type information to be
20781 ;; present and thus we must avoid subregs from being simplified and eliminated
20782 ;; in later compilation phases.
20783 ;;
20784 ;; We have following variants from each instruction:
20785 ;; sse_andsf3 - the operation taking V4SF vector operands
20786 ;;              and doing TImode cast on them
20787 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20788 ;;                      TImode, since backend insist on eliminating casts
20789 ;;                      on memory operands
20790 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20791 ;;                   We cannot accept memory operand here as instruction reads
20792 ;;                   whole scalar.  This is generated only post reload by GCC
20793 ;;                   scalar float operations that expands to logicals (fabs)
20794 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20795 ;;                   memory operand.  Eventually combine can be able
20796 ;;                   to synthesize these using splitter.
20797 ;; sse2_anddf3, *sse2_anddf3_memory
20798 ;;              
20799 ;; 
20800 ;; These are not called andti3 etc. because we really really don't want
20801 ;; the compiler to widen DImode ands to TImode ands and then try to move
20802 ;; into DImode subregs of SSE registers, and them together, and move out
20803 ;; of DImode subregs again!
20804 ;; SSE1 single precision floating point logical operation
20805 (define_expand "sse_andv4sf3"
20806   [(set (match_operand:V4SF 0 "register_operand" "")
20807         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20808                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20809   "TARGET_SSE"
20810   "")
20811
20812 (define_insn "*sse_andv4sf3"
20813   [(set (match_operand:V4SF 0 "register_operand" "=x")
20814         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20815                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20816   "TARGET_SSE
20817    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20818   "andps\t{%2, %0|%0, %2}"
20819   [(set_attr "type" "sselog")
20820    (set_attr "mode" "V4SF")])
20821
20822 (define_expand "sse_nandv4sf3"
20823   [(set (match_operand:V4SF 0 "register_operand" "")
20824         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20825                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20826   "TARGET_SSE"
20827   "")
20828
20829 (define_insn "*sse_nandv4sf3"
20830   [(set (match_operand:V4SF 0 "register_operand" "=x")
20831         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20832                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20833   "TARGET_SSE"
20834   "andnps\t{%2, %0|%0, %2}"
20835   [(set_attr "type" "sselog")
20836    (set_attr "mode" "V4SF")])
20837
20838 (define_expand "sse_iorv4sf3"
20839   [(set (match_operand:V4SF 0 "register_operand" "")
20840         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20841                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20842   "TARGET_SSE"
20843   "")
20844
20845 (define_insn "*sse_iorv4sf3"
20846   [(set (match_operand:V4SF 0 "register_operand" "=x")
20847         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20848                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20849   "TARGET_SSE
20850    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20851   "orps\t{%2, %0|%0, %2}"
20852   [(set_attr "type" "sselog")
20853    (set_attr "mode" "V4SF")])
20854
20855 (define_expand "sse_xorv4sf3"
20856   [(set (match_operand:V4SF 0 "register_operand" "")
20857         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20858                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20859   "TARGET_SSE"
20860   "")
20861
20862 (define_insn "*sse_xorv4sf3"
20863   [(set (match_operand:V4SF 0 "register_operand" "=x")
20864         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20865                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20866   "TARGET_SSE
20867    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20868   "xorps\t{%2, %0|%0, %2}"
20869   [(set_attr "type" "sselog")
20870    (set_attr "mode" "V4SF")])
20871
20872 ;; SSE2 double precision floating point logical operation
20873
20874 (define_expand "sse2_andv2df3"
20875   [(set (match_operand:V2DF 0 "register_operand" "")
20876         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20877                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20878   "TARGET_SSE2"
20879   "")
20880
20881 (define_insn "*sse2_andv2df3"
20882   [(set (match_operand:V2DF 0 "register_operand" "=x")
20883         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20884                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20885   "TARGET_SSE2
20886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20887   "andpd\t{%2, %0|%0, %2}"
20888   [(set_attr "type" "sselog")
20889    (set_attr "mode" "V2DF")])
20890
20891 (define_expand "sse2_nandv2df3"
20892   [(set (match_operand:V2DF 0 "register_operand" "")
20893         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20894                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20895   "TARGET_SSE2"
20896   "")
20897
20898 (define_insn "*sse2_nandv2df3"
20899   [(set (match_operand:V2DF 0 "register_operand" "=x")
20900         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20901                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20902   "TARGET_SSE2"
20903   "andnpd\t{%2, %0|%0, %2}"
20904   [(set_attr "type" "sselog")
20905    (set_attr "mode" "V2DF")])
20906
20907 (define_expand "sse2_iorv2df3"
20908   [(set (match_operand:V2DF 0 "register_operand" "")
20909         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20910                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20911   "TARGET_SSE2"
20912   "")
20913
20914 (define_insn "*sse2_iorv2df3"
20915   [(set (match_operand:V2DF 0 "register_operand" "=x")
20916         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20917                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20918   "TARGET_SSE2
20919    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20920   "orpd\t{%2, %0|%0, %2}"
20921   [(set_attr "type" "sselog")
20922    (set_attr "mode" "V2DF")])
20923
20924 (define_expand "sse2_xorv2df3"
20925   [(set (match_operand:V2DF 0 "register_operand" "")
20926         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20927                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20928   "TARGET_SSE2"
20929   "")
20930
20931 (define_insn "*sse2_xorv2df3"
20932   [(set (match_operand:V2DF 0 "register_operand" "=x")
20933         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20934                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20935   "TARGET_SSE2
20936    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20937   "xorpd\t{%2, %0|%0, %2}"
20938   [(set_attr "type" "sselog")
20939    (set_attr "mode" "V2DF")])
20940
20941 ;; SSE2 integral logicals.  These patterns must always come after floating
20942 ;; point ones since we don't want compiler to use integer opcodes on floating
20943 ;; point SSE values to avoid matching of subregs in the match_operand.
20944 (define_insn "*sse2_andti3"
20945   [(set (match_operand:TI 0 "register_operand" "=x")
20946         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20947                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20948   "TARGET_SSE2
20949    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20950   "pand\t{%2, %0|%0, %2}"
20951   [(set_attr "type" "sselog")
20952    (set_attr "mode" "TI")])
20953
20954 (define_insn "sse2_andv2di3"
20955   [(set (match_operand:V2DI 0 "register_operand" "=x")
20956         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20957                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20958   "TARGET_SSE2
20959    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20960   "pand\t{%2, %0|%0, %2}"
20961   [(set_attr "type" "sselog")
20962    (set_attr "mode" "TI")])
20963
20964 (define_insn "*sse2_nandti3"
20965   [(set (match_operand:TI 0 "register_operand" "=x")
20966         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20967                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20968   "TARGET_SSE2"
20969   "pandn\t{%2, %0|%0, %2}"
20970   [(set_attr "type" "sselog")
20971    (set_attr "mode" "TI")])
20972
20973 (define_insn "sse2_nandv2di3"
20974   [(set (match_operand:V2DI 0 "register_operand" "=x")
20975         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20976                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20977   "TARGET_SSE2
20978    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20979   "pandn\t{%2, %0|%0, %2}"
20980   [(set_attr "type" "sselog")
20981    (set_attr "mode" "TI")])
20982
20983 (define_insn "*sse2_iorti3"
20984   [(set (match_operand:TI 0 "register_operand" "=x")
20985         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20986                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20987   "TARGET_SSE2
20988    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20989   "por\t{%2, %0|%0, %2}"
20990   [(set_attr "type" "sselog")
20991    (set_attr "mode" "TI")])
20992
20993 (define_insn "sse2_iorv2di3"
20994   [(set (match_operand:V2DI 0 "register_operand" "=x")
20995         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20996                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20997   "TARGET_SSE2
20998    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20999   "por\t{%2, %0|%0, %2}"
21000   [(set_attr "type" "sselog")
21001    (set_attr "mode" "TI")])
21002
21003 (define_insn "*sse2_xorti3"
21004   [(set (match_operand:TI 0 "register_operand" "=x")
21005         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21006                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21007   "TARGET_SSE2
21008    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21009   "pxor\t{%2, %0|%0, %2}"
21010   [(set_attr "type" "sselog")
21011    (set_attr "mode" "TI")])
21012
21013 (define_insn "sse2_xorv2di3"
21014   [(set (match_operand:V2DI 0 "register_operand" "=x")
21015         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21016                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21017   "TARGET_SSE2
21018    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21019   "pxor\t{%2, %0|%0, %2}"
21020   [(set_attr "type" "sselog")
21021    (set_attr "mode" "TI")])
21022
21023 ;; Use xor, but don't show input operands so they aren't live before
21024 ;; this insn.
21025 (define_insn "sse_clrv4sf"
21026   [(set (match_operand:V4SF 0 "register_operand" "=x")
21027         (match_operand:V4SF 1 "const0_operand" "X"))]
21028   "TARGET_SSE"
21029 {
21030   if (get_attr_mode (insn) == MODE_TI)
21031     return "pxor\t{%0, %0|%0, %0}";
21032   else
21033     return "xorps\t{%0, %0|%0, %0}";
21034 }
21035   [(set_attr "type" "sselog")
21036    (set_attr "memory" "none")
21037    (set (attr "mode")
21038         (if_then_else
21039            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21040                          (const_int 0))
21041                      (ne (symbol_ref "TARGET_SSE2")
21042                          (const_int 0)))
21043                 (eq (symbol_ref "optimize_size")
21044                     (const_int 0)))
21045          (const_string "TI")
21046          (const_string "V4SF")))])
21047
21048 ;; Use xor, but don't show input operands so they aren't live before
21049 ;; this insn.
21050 (define_insn "sse_clrv2df"
21051   [(set (match_operand:V2DF 0 "register_operand" "=x")
21052         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21053   "TARGET_SSE2"
21054   "xorpd\t{%0, %0|%0, %0}"
21055   [(set_attr "type" "sselog")
21056    (set_attr "memory" "none")
21057    (set_attr "mode" "V4SF")])
21058
21059 ;; SSE mask-generating compares
21060
21061 (define_insn "maskcmpv4sf3"
21062   [(set (match_operand:V4SI 0 "register_operand" "=x")
21063         (match_operator:V4SI 3 "sse_comparison_operator"
21064                 [(match_operand:V4SF 1 "register_operand" "0")
21065                  (match_operand:V4SF 2 "register_operand" "x")]))]
21066   "TARGET_SSE"
21067   "cmp%D3ps\t{%2, %0|%0, %2}"
21068   [(set_attr "type" "ssecmp")
21069    (set_attr "mode" "V4SF")])
21070
21071 (define_insn "maskncmpv4sf3"
21072   [(set (match_operand:V4SI 0 "register_operand" "=x")
21073         (not:V4SI
21074          (match_operator:V4SI 3 "sse_comparison_operator"
21075                 [(match_operand:V4SF 1 "register_operand" "0")
21076                  (match_operand:V4SF 2 "register_operand" "x")])))]
21077   "TARGET_SSE"
21078 {
21079   if (GET_CODE (operands[3]) == UNORDERED)
21080     return "cmpordps\t{%2, %0|%0, %2}";
21081   else
21082     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21083 }
21084   [(set_attr "type" "ssecmp")
21085    (set_attr "mode" "V4SF")])
21086
21087 (define_insn "vmmaskcmpv4sf3"
21088   [(set (match_operand:V4SI 0 "register_operand" "=x")
21089         (vec_merge:V4SI
21090          (match_operator:V4SI 3 "sse_comparison_operator"
21091                 [(match_operand:V4SF 1 "register_operand" "0")
21092                  (match_operand:V4SF 2 "register_operand" "x")])
21093          (subreg:V4SI (match_dup 1) 0)
21094          (const_int 1)))]
21095   "TARGET_SSE"
21096   "cmp%D3ss\t{%2, %0|%0, %2}"
21097   [(set_attr "type" "ssecmp")
21098    (set_attr "mode" "SF")])
21099
21100 (define_insn "vmmaskncmpv4sf3"
21101   [(set (match_operand:V4SI 0 "register_operand" "=x")
21102         (vec_merge:V4SI
21103          (not:V4SI
21104           (match_operator:V4SI 3 "sse_comparison_operator"
21105                 [(match_operand:V4SF 1 "register_operand" "0")
21106                  (match_operand:V4SF 2 "register_operand" "x")]))
21107          (subreg:V4SI (match_dup 1) 0)
21108          (const_int 1)))]
21109   "TARGET_SSE"
21110 {
21111   if (GET_CODE (operands[3]) == UNORDERED)
21112     return "cmpordss\t{%2, %0|%0, %2}";
21113   else
21114     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21115 }
21116   [(set_attr "type" "ssecmp")
21117    (set_attr "mode" "SF")])
21118
21119 (define_insn "sse_comi"
21120   [(set (reg:CCFP FLAGS_REG)
21121         (compare:CCFP (vec_select:SF
21122                        (match_operand:V4SF 0 "register_operand" "x")
21123                        (parallel [(const_int 0)]))
21124                       (vec_select:SF
21125                        (match_operand:V4SF 1 "register_operand" "x")
21126                        (parallel [(const_int 0)]))))]
21127   "TARGET_SSE"
21128   "comiss\t{%1, %0|%0, %1}"
21129   [(set_attr "type" "ssecomi")
21130    (set_attr "mode" "SF")])
21131
21132 (define_insn "sse_ucomi"
21133   [(set (reg:CCFPU FLAGS_REG)
21134         (compare:CCFPU (vec_select:SF
21135                         (match_operand:V4SF 0 "register_operand" "x")
21136                         (parallel [(const_int 0)]))
21137                        (vec_select:SF
21138                         (match_operand:V4SF 1 "register_operand" "x")
21139                         (parallel [(const_int 0)]))))]
21140   "TARGET_SSE"
21141   "ucomiss\t{%1, %0|%0, %1}"
21142   [(set_attr "type" "ssecomi")
21143    (set_attr "mode" "SF")])
21144
21145
21146 ;; SSE unpack
21147
21148 (define_insn "sse_unpckhps"
21149   [(set (match_operand:V4SF 0 "register_operand" "=x")
21150         (vec_merge:V4SF
21151          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21152                           (parallel [(const_int 2)
21153                                      (const_int 0)
21154                                      (const_int 3)
21155                                      (const_int 1)]))
21156          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21157                           (parallel [(const_int 0)
21158                                      (const_int 2)
21159                                      (const_int 1)
21160                                      (const_int 3)]))
21161          (const_int 5)))]
21162   "TARGET_SSE"
21163   "unpckhps\t{%2, %0|%0, %2}"
21164   [(set_attr "type" "ssecvt")
21165    (set_attr "mode" "V4SF")])
21166
21167 (define_insn "sse_unpcklps"
21168   [(set (match_operand:V4SF 0 "register_operand" "=x")
21169         (vec_merge:V4SF
21170          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21171                           (parallel [(const_int 0)
21172                                      (const_int 2)
21173                                      (const_int 1)
21174                                      (const_int 3)]))
21175          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21176                           (parallel [(const_int 2)
21177                                      (const_int 0)
21178                                      (const_int 3)
21179                                      (const_int 1)]))
21180          (const_int 5)))]
21181   "TARGET_SSE"
21182   "unpcklps\t{%2, %0|%0, %2}"
21183   [(set_attr "type" "ssecvt")
21184    (set_attr "mode" "V4SF")])
21185
21186
21187 ;; SSE min/max
21188
21189 (define_insn "smaxv4sf3"
21190   [(set (match_operand:V4SF 0 "register_operand" "=x")
21191         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21192                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21193   "TARGET_SSE"
21194   "maxps\t{%2, %0|%0, %2}"
21195   [(set_attr "type" "sse")
21196    (set_attr "mode" "V4SF")])
21197
21198 (define_insn "vmsmaxv4sf3"
21199   [(set (match_operand:V4SF 0 "register_operand" "=x")
21200         (vec_merge:V4SF
21201          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21202                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21203          (match_dup 1)
21204          (const_int 1)))]
21205   "TARGET_SSE"
21206   "maxss\t{%2, %0|%0, %2}"
21207   [(set_attr "type" "sse")
21208    (set_attr "mode" "SF")])
21209
21210 (define_insn "sminv4sf3"
21211   [(set (match_operand:V4SF 0 "register_operand" "=x")
21212         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21213                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21214   "TARGET_SSE"
21215   "minps\t{%2, %0|%0, %2}"
21216   [(set_attr "type" "sse")
21217    (set_attr "mode" "V4SF")])
21218
21219 (define_insn "vmsminv4sf3"
21220   [(set (match_operand:V4SF 0 "register_operand" "=x")
21221         (vec_merge:V4SF
21222          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21223                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21224          (match_dup 1)
21225          (const_int 1)))]
21226   "TARGET_SSE"
21227   "minss\t{%2, %0|%0, %2}"
21228   [(set_attr "type" "sse")
21229    (set_attr "mode" "SF")])
21230
21231 ;; SSE <-> integer/MMX conversions
21232
21233 (define_insn "cvtpi2ps"
21234   [(set (match_operand:V4SF 0 "register_operand" "=x")
21235         (vec_merge:V4SF
21236          (match_operand:V4SF 1 "register_operand" "0")
21237          (vec_duplicate:V4SF
21238           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21239          (const_int 12)))]
21240   "TARGET_SSE"
21241   "cvtpi2ps\t{%2, %0|%0, %2}"
21242   [(set_attr "type" "ssecvt")
21243    (set_attr "mode" "V4SF")])
21244
21245 (define_insn "cvtps2pi"
21246   [(set (match_operand:V2SI 0 "register_operand" "=y")
21247         (vec_select:V2SI
21248          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21249          (parallel [(const_int 0) (const_int 1)])))]
21250   "TARGET_SSE"
21251   "cvtps2pi\t{%1, %0|%0, %1}"
21252   [(set_attr "type" "ssecvt")
21253    (set_attr "mode" "V4SF")])
21254
21255 (define_insn "cvttps2pi"
21256   [(set (match_operand:V2SI 0 "register_operand" "=y")
21257         (vec_select:V2SI
21258          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21259                       UNSPEC_FIX)
21260          (parallel [(const_int 0) (const_int 1)])))]
21261   "TARGET_SSE"
21262   "cvttps2pi\t{%1, %0|%0, %1}"
21263   [(set_attr "type" "ssecvt")
21264    (set_attr "mode" "SF")])
21265
21266 (define_insn "cvtsi2ss"
21267   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21268         (vec_merge:V4SF
21269          (match_operand:V4SF 1 "register_operand" "0,0")
21270          (vec_duplicate:V4SF
21271           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21272          (const_int 14)))]
21273   "TARGET_SSE"
21274   "cvtsi2ss\t{%2, %0|%0, %2}"
21275   [(set_attr "type" "sseicvt")
21276    (set_attr "athlon_decode" "vector,double")
21277    (set_attr "mode" "SF")])
21278
21279 (define_insn "cvtsi2ssq"
21280   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21281         (vec_merge:V4SF
21282          (match_operand:V4SF 1 "register_operand" "0,0")
21283          (vec_duplicate:V4SF
21284           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21285          (const_int 14)))]
21286   "TARGET_SSE && TARGET_64BIT"
21287   "cvtsi2ssq\t{%2, %0|%0, %2}"
21288   [(set_attr "type" "sseicvt")
21289    (set_attr "athlon_decode" "vector,double")
21290    (set_attr "mode" "SF")])
21291
21292 (define_insn "cvtss2si"
21293   [(set (match_operand:SI 0 "register_operand" "=r,r")
21294         (vec_select:SI
21295          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21296          (parallel [(const_int 0)])))]
21297   "TARGET_SSE"
21298   "cvtss2si\t{%1, %0|%0, %1}"
21299   [(set_attr "type" "sseicvt")
21300    (set_attr "athlon_decode" "double,vector")
21301    (set_attr "mode" "SI")])
21302
21303 (define_insn "cvtss2siq"
21304   [(set (match_operand:DI 0 "register_operand" "=r,r")
21305         (vec_select:DI
21306          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21307          (parallel [(const_int 0)])))]
21308   "TARGET_SSE"
21309   "cvtss2siq\t{%1, %0|%0, %1}"
21310   [(set_attr "type" "sseicvt")
21311    (set_attr "athlon_decode" "double,vector")
21312    (set_attr "mode" "DI")])
21313
21314 (define_insn "cvttss2si"
21315   [(set (match_operand:SI 0 "register_operand" "=r,r")
21316         (vec_select:SI
21317          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21318                       UNSPEC_FIX)
21319          (parallel [(const_int 0)])))]
21320   "TARGET_SSE"
21321   "cvttss2si\t{%1, %0|%0, %1}"
21322   [(set_attr "type" "sseicvt")
21323    (set_attr "mode" "SF")
21324    (set_attr "athlon_decode" "double,vector")])
21325
21326 (define_insn "cvttss2siq"
21327   [(set (match_operand:DI 0 "register_operand" "=r,r")
21328         (vec_select:DI
21329          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21330                       UNSPEC_FIX)
21331          (parallel [(const_int 0)])))]
21332   "TARGET_SSE && TARGET_64BIT"
21333   "cvttss2siq\t{%1, %0|%0, %1}"
21334   [(set_attr "type" "sseicvt")
21335    (set_attr "mode" "SF")
21336    (set_attr "athlon_decode" "double,vector")])
21337
21338
21339 ;; MMX insns
21340
21341 ;; MMX arithmetic
21342
21343 (define_insn "addv8qi3"
21344   [(set (match_operand:V8QI 0 "register_operand" "=y")
21345         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21346                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21347   "TARGET_MMX"
21348   "paddb\t{%2, %0|%0, %2}"
21349   [(set_attr "type" "mmxadd")
21350    (set_attr "mode" "DI")])
21351
21352 (define_insn "addv4hi3"
21353   [(set (match_operand:V4HI 0 "register_operand" "=y")
21354         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21355                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21356   "TARGET_MMX"
21357   "paddw\t{%2, %0|%0, %2}"
21358   [(set_attr "type" "mmxadd")
21359    (set_attr "mode" "DI")])
21360
21361 (define_insn "addv2si3"
21362   [(set (match_operand:V2SI 0 "register_operand" "=y")
21363         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21364                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21365   "TARGET_MMX"
21366   "paddd\t{%2, %0|%0, %2}"
21367   [(set_attr "type" "mmxadd")
21368    (set_attr "mode" "DI")])
21369
21370 (define_insn "mmx_adddi3"
21371   [(set (match_operand:DI 0 "register_operand" "=y")
21372         (unspec:DI
21373          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21374                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21375          UNSPEC_NOP))]
21376   "TARGET_MMX"
21377   "paddq\t{%2, %0|%0, %2}"
21378   [(set_attr "type" "mmxadd")
21379    (set_attr "mode" "DI")])
21380
21381 (define_insn "ssaddv8qi3"
21382   [(set (match_operand:V8QI 0 "register_operand" "=y")
21383         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21384                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21385   "TARGET_MMX"
21386   "paddsb\t{%2, %0|%0, %2}"
21387   [(set_attr "type" "mmxadd")
21388    (set_attr "mode" "DI")])
21389
21390 (define_insn "ssaddv4hi3"
21391   [(set (match_operand:V4HI 0 "register_operand" "=y")
21392         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21393                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21394   "TARGET_MMX"
21395   "paddsw\t{%2, %0|%0, %2}"
21396   [(set_attr "type" "mmxadd")
21397    (set_attr "mode" "DI")])
21398
21399 (define_insn "usaddv8qi3"
21400   [(set (match_operand:V8QI 0 "register_operand" "=y")
21401         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21402                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21403   "TARGET_MMX"
21404   "paddusb\t{%2, %0|%0, %2}"
21405   [(set_attr "type" "mmxadd")
21406    (set_attr "mode" "DI")])
21407
21408 (define_insn "usaddv4hi3"
21409   [(set (match_operand:V4HI 0 "register_operand" "=y")
21410         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21411                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21412   "TARGET_MMX"
21413   "paddusw\t{%2, %0|%0, %2}"
21414   [(set_attr "type" "mmxadd")
21415    (set_attr "mode" "DI")])
21416
21417 (define_insn "subv8qi3"
21418   [(set (match_operand:V8QI 0 "register_operand" "=y")
21419         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21420                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21421   "TARGET_MMX"
21422   "psubb\t{%2, %0|%0, %2}"
21423   [(set_attr "type" "mmxadd")
21424    (set_attr "mode" "DI")])
21425
21426 (define_insn "subv4hi3"
21427   [(set (match_operand:V4HI 0 "register_operand" "=y")
21428         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21429                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21430   "TARGET_MMX"
21431   "psubw\t{%2, %0|%0, %2}"
21432   [(set_attr "type" "mmxadd")
21433    (set_attr "mode" "DI")])
21434
21435 (define_insn "subv2si3"
21436   [(set (match_operand:V2SI 0 "register_operand" "=y")
21437         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21438                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21439   "TARGET_MMX"
21440   "psubd\t{%2, %0|%0, %2}"
21441   [(set_attr "type" "mmxadd")
21442    (set_attr "mode" "DI")])
21443
21444 (define_insn "mmx_subdi3"
21445   [(set (match_operand:DI 0 "register_operand" "=y")
21446         (unspec:DI
21447          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21448                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21449          UNSPEC_NOP))]
21450   "TARGET_MMX"
21451   "psubq\t{%2, %0|%0, %2}"
21452   [(set_attr "type" "mmxadd")
21453    (set_attr "mode" "DI")])
21454
21455 (define_insn "sssubv8qi3"
21456   [(set (match_operand:V8QI 0 "register_operand" "=y")
21457         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21458                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21459   "TARGET_MMX"
21460   "psubsb\t{%2, %0|%0, %2}"
21461   [(set_attr "type" "mmxadd")
21462    (set_attr "mode" "DI")])
21463
21464 (define_insn "sssubv4hi3"
21465   [(set (match_operand:V4HI 0 "register_operand" "=y")
21466         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21467                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21468   "TARGET_MMX"
21469   "psubsw\t{%2, %0|%0, %2}"
21470   [(set_attr "type" "mmxadd")
21471    (set_attr "mode" "DI")])
21472
21473 (define_insn "ussubv8qi3"
21474   [(set (match_operand:V8QI 0 "register_operand" "=y")
21475         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21476                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21477   "TARGET_MMX"
21478   "psubusb\t{%2, %0|%0, %2}"
21479   [(set_attr "type" "mmxadd")
21480    (set_attr "mode" "DI")])
21481
21482 (define_insn "ussubv4hi3"
21483   [(set (match_operand:V4HI 0 "register_operand" "=y")
21484         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21485                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21486   "TARGET_MMX"
21487   "psubusw\t{%2, %0|%0, %2}"
21488   [(set_attr "type" "mmxadd")
21489    (set_attr "mode" "DI")])
21490
21491 (define_insn "mulv4hi3"
21492   [(set (match_operand:V4HI 0 "register_operand" "=y")
21493         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21494                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21495   "TARGET_MMX"
21496   "pmullw\t{%2, %0|%0, %2}"
21497   [(set_attr "type" "mmxmul")
21498    (set_attr "mode" "DI")])
21499
21500 (define_insn "smulv4hi3_highpart"
21501   [(set (match_operand:V4HI 0 "register_operand" "=y")
21502         (truncate:V4HI
21503          (lshiftrt:V4SI
21504           (mult:V4SI (sign_extend:V4SI
21505                       (match_operand:V4HI 1 "register_operand" "0"))
21506                      (sign_extend:V4SI
21507                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21508           (const_int 16))))]
21509   "TARGET_MMX"
21510   "pmulhw\t{%2, %0|%0, %2}"
21511   [(set_attr "type" "mmxmul")
21512    (set_attr "mode" "DI")])
21513
21514 (define_insn "umulv4hi3_highpart"
21515   [(set (match_operand:V4HI 0 "register_operand" "=y")
21516         (truncate:V4HI
21517          (lshiftrt:V4SI
21518           (mult:V4SI (zero_extend:V4SI
21519                       (match_operand:V4HI 1 "register_operand" "0"))
21520                      (zero_extend:V4SI
21521                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21522           (const_int 16))))]
21523   "TARGET_SSE || TARGET_3DNOW_A"
21524   "pmulhuw\t{%2, %0|%0, %2}"
21525   [(set_attr "type" "mmxmul")
21526    (set_attr "mode" "DI")])
21527
21528 (define_insn "mmx_pmaddwd"
21529   [(set (match_operand:V2SI 0 "register_operand" "=y")
21530         (plus:V2SI
21531          (mult:V2SI
21532           (sign_extend:V2SI
21533            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21534                             (parallel [(const_int 0) (const_int 2)])))
21535           (sign_extend:V2SI
21536            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21537                             (parallel [(const_int 0) (const_int 2)]))))
21538          (mult:V2SI
21539           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21540                                              (parallel [(const_int 1)
21541                                                         (const_int 3)])))
21542           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21543                                              (parallel [(const_int 1)
21544                                                         (const_int 3)]))))))]
21545   "TARGET_MMX"
21546   "pmaddwd\t{%2, %0|%0, %2}"
21547   [(set_attr "type" "mmxmul")
21548    (set_attr "mode" "DI")])
21549
21550
21551 ;; MMX logical operations
21552 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21553 ;; normal code that also wants to use the FPU from getting broken.
21554 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21555 (define_insn "mmx_iordi3"
21556   [(set (match_operand:DI 0 "register_operand" "=y")
21557         (unspec:DI
21558          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21559                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21560          UNSPEC_NOP))]
21561   "TARGET_MMX"
21562   "por\t{%2, %0|%0, %2}"
21563   [(set_attr "type" "mmxadd")
21564    (set_attr "mode" "DI")])
21565
21566 (define_insn "mmx_xordi3"
21567   [(set (match_operand:DI 0 "register_operand" "=y")
21568         (unspec:DI
21569          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21570                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21571          UNSPEC_NOP))]
21572   "TARGET_MMX"
21573   "pxor\t{%2, %0|%0, %2}"
21574   [(set_attr "type" "mmxadd")
21575    (set_attr "mode" "DI")
21576    (set_attr "memory" "none")])
21577
21578 ;; Same as pxor, but don't show input operands so that we don't think
21579 ;; they are live.
21580 (define_insn "mmx_clrdi"
21581   [(set (match_operand:DI 0 "register_operand" "=y")
21582         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21583   "TARGET_MMX"
21584   "pxor\t{%0, %0|%0, %0}"
21585   [(set_attr "type" "mmxadd")
21586    (set_attr "mode" "DI")
21587    (set_attr "memory" "none")])
21588
21589 (define_insn "mmx_anddi3"
21590   [(set (match_operand:DI 0 "register_operand" "=y")
21591         (unspec:DI
21592          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21593                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21594          UNSPEC_NOP))]
21595   "TARGET_MMX"
21596   "pand\t{%2, %0|%0, %2}"
21597   [(set_attr "type" "mmxadd")
21598    (set_attr "mode" "DI")])
21599
21600 (define_insn "mmx_nanddi3"
21601   [(set (match_operand:DI 0 "register_operand" "=y")
21602         (unspec:DI
21603          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21604                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21605          UNSPEC_NOP))]
21606   "TARGET_MMX"
21607   "pandn\t{%2, %0|%0, %2}"
21608   [(set_attr "type" "mmxadd")
21609    (set_attr "mode" "DI")])
21610
21611
21612 ;; MMX unsigned averages/sum of absolute differences
21613
21614 (define_insn "mmx_uavgv8qi3"
21615   [(set (match_operand:V8QI 0 "register_operand" "=y")
21616         (ashiftrt:V8QI
21617          (plus:V8QI (plus:V8QI
21618                      (match_operand:V8QI 1 "register_operand" "0")
21619                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21620                     (const_vector:V8QI [(const_int 1)
21621                                         (const_int 1)
21622                                         (const_int 1)
21623                                         (const_int 1)
21624                                         (const_int 1)
21625                                         (const_int 1)
21626                                         (const_int 1)
21627                                         (const_int 1)]))
21628          (const_int 1)))]
21629   "TARGET_SSE || TARGET_3DNOW_A"
21630   "pavgb\t{%2, %0|%0, %2}"
21631   [(set_attr "type" "mmxshft")
21632    (set_attr "mode" "DI")])
21633
21634 (define_insn "mmx_uavgv4hi3"
21635   [(set (match_operand:V4HI 0 "register_operand" "=y")
21636         (ashiftrt:V4HI
21637          (plus:V4HI (plus:V4HI
21638                      (match_operand:V4HI 1 "register_operand" "0")
21639                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21640                     (const_vector:V4HI [(const_int 1)
21641                                         (const_int 1)
21642                                         (const_int 1)
21643                                         (const_int 1)]))
21644          (const_int 1)))]
21645   "TARGET_SSE || TARGET_3DNOW_A"
21646   "pavgw\t{%2, %0|%0, %2}"
21647   [(set_attr "type" "mmxshft")
21648    (set_attr "mode" "DI")])
21649
21650 (define_insn "mmx_psadbw"
21651   [(set (match_operand:DI 0 "register_operand" "=y")
21652         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21653                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21654                    UNSPEC_PSADBW))]
21655   "TARGET_SSE || TARGET_3DNOW_A"
21656   "psadbw\t{%2, %0|%0, %2}"
21657   [(set_attr "type" "mmxshft")
21658    (set_attr "mode" "DI")])
21659
21660
21661 ;; MMX insert/extract/shuffle
21662
21663 (define_insn "mmx_pinsrw"
21664   [(set (match_operand:V4HI 0 "register_operand" "=y")
21665         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21666                         (vec_duplicate:V4HI
21667                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21668                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21669   "TARGET_SSE || TARGET_3DNOW_A"
21670   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21671   [(set_attr "type" "mmxcvt")
21672    (set_attr "mode" "DI")])
21673
21674 (define_insn "mmx_pextrw"
21675   [(set (match_operand:SI 0 "register_operand" "=r")
21676         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21677                                        (parallel
21678                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21679   "TARGET_SSE || TARGET_3DNOW_A"
21680   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21681   [(set_attr "type" "mmxcvt")
21682    (set_attr "mode" "DI")])
21683
21684 (define_insn "mmx_pshufw"
21685   [(set (match_operand:V4HI 0 "register_operand" "=y")
21686         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21687                       (match_operand:SI 2 "immediate_operand" "i")]
21688                      UNSPEC_SHUFFLE))]
21689   "TARGET_SSE || TARGET_3DNOW_A"
21690   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21691   [(set_attr "type" "mmxcvt")
21692    (set_attr "mode" "DI")])
21693
21694
21695 ;; MMX mask-generating comparisons
21696
21697 (define_insn "eqv8qi3"
21698   [(set (match_operand:V8QI 0 "register_operand" "=y")
21699         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21700                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21701   "TARGET_MMX"
21702   "pcmpeqb\t{%2, %0|%0, %2}"
21703   [(set_attr "type" "mmxcmp")
21704    (set_attr "mode" "DI")])
21705
21706 (define_insn "eqv4hi3"
21707   [(set (match_operand:V4HI 0 "register_operand" "=y")
21708         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21709                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21710   "TARGET_MMX"
21711   "pcmpeqw\t{%2, %0|%0, %2}"
21712   [(set_attr "type" "mmxcmp")
21713    (set_attr "mode" "DI")])
21714
21715 (define_insn "eqv2si3"
21716   [(set (match_operand:V2SI 0 "register_operand" "=y")
21717         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21718                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21719   "TARGET_MMX"
21720   "pcmpeqd\t{%2, %0|%0, %2}"
21721   [(set_attr "type" "mmxcmp")
21722    (set_attr "mode" "DI")])
21723
21724 (define_insn "gtv8qi3"
21725   [(set (match_operand:V8QI 0 "register_operand" "=y")
21726         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21727                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21728   "TARGET_MMX"
21729   "pcmpgtb\t{%2, %0|%0, %2}"
21730   [(set_attr "type" "mmxcmp")
21731    (set_attr "mode" "DI")])
21732
21733 (define_insn "gtv4hi3"
21734   [(set (match_operand:V4HI 0 "register_operand" "=y")
21735         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21736                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21737   "TARGET_MMX"
21738   "pcmpgtw\t{%2, %0|%0, %2}"
21739   [(set_attr "type" "mmxcmp")
21740    (set_attr "mode" "DI")])
21741
21742 (define_insn "gtv2si3"
21743   [(set (match_operand:V2SI 0 "register_operand" "=y")
21744         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21745                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21746   "TARGET_MMX"
21747   "pcmpgtd\t{%2, %0|%0, %2}"
21748   [(set_attr "type" "mmxcmp")
21749    (set_attr "mode" "DI")])
21750
21751
21752 ;; MMX max/min insns
21753
21754 (define_insn "umaxv8qi3"
21755   [(set (match_operand:V8QI 0 "register_operand" "=y")
21756         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21757                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21758   "TARGET_SSE || TARGET_3DNOW_A"
21759   "pmaxub\t{%2, %0|%0, %2}"
21760   [(set_attr "type" "mmxadd")
21761    (set_attr "mode" "DI")])
21762
21763 (define_insn "smaxv4hi3"
21764   [(set (match_operand:V4HI 0 "register_operand" "=y")
21765         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21766                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21767   "TARGET_SSE || TARGET_3DNOW_A"
21768   "pmaxsw\t{%2, %0|%0, %2}"
21769   [(set_attr "type" "mmxadd")
21770    (set_attr "mode" "DI")])
21771
21772 (define_insn "uminv8qi3"
21773   [(set (match_operand:V8QI 0 "register_operand" "=y")
21774         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21775                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21776   "TARGET_SSE || TARGET_3DNOW_A"
21777   "pminub\t{%2, %0|%0, %2}"
21778   [(set_attr "type" "mmxadd")
21779    (set_attr "mode" "DI")])
21780
21781 (define_insn "sminv4hi3"
21782   [(set (match_operand:V4HI 0 "register_operand" "=y")
21783         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21784                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21785   "TARGET_SSE || TARGET_3DNOW_A"
21786   "pminsw\t{%2, %0|%0, %2}"
21787   [(set_attr "type" "mmxadd")
21788    (set_attr "mode" "DI")])
21789
21790
21791 ;; MMX shifts
21792
21793 (define_insn "ashrv4hi3"
21794   [(set (match_operand:V4HI 0 "register_operand" "=y")
21795         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21796                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21797   "TARGET_MMX"
21798   "psraw\t{%2, %0|%0, %2}"
21799   [(set_attr "type" "mmxshft")
21800    (set_attr "mode" "DI")])
21801
21802 (define_insn "ashrv2si3"
21803   [(set (match_operand:V2SI 0 "register_operand" "=y")
21804         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21805                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21806   "TARGET_MMX"
21807   "psrad\t{%2, %0|%0, %2}"
21808   [(set_attr "type" "mmxshft")
21809    (set_attr "mode" "DI")])
21810
21811 (define_insn "lshrv4hi3"
21812   [(set (match_operand:V4HI 0 "register_operand" "=y")
21813         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21814                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21815   "TARGET_MMX"
21816   "psrlw\t{%2, %0|%0, %2}"
21817   [(set_attr "type" "mmxshft")
21818    (set_attr "mode" "DI")])
21819
21820 (define_insn "lshrv2si3"
21821   [(set (match_operand:V2SI 0 "register_operand" "=y")
21822         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21823                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21824   "TARGET_MMX"
21825   "psrld\t{%2, %0|%0, %2}"
21826   [(set_attr "type" "mmxshft")
21827    (set_attr "mode" "DI")])
21828
21829 ;; See logical MMX insns.
21830 (define_insn "mmx_lshrdi3"
21831   [(set (match_operand:DI 0 "register_operand" "=y")
21832         (unspec:DI
21833           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21834                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21835           UNSPEC_NOP))]
21836   "TARGET_MMX"
21837   "psrlq\t{%2, %0|%0, %2}"
21838   [(set_attr "type" "mmxshft")
21839    (set_attr "mode" "DI")])
21840
21841 (define_insn "ashlv4hi3"
21842   [(set (match_operand:V4HI 0 "register_operand" "=y")
21843         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21844                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21845   "TARGET_MMX"
21846   "psllw\t{%2, %0|%0, %2}"
21847   [(set_attr "type" "mmxshft")
21848    (set_attr "mode" "DI")])
21849
21850 (define_insn "ashlv2si3"
21851   [(set (match_operand:V2SI 0 "register_operand" "=y")
21852         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21853                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21854   "TARGET_MMX"
21855   "pslld\t{%2, %0|%0, %2}"
21856   [(set_attr "type" "mmxshft")
21857    (set_attr "mode" "DI")])
21858
21859 ;; See logical MMX insns.
21860 (define_insn "mmx_ashldi3"
21861   [(set (match_operand:DI 0 "register_operand" "=y")
21862         (unspec:DI
21863          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21864                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21865          UNSPEC_NOP))]
21866   "TARGET_MMX"
21867   "psllq\t{%2, %0|%0, %2}"
21868   [(set_attr "type" "mmxshft")
21869    (set_attr "mode" "DI")])
21870
21871
21872 ;; MMX pack/unpack insns.
21873
21874 (define_insn "mmx_packsswb"
21875   [(set (match_operand:V8QI 0 "register_operand" "=y")
21876         (vec_concat:V8QI
21877          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21878          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21879   "TARGET_MMX"
21880   "packsswb\t{%2, %0|%0, %2}"
21881   [(set_attr "type" "mmxshft")
21882    (set_attr "mode" "DI")])
21883
21884 (define_insn "mmx_packssdw"
21885   [(set (match_operand:V4HI 0 "register_operand" "=y")
21886         (vec_concat:V4HI
21887          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21888          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21889   "TARGET_MMX"
21890   "packssdw\t{%2, %0|%0, %2}"
21891   [(set_attr "type" "mmxshft")
21892    (set_attr "mode" "DI")])
21893
21894 (define_insn "mmx_packuswb"
21895   [(set (match_operand:V8QI 0 "register_operand" "=y")
21896         (vec_concat:V8QI
21897          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21898          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21899   "TARGET_MMX"
21900   "packuswb\t{%2, %0|%0, %2}"
21901   [(set_attr "type" "mmxshft")
21902    (set_attr "mode" "DI")])
21903
21904 (define_insn "mmx_punpckhbw"
21905   [(set (match_operand:V8QI 0 "register_operand" "=y")
21906         (vec_merge:V8QI
21907          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21908                           (parallel [(const_int 4)
21909                                      (const_int 0)
21910                                      (const_int 5)
21911                                      (const_int 1)
21912                                      (const_int 6)
21913                                      (const_int 2)
21914                                      (const_int 7)
21915                                      (const_int 3)]))
21916          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21917                           (parallel [(const_int 0)
21918                                      (const_int 4)
21919                                      (const_int 1)
21920                                      (const_int 5)
21921                                      (const_int 2)
21922                                      (const_int 6)
21923                                      (const_int 3)
21924                                      (const_int 7)]))
21925          (const_int 85)))]
21926   "TARGET_MMX"
21927   "punpckhbw\t{%2, %0|%0, %2}"
21928   [(set_attr "type" "mmxcvt")
21929    (set_attr "mode" "DI")])
21930
21931 (define_insn "mmx_punpckhwd"
21932   [(set (match_operand:V4HI 0 "register_operand" "=y")
21933         (vec_merge:V4HI
21934          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21935                           (parallel [(const_int 0)
21936                                      (const_int 2)
21937                                      (const_int 1)
21938                                      (const_int 3)]))
21939          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21940                           (parallel [(const_int 2)
21941                                      (const_int 0)
21942                                      (const_int 3)
21943                                      (const_int 1)]))
21944          (const_int 5)))]
21945   "TARGET_MMX"
21946   "punpckhwd\t{%2, %0|%0, %2}"
21947   [(set_attr "type" "mmxcvt")
21948    (set_attr "mode" "DI")])
21949
21950 (define_insn "mmx_punpckhdq"
21951   [(set (match_operand:V2SI 0 "register_operand" "=y")
21952         (vec_merge:V2SI
21953          (match_operand:V2SI 1 "register_operand" "0")
21954          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21955                           (parallel [(const_int 1)
21956                                      (const_int 0)]))
21957          (const_int 1)))]
21958   "TARGET_MMX"
21959   "punpckhdq\t{%2, %0|%0, %2}"
21960   [(set_attr "type" "mmxcvt")
21961    (set_attr "mode" "DI")])
21962
21963 (define_insn "mmx_punpcklbw"
21964   [(set (match_operand:V8QI 0 "register_operand" "=y")
21965         (vec_merge:V8QI
21966          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21967                           (parallel [(const_int 0)
21968                                      (const_int 4)
21969                                      (const_int 1)
21970                                      (const_int 5)
21971                                      (const_int 2)
21972                                      (const_int 6)
21973                                      (const_int 3)
21974                                      (const_int 7)]))
21975          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21976                           (parallel [(const_int 4)
21977                                      (const_int 0)
21978                                      (const_int 5)
21979                                      (const_int 1)
21980                                      (const_int 6)
21981                                      (const_int 2)
21982                                      (const_int 7)
21983                                      (const_int 3)]))
21984          (const_int 85)))]
21985   "TARGET_MMX"
21986   "punpcklbw\t{%2, %0|%0, %2}"
21987   [(set_attr "type" "mmxcvt")
21988    (set_attr "mode" "DI")])
21989
21990 (define_insn "mmx_punpcklwd"
21991   [(set (match_operand:V4HI 0 "register_operand" "=y")
21992         (vec_merge:V4HI
21993          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21994                           (parallel [(const_int 2)
21995                                      (const_int 0)
21996                                      (const_int 3)
21997                                      (const_int 1)]))
21998          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21999                           (parallel [(const_int 0)
22000                                      (const_int 2)
22001                                      (const_int 1)
22002                                      (const_int 3)]))
22003          (const_int 5)))]
22004   "TARGET_MMX"
22005   "punpcklwd\t{%2, %0|%0, %2}"
22006   [(set_attr "type" "mmxcvt")
22007    (set_attr "mode" "DI")])
22008
22009 (define_insn "mmx_punpckldq"
22010   [(set (match_operand:V2SI 0 "register_operand" "=y")
22011         (vec_merge:V2SI
22012          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22013                            (parallel [(const_int 1)
22014                                       (const_int 0)]))
22015          (match_operand:V2SI 2 "register_operand" "y")
22016          (const_int 1)))]
22017   "TARGET_MMX"
22018   "punpckldq\t{%2, %0|%0, %2}"
22019   [(set_attr "type" "mmxcvt")
22020    (set_attr "mode" "DI")])
22021
22022
22023 ;; Miscellaneous stuff
22024
22025 (define_insn "emms"
22026   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22027    (clobber (reg:XF 8))
22028    (clobber (reg:XF 9))
22029    (clobber (reg:XF 10))
22030    (clobber (reg:XF 11))
22031    (clobber (reg:XF 12))
22032    (clobber (reg:XF 13))
22033    (clobber (reg:XF 14))
22034    (clobber (reg:XF 15))
22035    (clobber (reg:DI 29))
22036    (clobber (reg:DI 30))
22037    (clobber (reg:DI 31))
22038    (clobber (reg:DI 32))
22039    (clobber (reg:DI 33))
22040    (clobber (reg:DI 34))
22041    (clobber (reg:DI 35))
22042    (clobber (reg:DI 36))]
22043   "TARGET_MMX"
22044   "emms"
22045   [(set_attr "type" "mmx")
22046    (set_attr "memory" "unknown")])
22047
22048 (define_insn "ldmxcsr"
22049   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22050                     UNSPECV_LDMXCSR)]
22051   "TARGET_SSE"
22052   "ldmxcsr\t%0"
22053   [(set_attr "type" "sse")
22054    (set_attr "memory" "load")])
22055
22056 (define_insn "stmxcsr"
22057   [(set (match_operand:SI 0 "memory_operand" "=m")
22058         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22059   "TARGET_SSE"
22060   "stmxcsr\t%0"
22061   [(set_attr "type" "sse")
22062    (set_attr "memory" "store")])
22063
22064 (define_expand "sfence"
22065   [(set (match_dup 0)
22066         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22067   "TARGET_SSE || TARGET_3DNOW_A"
22068 {
22069   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22070   MEM_VOLATILE_P (operands[0]) = 1;
22071 })
22072
22073 (define_insn "*sfence_insn"
22074   [(set (match_operand:BLK 0 "" "")
22075         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22076   "TARGET_SSE || TARGET_3DNOW_A"
22077   "sfence"
22078   [(set_attr "type" "sse")
22079    (set_attr "memory" "unknown")])
22080
22081 (define_expand "sse_prologue_save"
22082   [(parallel [(set (match_operand:BLK 0 "" "")
22083                    (unspec:BLK [(reg:DI 21)
22084                                 (reg:DI 22)
22085                                 (reg:DI 23)
22086                                 (reg:DI 24)
22087                                 (reg:DI 25)
22088                                 (reg:DI 26)
22089                                 (reg:DI 27)
22090                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22091               (use (match_operand:DI 1 "register_operand" ""))
22092               (use (match_operand:DI 2 "immediate_operand" ""))
22093               (use (label_ref:DI (match_operand 3 "" "")))])]
22094   "TARGET_64BIT"
22095   "")
22096
22097 (define_insn "*sse_prologue_save_insn"
22098   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22099                           (match_operand:DI 4 "const_int_operand" "n")))
22100         (unspec:BLK [(reg:DI 21)
22101                      (reg:DI 22)
22102                      (reg:DI 23)
22103                      (reg:DI 24)
22104                      (reg:DI 25)
22105                      (reg:DI 26)
22106                      (reg:DI 27)
22107                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22108    (use (match_operand:DI 1 "register_operand" "r"))
22109    (use (match_operand:DI 2 "const_int_operand" "i"))
22110    (use (label_ref:DI (match_operand 3 "" "X")))]
22111   "TARGET_64BIT
22112    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22113    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22114   "*
22115 {
22116   int i;
22117   operands[0] = gen_rtx_MEM (Pmode,
22118                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22119   output_asm_insn (\"jmp\\t%A1\", operands);
22120   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22121     {
22122       operands[4] = adjust_address (operands[0], DImode, i*16);
22123       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22124       PUT_MODE (operands[4], TImode);
22125       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22126         output_asm_insn (\"rex\", operands);
22127       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22128     }
22129   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22130                              CODE_LABEL_NUMBER (operands[3]));
22131   RET;
22132 }
22133   "
22134   [(set_attr "type" "other")
22135    (set_attr "length_immediate" "0")
22136    (set_attr "length_address" "0")
22137    (set_attr "length" "135")
22138    (set_attr "memory" "store")
22139    (set_attr "modrm" "0")
22140    (set_attr "mode" "DI")])
22141
22142 ;; 3Dnow! instructions
22143
22144 (define_insn "addv2sf3"
22145   [(set (match_operand:V2SF 0 "register_operand" "=y")
22146         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22147                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22148   "TARGET_3DNOW"
22149   "pfadd\\t{%2, %0|%0, %2}"
22150   [(set_attr "type" "mmxadd")
22151    (set_attr "mode" "V2SF")])
22152
22153 (define_insn "subv2sf3"
22154   [(set (match_operand:V2SF 0 "register_operand" "=y")
22155         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22156                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22157   "TARGET_3DNOW"
22158   "pfsub\\t{%2, %0|%0, %2}"
22159   [(set_attr "type" "mmxadd")
22160    (set_attr "mode" "V2SF")])
22161
22162 (define_insn "subrv2sf3"
22163   [(set (match_operand:V2SF 0 "register_operand" "=y")
22164         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22165                     (match_operand:V2SF 1 "register_operand" "0")))]
22166   "TARGET_3DNOW"
22167   "pfsubr\\t{%2, %0|%0, %2}"
22168   [(set_attr "type" "mmxadd")
22169    (set_attr "mode" "V2SF")])
22170
22171 (define_insn "gtv2sf3"
22172   [(set (match_operand:V2SI 0 "register_operand" "=y")
22173         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22174                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22175  "TARGET_3DNOW"
22176   "pfcmpgt\\t{%2, %0|%0, %2}"
22177   [(set_attr "type" "mmxcmp")
22178    (set_attr "mode" "V2SF")])
22179
22180 (define_insn "gev2sf3"
22181   [(set (match_operand:V2SI 0 "register_operand" "=y")
22182         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22183                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22184   "TARGET_3DNOW"
22185   "pfcmpge\\t{%2, %0|%0, %2}"
22186   [(set_attr "type" "mmxcmp")
22187    (set_attr "mode" "V2SF")])
22188
22189 (define_insn "eqv2sf3"
22190   [(set (match_operand:V2SI 0 "register_operand" "=y")
22191         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22192                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22193   "TARGET_3DNOW"
22194   "pfcmpeq\\t{%2, %0|%0, %2}"
22195   [(set_attr "type" "mmxcmp")
22196    (set_attr "mode" "V2SF")])
22197
22198 (define_insn "pfmaxv2sf3"
22199   [(set (match_operand:V2SF 0 "register_operand" "=y")
22200         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22201                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22202   "TARGET_3DNOW"
22203   "pfmax\\t{%2, %0|%0, %2}"
22204   [(set_attr "type" "mmxadd")
22205    (set_attr "mode" "V2SF")])
22206
22207 (define_insn "pfminv2sf3"
22208   [(set (match_operand:V2SF 0 "register_operand" "=y")
22209         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22210                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22211   "TARGET_3DNOW"
22212   "pfmin\\t{%2, %0|%0, %2}"
22213   [(set_attr "type" "mmxadd")
22214    (set_attr "mode" "V2SF")])
22215
22216 (define_insn "mulv2sf3"
22217   [(set (match_operand:V2SF 0 "register_operand" "=y")
22218         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22219                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22220   "TARGET_3DNOW"
22221   "pfmul\\t{%2, %0|%0, %2}"
22222   [(set_attr "type" "mmxmul")
22223    (set_attr "mode" "V2SF")])
22224
22225 (define_insn "femms"
22226   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22227    (clobber (reg:XF 8))
22228    (clobber (reg:XF 9))
22229    (clobber (reg:XF 10))
22230    (clobber (reg:XF 11))
22231    (clobber (reg:XF 12))
22232    (clobber (reg:XF 13))
22233    (clobber (reg:XF 14))
22234    (clobber (reg:XF 15))
22235    (clobber (reg:DI 29))
22236    (clobber (reg:DI 30))
22237    (clobber (reg:DI 31))
22238    (clobber (reg:DI 32))
22239    (clobber (reg:DI 33))
22240    (clobber (reg:DI 34))
22241    (clobber (reg:DI 35))
22242    (clobber (reg:DI 36))]
22243   "TARGET_3DNOW"
22244   "femms"
22245   [(set_attr "type" "mmx")
22246    (set_attr "memory" "none")]) 
22247
22248 (define_insn "pf2id"
22249   [(set (match_operand:V2SI 0 "register_operand" "=y")
22250         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22251   "TARGET_3DNOW"
22252   "pf2id\\t{%1, %0|%0, %1}"
22253   [(set_attr "type" "mmxcvt")
22254    (set_attr "mode" "V2SF")])
22255
22256 (define_insn "pf2iw"
22257   [(set (match_operand:V2SI 0 "register_operand" "=y")
22258         (sign_extend:V2SI
22259            (ss_truncate:V2HI
22260               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22261   "TARGET_3DNOW_A"
22262   "pf2iw\\t{%1, %0|%0, %1}"
22263   [(set_attr "type" "mmxcvt")
22264    (set_attr "mode" "V2SF")])
22265
22266 (define_insn "pfacc"
22267   [(set (match_operand:V2SF 0 "register_operand" "=y")
22268         (vec_concat:V2SF
22269            (plus:SF
22270               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22271                              (parallel [(const_int  0)]))
22272               (vec_select:SF (match_dup 1)
22273                              (parallel [(const_int 1)])))
22274            (plus:SF
22275               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22276                              (parallel [(const_int  0)]))
22277               (vec_select:SF (match_dup 2)
22278                              (parallel [(const_int 1)])))))]
22279   "TARGET_3DNOW"
22280   "pfacc\\t{%2, %0|%0, %2}"
22281   [(set_attr "type" "mmxadd")
22282    (set_attr "mode" "V2SF")])
22283
22284 (define_insn "pfnacc"
22285   [(set (match_operand:V2SF 0 "register_operand" "=y")
22286         (vec_concat:V2SF
22287            (minus:SF
22288               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22289                              (parallel [(const_int 0)]))
22290               (vec_select:SF (match_dup 1)
22291                              (parallel [(const_int 1)])))
22292            (minus:SF
22293               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22294                              (parallel [(const_int  0)]))
22295               (vec_select:SF (match_dup 2)
22296                              (parallel [(const_int 1)])))))]
22297   "TARGET_3DNOW_A"
22298   "pfnacc\\t{%2, %0|%0, %2}"
22299   [(set_attr "type" "mmxadd")
22300    (set_attr "mode" "V2SF")])
22301
22302 (define_insn "pfpnacc"
22303   [(set (match_operand:V2SF 0 "register_operand" "=y")
22304         (vec_concat:V2SF
22305            (minus:SF
22306               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22307                              (parallel [(const_int 0)]))
22308               (vec_select:SF (match_dup 1)
22309                              (parallel [(const_int 1)])))
22310            (plus:SF
22311               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22312                              (parallel [(const_int 0)]))
22313               (vec_select:SF (match_dup 2)
22314                              (parallel [(const_int 1)])))))]
22315   "TARGET_3DNOW_A"
22316   "pfpnacc\\t{%2, %0|%0, %2}"
22317   [(set_attr "type" "mmxadd")
22318    (set_attr "mode" "V2SF")])
22319
22320 (define_insn "pi2fw"
22321   [(set (match_operand:V2SF 0 "register_operand" "=y")
22322         (float:V2SF
22323            (vec_concat:V2SI
22324               (sign_extend:SI
22325                  (truncate:HI
22326                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22327                                    (parallel [(const_int 0)]))))
22328               (sign_extend:SI
22329                  (truncate:HI
22330                     (vec_select:SI (match_dup 1)
22331                                    (parallel [(const_int  1)])))))))]
22332   "TARGET_3DNOW_A"
22333   "pi2fw\\t{%1, %0|%0, %1}"
22334   [(set_attr "type" "mmxcvt")
22335    (set_attr "mode" "V2SF")])
22336
22337 (define_insn "floatv2si2"
22338   [(set (match_operand:V2SF 0 "register_operand" "=y")
22339         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22340   "TARGET_3DNOW"
22341   "pi2fd\\t{%1, %0|%0, %1}"
22342   [(set_attr "type" "mmxcvt")
22343    (set_attr "mode" "V2SF")])
22344
22345 ;; This insn is identical to pavgb in operation, but the opcode is
22346 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22347
22348 (define_insn "pavgusb"
22349  [(set (match_operand:V8QI 0 "register_operand" "=y")
22350        (unspec:V8QI
22351           [(match_operand:V8QI 1 "register_operand" "0")
22352            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22353           UNSPEC_PAVGUSB))]
22354   "TARGET_3DNOW"
22355   "pavgusb\\t{%2, %0|%0, %2}"
22356   [(set_attr "type" "mmxshft")
22357    (set_attr "mode" "TI")])
22358
22359 ;; 3DNow reciprocal and sqrt
22360  
22361 (define_insn "pfrcpv2sf2"
22362   [(set (match_operand:V2SF 0 "register_operand" "=y")
22363         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22364         UNSPEC_PFRCP))]
22365   "TARGET_3DNOW"
22366   "pfrcp\\t{%1, %0|%0, %1}"
22367   [(set_attr "type" "mmx")
22368    (set_attr "mode" "TI")])
22369
22370 (define_insn "pfrcpit1v2sf3"
22371   [(set (match_operand:V2SF 0 "register_operand" "=y")
22372         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22373                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22374                      UNSPEC_PFRCPIT1))]
22375   "TARGET_3DNOW"
22376   "pfrcpit1\\t{%2, %0|%0, %2}"
22377   [(set_attr "type" "mmx")
22378    (set_attr "mode" "TI")])
22379
22380 (define_insn "pfrcpit2v2sf3"
22381   [(set (match_operand:V2SF 0 "register_operand" "=y")
22382         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22383                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22384                      UNSPEC_PFRCPIT2))]
22385   "TARGET_3DNOW"
22386   "pfrcpit2\\t{%2, %0|%0, %2}"
22387   [(set_attr "type" "mmx")
22388    (set_attr "mode" "TI")])
22389
22390 (define_insn "pfrsqrtv2sf2"
22391   [(set (match_operand:V2SF 0 "register_operand" "=y")
22392         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22393                      UNSPEC_PFRSQRT))]
22394   "TARGET_3DNOW"
22395   "pfrsqrt\\t{%1, %0|%0, %1}"
22396   [(set_attr "type" "mmx")
22397    (set_attr "mode" "TI")])
22398                 
22399 (define_insn "pfrsqit1v2sf3"
22400   [(set (match_operand:V2SF 0 "register_operand" "=y")
22401         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22402                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22403                      UNSPEC_PFRSQIT1))]
22404   "TARGET_3DNOW"
22405   "pfrsqit1\\t{%2, %0|%0, %2}"
22406   [(set_attr "type" "mmx")
22407    (set_attr "mode" "TI")])
22408
22409 (define_insn "pmulhrwv4hi3"
22410   [(set (match_operand:V4HI 0 "register_operand" "=y")
22411         (truncate:V4HI
22412            (lshiftrt:V4SI
22413               (plus:V4SI
22414                  (mult:V4SI
22415                     (sign_extend:V4SI
22416                        (match_operand:V4HI 1 "register_operand" "0"))
22417                     (sign_extend:V4SI
22418                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22419                  (const_vector:V4SI [(const_int 32768)
22420                                      (const_int 32768)
22421                                      (const_int 32768)
22422                                      (const_int 32768)]))
22423               (const_int 16))))]
22424   "TARGET_3DNOW"
22425   "pmulhrw\\t{%2, %0|%0, %2}"
22426   [(set_attr "type" "mmxmul")
22427    (set_attr "mode" "TI")])
22428
22429 (define_insn "pswapdv2si2"
22430   [(set (match_operand:V2SI 0 "register_operand" "=y")
22431         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22432                          (parallel [(const_int 1) (const_int 0)])))]
22433   "TARGET_3DNOW_A"
22434   "pswapd\\t{%1, %0|%0, %1}"
22435   [(set_attr "type" "mmxcvt")
22436    (set_attr "mode" "TI")])
22437
22438 (define_insn "pswapdv2sf2"
22439   [(set (match_operand:V2SF 0 "register_operand" "=y")
22440         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22441                          (parallel [(const_int 1) (const_int 0)])))]
22442   "TARGET_3DNOW_A"
22443   "pswapd\\t{%1, %0|%0, %1}"
22444   [(set_attr "type" "mmxcvt")
22445    (set_attr "mode" "TI")])
22446
22447 (define_expand "prefetch"
22448   [(prefetch (match_operand 0 "address_operand" "")
22449              (match_operand:SI 1 "const_int_operand" "")
22450              (match_operand:SI 2 "const_int_operand" ""))]
22451   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22452 {
22453   int rw = INTVAL (operands[1]);
22454   int locality = INTVAL (operands[2]);
22455
22456   if (rw != 0 && rw != 1)
22457     abort ();
22458   if (locality < 0 || locality > 3)
22459     abort ();
22460   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22461     abort ();
22462
22463   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22464      suported by SSE counterpart or the SSE prefetch is not available
22465      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22466      of locality.  */
22467   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22468     operands[2] = GEN_INT (3);
22469   else
22470     operands[1] = const0_rtx;
22471 })
22472
22473 (define_insn "*prefetch_sse"
22474   [(prefetch (match_operand:SI 0 "address_operand" "p")
22475              (const_int 0)
22476              (match_operand:SI 1 "const_int_operand" ""))]
22477   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22478 {
22479   static const char * const patterns[4] = {
22480    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22481   };
22482
22483   int locality = INTVAL (operands[1]);
22484   if (locality < 0 || locality > 3)
22485     abort ();
22486
22487   return patterns[locality];  
22488 }
22489   [(set_attr "type" "sse")
22490    (set_attr "memory" "none")])
22491
22492 (define_insn "*prefetch_sse_rex"
22493   [(prefetch (match_operand:DI 0 "address_operand" "p")
22494              (const_int 0)
22495              (match_operand:SI 1 "const_int_operand" ""))]
22496   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22497 {
22498   static const char * const patterns[4] = {
22499    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22500   };
22501
22502   int locality = INTVAL (operands[1]);
22503   if (locality < 0 || locality > 3)
22504     abort ();
22505
22506   return patterns[locality];  
22507 }
22508   [(set_attr "type" "sse")
22509    (set_attr "memory" "none")])
22510
22511 (define_insn "*prefetch_3dnow"
22512   [(prefetch (match_operand:SI 0 "address_operand" "p")
22513              (match_operand:SI 1 "const_int_operand" "n")
22514              (const_int 3))]
22515   "TARGET_3DNOW && !TARGET_64BIT"
22516 {
22517   if (INTVAL (operands[1]) == 0)
22518     return "prefetch\t%a0";
22519   else
22520     return "prefetchw\t%a0";
22521 }
22522   [(set_attr "type" "mmx")
22523    (set_attr "memory" "none")])
22524
22525 (define_insn "*prefetch_3dnow_rex"
22526   [(prefetch (match_operand:DI 0 "address_operand" "p")
22527              (match_operand:SI 1 "const_int_operand" "n")
22528              (const_int 3))]
22529   "TARGET_3DNOW && TARGET_64BIT"
22530 {
22531   if (INTVAL (operands[1]) == 0)
22532     return "prefetch\t%a0";
22533   else
22534     return "prefetchw\t%a0";
22535 }
22536   [(set_attr "type" "mmx")
22537    (set_attr "memory" "none")])
22538
22539 ;; SSE2 support
22540
22541 (define_insn "addv2df3"
22542   [(set (match_operand:V2DF 0 "register_operand" "=x")
22543         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22544                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22545   "TARGET_SSE2"
22546   "addpd\t{%2, %0|%0, %2}"
22547   [(set_attr "type" "sseadd")
22548    (set_attr "mode" "V2DF")])
22549
22550 (define_insn "vmaddv2df3"
22551   [(set (match_operand:V2DF 0 "register_operand" "=x")
22552         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22553                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22554                         (match_dup 1)
22555                         (const_int 1)))]
22556   "TARGET_SSE2"
22557   "addsd\t{%2, %0|%0, %2}"
22558   [(set_attr "type" "sseadd")
22559    (set_attr "mode" "DF")])
22560
22561 (define_insn "subv2df3"
22562   [(set (match_operand:V2DF 0 "register_operand" "=x")
22563         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22564                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22565   "TARGET_SSE2"
22566   "subpd\t{%2, %0|%0, %2}"
22567   [(set_attr "type" "sseadd")
22568    (set_attr "mode" "V2DF")])
22569
22570 (define_insn "vmsubv2df3"
22571   [(set (match_operand:V2DF 0 "register_operand" "=x")
22572         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22573                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22574                         (match_dup 1)
22575                         (const_int 1)))]
22576   "TARGET_SSE2"
22577   "subsd\t{%2, %0|%0, %2}"
22578   [(set_attr "type" "sseadd")
22579    (set_attr "mode" "DF")])
22580
22581 (define_insn "mulv2df3"
22582   [(set (match_operand:V2DF 0 "register_operand" "=x")
22583         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22584                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22585   "TARGET_SSE2"
22586   "mulpd\t{%2, %0|%0, %2}"
22587   [(set_attr "type" "ssemul")
22588    (set_attr "mode" "V2DF")])
22589
22590 (define_insn "vmmulv2df3"
22591   [(set (match_operand:V2DF 0 "register_operand" "=x")
22592         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22593                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22594                         (match_dup 1)
22595                         (const_int 1)))]
22596   "TARGET_SSE2"
22597   "mulsd\t{%2, %0|%0, %2}"
22598   [(set_attr "type" "ssemul")
22599    (set_attr "mode" "DF")])
22600
22601 (define_insn "divv2df3"
22602   [(set (match_operand:V2DF 0 "register_operand" "=x")
22603         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22604                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22605   "TARGET_SSE2"
22606   "divpd\t{%2, %0|%0, %2}"
22607   [(set_attr "type" "ssediv")
22608    (set_attr "mode" "V2DF")])
22609
22610 (define_insn "vmdivv2df3"
22611   [(set (match_operand:V2DF 0 "register_operand" "=x")
22612         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22613                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22614                         (match_dup 1)
22615                         (const_int 1)))]
22616   "TARGET_SSE2"
22617   "divsd\t{%2, %0|%0, %2}"
22618   [(set_attr "type" "ssediv")
22619    (set_attr "mode" "DF")])
22620
22621 ;; SSE min/max
22622
22623 (define_insn "smaxv2df3"
22624   [(set (match_operand:V2DF 0 "register_operand" "=x")
22625         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22626                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22627   "TARGET_SSE2"
22628   "maxpd\t{%2, %0|%0, %2}"
22629   [(set_attr "type" "sseadd")
22630    (set_attr "mode" "V2DF")])
22631
22632 (define_insn "vmsmaxv2df3"
22633   [(set (match_operand:V2DF 0 "register_operand" "=x")
22634         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22635                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22636                         (match_dup 1)
22637                         (const_int 1)))]
22638   "TARGET_SSE2"
22639   "maxsd\t{%2, %0|%0, %2}"
22640   [(set_attr "type" "sseadd")
22641    (set_attr "mode" "DF")])
22642
22643 (define_insn "sminv2df3"
22644   [(set (match_operand:V2DF 0 "register_operand" "=x")
22645         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22646                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22647   "TARGET_SSE2"
22648   "minpd\t{%2, %0|%0, %2}"
22649   [(set_attr "type" "sseadd")
22650    (set_attr "mode" "V2DF")])
22651
22652 (define_insn "vmsminv2df3"
22653   [(set (match_operand:V2DF 0 "register_operand" "=x")
22654         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22655                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22656                         (match_dup 1)
22657                         (const_int 1)))]
22658   "TARGET_SSE2"
22659   "minsd\t{%2, %0|%0, %2}"
22660   [(set_attr "type" "sseadd")
22661    (set_attr "mode" "DF")])
22662 ;; SSE2 square root.  There doesn't appear to be an extension for the
22663 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22664
22665 (define_insn "sqrtv2df2"
22666   [(set (match_operand:V2DF 0 "register_operand" "=x")
22667         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22668   "TARGET_SSE2"
22669   "sqrtpd\t{%1, %0|%0, %1}"
22670   [(set_attr "type" "sse")
22671    (set_attr "mode" "V2DF")])
22672
22673 (define_insn "vmsqrtv2df2"
22674   [(set (match_operand:V2DF 0 "register_operand" "=x")
22675         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22676                         (match_operand:V2DF 2 "register_operand" "0")
22677                         (const_int 1)))]
22678   "TARGET_SSE2"
22679   "sqrtsd\t{%1, %0|%0, %1}"
22680   [(set_attr "type" "sse")
22681    (set_attr "mode" "SF")])
22682
22683 ;; SSE mask-generating compares
22684
22685 (define_insn "maskcmpv2df3"
22686   [(set (match_operand:V2DI 0 "register_operand" "=x")
22687         (match_operator:V2DI 3 "sse_comparison_operator"
22688                              [(match_operand:V2DF 1 "register_operand" "0")
22689                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22690   "TARGET_SSE2"
22691   "cmp%D3pd\t{%2, %0|%0, %2}"
22692   [(set_attr "type" "ssecmp")
22693    (set_attr "mode" "V2DF")])
22694
22695 (define_insn "maskncmpv2df3"
22696   [(set (match_operand:V2DI 0 "register_operand" "=x")
22697         (not:V2DI
22698          (match_operator:V2DI 3 "sse_comparison_operator"
22699                               [(match_operand:V2DF 1 "register_operand" "0")
22700                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22701   "TARGET_SSE2"
22702 {
22703   if (GET_CODE (operands[3]) == UNORDERED)
22704     return "cmpordps\t{%2, %0|%0, %2}";
22705   else
22706     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22707 }
22708   [(set_attr "type" "ssecmp")
22709    (set_attr "mode" "V2DF")])
22710
22711 (define_insn "vmmaskcmpv2df3"
22712   [(set (match_operand:V2DI 0 "register_operand" "=x")
22713         (vec_merge:V2DI
22714          (match_operator:V2DI 3 "sse_comparison_operator"
22715                               [(match_operand:V2DF 1 "register_operand" "0")
22716                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22717          (subreg:V2DI (match_dup 1) 0)
22718          (const_int 1)))]
22719   "TARGET_SSE2"
22720   "cmp%D3sd\t{%2, %0|%0, %2}"
22721   [(set_attr "type" "ssecmp")
22722    (set_attr "mode" "DF")])
22723
22724 (define_insn "vmmaskncmpv2df3"
22725   [(set (match_operand:V2DI 0 "register_operand" "=x")
22726         (vec_merge:V2DI
22727          (not:V2DI
22728           (match_operator:V2DI 3 "sse_comparison_operator"
22729                                [(match_operand:V2DF 1 "register_operand" "0")
22730                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22731          (subreg:V2DI (match_dup 1) 0)
22732          (const_int 1)))]
22733   "TARGET_SSE2"
22734 {
22735   if (GET_CODE (operands[3]) == UNORDERED)
22736     return "cmpordsd\t{%2, %0|%0, %2}";
22737   else
22738     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22739 }
22740   [(set_attr "type" "ssecmp")
22741    (set_attr "mode" "DF")])
22742
22743 (define_insn "sse2_comi"
22744   [(set (reg:CCFP FLAGS_REG)
22745         (compare:CCFP (vec_select:DF
22746                        (match_operand:V2DF 0 "register_operand" "x")
22747                        (parallel [(const_int 0)]))
22748                       (vec_select:DF
22749                        (match_operand:V2DF 1 "register_operand" "x")
22750                        (parallel [(const_int 0)]))))]
22751   "TARGET_SSE2"
22752   "comisd\t{%1, %0|%0, %1}"
22753   [(set_attr "type" "ssecomi")
22754    (set_attr "mode" "DF")])
22755
22756 (define_insn "sse2_ucomi"
22757   [(set (reg:CCFPU FLAGS_REG)
22758         (compare:CCFPU (vec_select:DF
22759                          (match_operand:V2DF 0 "register_operand" "x")
22760                          (parallel [(const_int 0)]))
22761                         (vec_select:DF
22762                          (match_operand:V2DF 1 "register_operand" "x")
22763                          (parallel [(const_int 0)]))))]
22764   "TARGET_SSE2"
22765   "ucomisd\t{%1, %0|%0, %1}"
22766   [(set_attr "type" "ssecomi")
22767    (set_attr "mode" "DF")])
22768
22769 ;; SSE Strange Moves.
22770
22771 (define_insn "sse2_movmskpd"
22772   [(set (match_operand:SI 0 "register_operand" "=r")
22773         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22774                    UNSPEC_MOVMSK))]
22775   "TARGET_SSE2"
22776   "movmskpd\t{%1, %0|%0, %1}"
22777   [(set_attr "type" "ssecvt")
22778    (set_attr "mode" "V2DF")])
22779
22780 (define_insn "sse2_pmovmskb"
22781   [(set (match_operand:SI 0 "register_operand" "=r")
22782         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22783                    UNSPEC_MOVMSK))]
22784   "TARGET_SSE2"
22785   "pmovmskb\t{%1, %0|%0, %1}"
22786   [(set_attr "type" "ssecvt")
22787    (set_attr "mode" "V2DF")])
22788
22789 (define_insn "sse2_maskmovdqu"
22790   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22791         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22792                        (match_operand:V16QI 2 "register_operand" "x")]
22793                       UNSPEC_MASKMOV))]
22794   "TARGET_SSE2"
22795   ;; @@@ check ordering of operands in intel/nonintel syntax
22796   "maskmovdqu\t{%2, %1|%1, %2}"
22797   [(set_attr "type" "ssecvt")
22798    (set_attr "mode" "TI")])
22799
22800 (define_insn "sse2_maskmovdqu_rex64"
22801   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22802         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22803                        (match_operand:V16QI 2 "register_operand" "x")]
22804                       UNSPEC_MASKMOV))]
22805   "TARGET_SSE2"
22806   ;; @@@ check ordering of operands in intel/nonintel syntax
22807   "maskmovdqu\t{%2, %1|%1, %2}"
22808   [(set_attr "type" "ssecvt")
22809    (set_attr "mode" "TI")])
22810
22811 (define_insn "sse2_movntv2df"
22812   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22813         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22814                      UNSPEC_MOVNT))]
22815   "TARGET_SSE2"
22816   "movntpd\t{%1, %0|%0, %1}"
22817   [(set_attr "type" "ssecvt")
22818    (set_attr "mode" "V2DF")])
22819
22820 (define_insn "sse2_movntv2di"
22821   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22822         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22823                      UNSPEC_MOVNT))]
22824   "TARGET_SSE2"
22825   "movntdq\t{%1, %0|%0, %1}"
22826   [(set_attr "type" "ssecvt")
22827    (set_attr "mode" "TI")])
22828
22829 (define_insn "sse2_movntsi"
22830   [(set (match_operand:SI 0 "memory_operand" "=m")
22831         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22832                    UNSPEC_MOVNT))]
22833   "TARGET_SSE2"
22834   "movnti\t{%1, %0|%0, %1}"
22835   [(set_attr "type" "ssecvt")
22836    (set_attr "mode" "V2DF")])
22837
22838 ;; SSE <-> integer/MMX conversions
22839
22840 ;; Conversions between SI and SF
22841
22842 (define_insn "cvtdq2ps"
22843   [(set (match_operand:V4SF 0 "register_operand" "=x")
22844         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22845   "TARGET_SSE2"
22846   "cvtdq2ps\t{%1, %0|%0, %1}"
22847   [(set_attr "type" "ssecvt")
22848    (set_attr "mode" "V2DF")])
22849
22850 (define_insn "cvtps2dq"
22851   [(set (match_operand:V4SI 0 "register_operand" "=x")
22852         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22853   "TARGET_SSE2"
22854   "cvtps2dq\t{%1, %0|%0, %1}"
22855   [(set_attr "type" "ssecvt")
22856    (set_attr "mode" "TI")])
22857
22858 (define_insn "cvttps2dq"
22859   [(set (match_operand:V4SI 0 "register_operand" "=x")
22860         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22861                      UNSPEC_FIX))]
22862   "TARGET_SSE2"
22863   "cvttps2dq\t{%1, %0|%0, %1}"
22864   [(set_attr "type" "ssecvt")
22865    (set_attr "mode" "TI")])
22866
22867 ;; Conversions between SI and DF
22868
22869 (define_insn "cvtdq2pd"
22870   [(set (match_operand:V2DF 0 "register_operand" "=x")
22871         (float:V2DF (vec_select:V2SI
22872                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22873                      (parallel
22874                       [(const_int 0)
22875                        (const_int 1)]))))]
22876   "TARGET_SSE2"
22877   "cvtdq2pd\t{%1, %0|%0, %1}"
22878   [(set_attr "type" "ssecvt")
22879    (set_attr "mode" "V2DF")])
22880
22881 (define_insn "cvtpd2dq"
22882   [(set (match_operand:V4SI 0 "register_operand" "=x")
22883         (vec_concat:V4SI
22884          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22885          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22886   "TARGET_SSE2"
22887   "cvtpd2dq\t{%1, %0|%0, %1}"
22888   [(set_attr "type" "ssecvt")
22889    (set_attr "mode" "TI")])
22890
22891 (define_insn "cvttpd2dq"
22892   [(set (match_operand:V4SI 0 "register_operand" "=x")
22893         (vec_concat:V4SI
22894          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22895                       UNSPEC_FIX)
22896          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22897   "TARGET_SSE2"
22898   "cvttpd2dq\t{%1, %0|%0, %1}"
22899   [(set_attr "type" "ssecvt")
22900    (set_attr "mode" "TI")])
22901
22902 (define_insn "cvtpd2pi"
22903   [(set (match_operand:V2SI 0 "register_operand" "=y")
22904         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22905   "TARGET_SSE2"
22906   "cvtpd2pi\t{%1, %0|%0, %1}"
22907   [(set_attr "type" "ssecvt")
22908    (set_attr "mode" "TI")])
22909
22910 (define_insn "cvttpd2pi"
22911   [(set (match_operand:V2SI 0 "register_operand" "=y")
22912         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22913                      UNSPEC_FIX))]
22914   "TARGET_SSE2"
22915   "cvttpd2pi\t{%1, %0|%0, %1}"
22916   [(set_attr "type" "ssecvt")
22917    (set_attr "mode" "TI")])
22918
22919 (define_insn "cvtpi2pd"
22920   [(set (match_operand:V2DF 0 "register_operand" "=x")
22921         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22922   "TARGET_SSE2"
22923   "cvtpi2pd\t{%1, %0|%0, %1}"
22924   [(set_attr "type" "ssecvt")
22925    (set_attr "mode" "TI")])
22926
22927 ;; Conversions between SI and DF
22928
22929 (define_insn "cvtsd2si"
22930   [(set (match_operand:SI 0 "register_operand" "=r,r")
22931         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22932                                (parallel [(const_int 0)]))))]
22933   "TARGET_SSE2"
22934   "cvtsd2si\t{%1, %0|%0, %1}"
22935   [(set_attr "type" "sseicvt")
22936    (set_attr "athlon_decode" "double,vector")
22937    (set_attr "mode" "SI")])
22938
22939 (define_insn "cvtsd2siq"
22940   [(set (match_operand:DI 0 "register_operand" "=r,r")
22941         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22942                                (parallel [(const_int 0)]))))]
22943   "TARGET_SSE2 && TARGET_64BIT"
22944   "cvtsd2siq\t{%1, %0|%0, %1}"
22945   [(set_attr "type" "sseicvt")
22946    (set_attr "athlon_decode" "double,vector")
22947    (set_attr "mode" "DI")])
22948
22949 (define_insn "cvttsd2si"
22950   [(set (match_operand:SI 0 "register_operand" "=r,r")
22951         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22952                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22953   "TARGET_SSE2"
22954   "cvttsd2si\t{%1, %0|%0, %1}"
22955   [(set_attr "type" "sseicvt")
22956    (set_attr "mode" "SI")
22957    (set_attr "athlon_decode" "double,vector")])
22958
22959 (define_insn "cvttsd2siq"
22960   [(set (match_operand:DI 0 "register_operand" "=r,r")
22961         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22962                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22963   "TARGET_SSE2 && TARGET_64BIT"
22964   "cvttsd2siq\t{%1, %0|%0, %1}"
22965   [(set_attr "type" "sseicvt")
22966    (set_attr "mode" "DI")
22967    (set_attr "athlon_decode" "double,vector")])
22968
22969 (define_insn "cvtsi2sd"
22970   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22971         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22972                         (vec_duplicate:V2DF
22973                           (float:DF
22974                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22975                         (const_int 2)))]
22976   "TARGET_SSE2"
22977   "cvtsi2sd\t{%2, %0|%0, %2}"
22978   [(set_attr "type" "sseicvt")
22979    (set_attr "mode" "DF")
22980    (set_attr "athlon_decode" "double,direct")])
22981
22982 (define_insn "cvtsi2sdq"
22983   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22984         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22985                         (vec_duplicate:V2DF
22986                           (float:DF
22987                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22988                         (const_int 2)))]
22989   "TARGET_SSE2 && TARGET_64BIT"
22990   "cvtsi2sdq\t{%2, %0|%0, %2}"
22991   [(set_attr "type" "sseicvt")
22992    (set_attr "mode" "DF")
22993    (set_attr "athlon_decode" "double,direct")])
22994
22995 ;; Conversions between SF and DF
22996
22997 (define_insn "cvtsd2ss"
22998   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22999         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23000                         (vec_duplicate:V4SF
23001                           (float_truncate:V2SF
23002                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23003                         (const_int 14)))]
23004   "TARGET_SSE2"
23005   "cvtsd2ss\t{%2, %0|%0, %2}"
23006   [(set_attr "type" "ssecvt")
23007    (set_attr "athlon_decode" "vector,double")
23008    (set_attr "mode" "SF")])
23009
23010 (define_insn "cvtss2sd"
23011   [(set (match_operand:V2DF 0 "register_operand" "=x")
23012         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23013                         (float_extend:V2DF
23014                           (vec_select:V2SF
23015                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23016                             (parallel [(const_int 0)
23017                                        (const_int 1)])))
23018                         (const_int 2)))]
23019   "TARGET_SSE2"
23020   "cvtss2sd\t{%2, %0|%0, %2}"
23021   [(set_attr "type" "ssecvt")
23022    (set_attr "mode" "DF")])
23023
23024 (define_insn "cvtpd2ps"
23025   [(set (match_operand:V4SF 0 "register_operand" "=x")
23026         (subreg:V4SF
23027           (vec_concat:V4SI
23028             (subreg:V2SI (float_truncate:V2SF
23029                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23030             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23031   "TARGET_SSE2"
23032   "cvtpd2ps\t{%1, %0|%0, %1}"
23033   [(set_attr "type" "ssecvt")
23034    (set_attr "mode" "V4SF")])
23035
23036 (define_insn "cvtps2pd"
23037   [(set (match_operand:V2DF 0 "register_operand" "=x")
23038         (float_extend:V2DF
23039           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23040                            (parallel [(const_int 0)
23041                                       (const_int 1)]))))]
23042   "TARGET_SSE2"
23043   "cvtps2pd\t{%1, %0|%0, %1}"
23044   [(set_attr "type" "ssecvt")
23045    (set_attr "mode" "V2DF")])
23046
23047 ;; SSE2 variants of MMX insns
23048
23049 ;; MMX arithmetic
23050
23051 (define_insn "addv16qi3"
23052   [(set (match_operand:V16QI 0 "register_operand" "=x")
23053         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23054                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23055   "TARGET_SSE2"
23056   "paddb\t{%2, %0|%0, %2}"
23057   [(set_attr "type" "sseiadd")
23058    (set_attr "mode" "TI")])
23059
23060 (define_insn "addv8hi3"
23061   [(set (match_operand:V8HI 0 "register_operand" "=x")
23062         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23063                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23064   "TARGET_SSE2"
23065   "paddw\t{%2, %0|%0, %2}"
23066   [(set_attr "type" "sseiadd")
23067    (set_attr "mode" "TI")])
23068
23069 (define_insn "addv4si3"
23070   [(set (match_operand:V4SI 0 "register_operand" "=x")
23071         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23072                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23073   "TARGET_SSE2"
23074   "paddd\t{%2, %0|%0, %2}"
23075   [(set_attr "type" "sseiadd")
23076    (set_attr "mode" "TI")])
23077
23078 (define_insn "addv2di3"
23079   [(set (match_operand:V2DI 0 "register_operand" "=x")
23080         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23081                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23082   "TARGET_SSE2"
23083   "paddq\t{%2, %0|%0, %2}"
23084   [(set_attr "type" "sseiadd")
23085    (set_attr "mode" "TI")])
23086
23087 (define_insn "ssaddv16qi3"
23088   [(set (match_operand:V16QI 0 "register_operand" "=x")
23089         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23090                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23091   "TARGET_SSE2"
23092   "paddsb\t{%2, %0|%0, %2}"
23093   [(set_attr "type" "sseiadd")
23094    (set_attr "mode" "TI")])
23095
23096 (define_insn "ssaddv8hi3"
23097   [(set (match_operand:V8HI 0 "register_operand" "=x")
23098         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23099                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23100   "TARGET_SSE2"
23101   "paddsw\t{%2, %0|%0, %2}"
23102   [(set_attr "type" "sseiadd")
23103    (set_attr "mode" "TI")])
23104
23105 (define_insn "usaddv16qi3"
23106   [(set (match_operand:V16QI 0 "register_operand" "=x")
23107         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23108                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23109   "TARGET_SSE2"
23110   "paddusb\t{%2, %0|%0, %2}"
23111   [(set_attr "type" "sseiadd")
23112    (set_attr "mode" "TI")])
23113
23114 (define_insn "usaddv8hi3"
23115   [(set (match_operand:V8HI 0 "register_operand" "=x")
23116         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23117                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23118   "TARGET_SSE2"
23119   "paddusw\t{%2, %0|%0, %2}"
23120   [(set_attr "type" "sseiadd")
23121    (set_attr "mode" "TI")])
23122
23123 (define_insn "subv16qi3"
23124   [(set (match_operand:V16QI 0 "register_operand" "=x")
23125         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23126                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23127   "TARGET_SSE2"
23128   "psubb\t{%2, %0|%0, %2}"
23129   [(set_attr "type" "sseiadd")
23130    (set_attr "mode" "TI")])
23131
23132 (define_insn "subv8hi3"
23133   [(set (match_operand:V8HI 0 "register_operand" "=x")
23134         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23135                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23136   "TARGET_SSE2"
23137   "psubw\t{%2, %0|%0, %2}"
23138   [(set_attr "type" "sseiadd")
23139    (set_attr "mode" "TI")])
23140
23141 (define_insn "subv4si3"
23142   [(set (match_operand:V4SI 0 "register_operand" "=x")
23143         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23144                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23145   "TARGET_SSE2"
23146   "psubd\t{%2, %0|%0, %2}"
23147   [(set_attr "type" "sseiadd")
23148    (set_attr "mode" "TI")])
23149
23150 (define_insn "subv2di3"
23151   [(set (match_operand:V2DI 0 "register_operand" "=x")
23152         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23153                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23154   "TARGET_SSE2"
23155   "psubq\t{%2, %0|%0, %2}"
23156   [(set_attr "type" "sseiadd")
23157    (set_attr "mode" "TI")])
23158
23159 (define_insn "sssubv16qi3"
23160   [(set (match_operand:V16QI 0 "register_operand" "=x")
23161         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23162                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23163   "TARGET_SSE2"
23164   "psubsb\t{%2, %0|%0, %2}"
23165   [(set_attr "type" "sseiadd")
23166    (set_attr "mode" "TI")])
23167
23168 (define_insn "sssubv8hi3"
23169   [(set (match_operand:V8HI 0 "register_operand" "=x")
23170         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23171                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23172   "TARGET_SSE2"
23173   "psubsw\t{%2, %0|%0, %2}"
23174   [(set_attr "type" "sseiadd")
23175    (set_attr "mode" "TI")])
23176
23177 (define_insn "ussubv16qi3"
23178   [(set (match_operand:V16QI 0 "register_operand" "=x")
23179         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23180                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23181   "TARGET_SSE2"
23182   "psubusb\t{%2, %0|%0, %2}"
23183   [(set_attr "type" "sseiadd")
23184    (set_attr "mode" "TI")])
23185
23186 (define_insn "ussubv8hi3"
23187   [(set (match_operand:V8HI 0 "register_operand" "=x")
23188         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23189                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23190   "TARGET_SSE2"
23191   "psubusw\t{%2, %0|%0, %2}"
23192   [(set_attr "type" "sseiadd")
23193    (set_attr "mode" "TI")])
23194
23195 (define_insn "mulv8hi3"
23196   [(set (match_operand:V8HI 0 "register_operand" "=x")
23197         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23198                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23199   "TARGET_SSE2"
23200   "pmullw\t{%2, %0|%0, %2}"
23201   [(set_attr "type" "sseimul")
23202    (set_attr "mode" "TI")])
23203
23204 (define_insn "smulv8hi3_highpart"
23205   [(set (match_operand:V8HI 0 "register_operand" "=x")
23206         (truncate:V8HI
23207          (lshiftrt:V8SI
23208           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23209                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23210           (const_int 16))))]
23211   "TARGET_SSE2"
23212   "pmulhw\t{%2, %0|%0, %2}"
23213   [(set_attr "type" "sseimul")
23214    (set_attr "mode" "TI")])
23215
23216 (define_insn "umulv8hi3_highpart"
23217   [(set (match_operand:V8HI 0 "register_operand" "=x")
23218         (truncate:V8HI
23219          (lshiftrt:V8SI
23220           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23221                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23222           (const_int 16))))]
23223   "TARGET_SSE2"
23224   "pmulhuw\t{%2, %0|%0, %2}"
23225   [(set_attr "type" "sseimul")
23226    (set_attr "mode" "TI")])
23227
23228 (define_insn "sse2_umulsidi3"
23229   [(set (match_operand:DI 0 "register_operand" "=y")
23230         (mult:DI (zero_extend:DI (vec_select:SI
23231                                   (match_operand:V2SI 1 "register_operand" "0")
23232                                   (parallel [(const_int 0)])))
23233                  (zero_extend:DI (vec_select:SI
23234                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23235                                   (parallel [(const_int 0)])))))]
23236   "TARGET_SSE2"
23237   "pmuludq\t{%2, %0|%0, %2}"
23238   [(set_attr "type" "mmxmul")
23239    (set_attr "mode" "DI")])
23240
23241 (define_insn "sse2_umulv2siv2di3"
23242   [(set (match_operand:V2DI 0 "register_operand" "=x")
23243         (mult:V2DI (zero_extend:V2DI
23244                      (vec_select:V2SI
23245                        (match_operand:V4SI 1 "register_operand" "0")
23246                        (parallel [(const_int 0) (const_int 2)])))
23247                    (zero_extend:V2DI
23248                      (vec_select:V2SI
23249                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23250                        (parallel [(const_int 0) (const_int 2)])))))]
23251   "TARGET_SSE2"
23252   "pmuludq\t{%2, %0|%0, %2}"
23253   [(set_attr "type" "sseimul")
23254    (set_attr "mode" "TI")])
23255
23256 (define_insn "sse2_pmaddwd"
23257   [(set (match_operand:V4SI 0 "register_operand" "=x")
23258         (plus:V4SI
23259          (mult:V4SI
23260           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23261                                              (parallel [(const_int 0)
23262                                                         (const_int 2)
23263                                                         (const_int 4)
23264                                                         (const_int 6)])))
23265           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23266                                              (parallel [(const_int 0)
23267                                                         (const_int 2)
23268                                                         (const_int 4)
23269                                                         (const_int 6)]))))
23270          (mult:V4SI
23271           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23272                                              (parallel [(const_int 1)
23273                                                         (const_int 3)
23274                                                         (const_int 5)
23275                                                         (const_int 7)])))
23276           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23277                                              (parallel [(const_int 1)
23278                                                         (const_int 3)
23279                                                         (const_int 5)
23280                                                         (const_int 7)]))))))]
23281   "TARGET_SSE2"
23282   "pmaddwd\t{%2, %0|%0, %2}"
23283   [(set_attr "type" "sseiadd")
23284    (set_attr "mode" "TI")])
23285
23286 ;; Same as pxor, but don't show input operands so that we don't think
23287 ;; they are live.
23288 (define_insn "sse2_clrti"
23289   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23290   "TARGET_SSE2"
23291 {
23292   if (get_attr_mode (insn) == MODE_TI)
23293     return "pxor\t%0, %0";
23294   else
23295     return "xorps\t%0, %0";
23296 }
23297   [(set_attr "type" "ssemov")
23298    (set_attr "memory" "none")
23299    (set (attr "mode")
23300               (if_then_else
23301                 (ne (symbol_ref "optimize_size")
23302                     (const_int 0))
23303                 (const_string "V4SF")
23304                 (const_string "TI")))])
23305
23306 ;; MMX unsigned averages/sum of absolute differences
23307
23308 (define_insn "sse2_uavgv16qi3"
23309   [(set (match_operand:V16QI 0 "register_operand" "=x")
23310         (ashiftrt:V16QI
23311          (plus:V16QI (plus:V16QI
23312                      (match_operand:V16QI 1 "register_operand" "0")
23313                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23314                      (const_vector:V16QI [(const_int 1) (const_int 1)
23315                                           (const_int 1) (const_int 1)
23316                                           (const_int 1) (const_int 1)
23317                                           (const_int 1) (const_int 1)
23318                                           (const_int 1) (const_int 1)
23319                                           (const_int 1) (const_int 1)
23320                                           (const_int 1) (const_int 1)
23321                                           (const_int 1) (const_int 1)]))
23322          (const_int 1)))]
23323   "TARGET_SSE2"
23324   "pavgb\t{%2, %0|%0, %2}"
23325   [(set_attr "type" "sseiadd")
23326    (set_attr "mode" "TI")])
23327
23328 (define_insn "sse2_uavgv8hi3"
23329   [(set (match_operand:V8HI 0 "register_operand" "=x")
23330         (ashiftrt:V8HI
23331          (plus:V8HI (plus:V8HI
23332                      (match_operand:V8HI 1 "register_operand" "0")
23333                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23334                     (const_vector:V8HI [(const_int 1) (const_int 1)
23335                                         (const_int 1) (const_int 1)
23336                                         (const_int 1) (const_int 1)
23337                                         (const_int 1) (const_int 1)]))
23338          (const_int 1)))]
23339   "TARGET_SSE2"
23340   "pavgw\t{%2, %0|%0, %2}"
23341   [(set_attr "type" "sseiadd")
23342    (set_attr "mode" "TI")])
23343
23344 ;; @@@ this isn't the right representation.
23345 (define_insn "sse2_psadbw"
23346   [(set (match_operand:V2DI 0 "register_operand" "=x")
23347         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23348                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23349                      UNSPEC_PSADBW))]
23350   "TARGET_SSE2"
23351   "psadbw\t{%2, %0|%0, %2}"
23352   [(set_attr "type" "sseiadd")
23353    (set_attr "mode" "TI")])
23354
23355
23356 ;; MMX insert/extract/shuffle
23357
23358 (define_insn "sse2_pinsrw"
23359   [(set (match_operand:V8HI 0 "register_operand" "=x")
23360         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23361                         (vec_duplicate:V8HI
23362                          (truncate:HI
23363                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23364                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23365   "TARGET_SSE2"
23366   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23367   [(set_attr "type" "ssecvt")
23368    (set_attr "mode" "TI")])
23369
23370 (define_insn "sse2_pextrw"
23371   [(set (match_operand:SI 0 "register_operand" "=r")
23372         (zero_extend:SI
23373           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23374                          (parallel
23375                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23376   "TARGET_SSE2"
23377   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23378   [(set_attr "type" "ssecvt")
23379    (set_attr "mode" "TI")])
23380
23381 (define_insn "sse2_pshufd"
23382   [(set (match_operand:V4SI 0 "register_operand" "=x")
23383         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23384                       (match_operand:SI 2 "immediate_operand" "i")]
23385                      UNSPEC_SHUFFLE))]
23386   "TARGET_SSE2"
23387   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23388   [(set_attr "type" "ssecvt")
23389    (set_attr "mode" "TI")])
23390
23391 (define_insn "sse2_pshuflw"
23392   [(set (match_operand:V8HI 0 "register_operand" "=x")
23393         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23394                       (match_operand:SI 2 "immediate_operand" "i")]
23395                      UNSPEC_PSHUFLW))]
23396   "TARGET_SSE2"
23397   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23398   [(set_attr "type" "ssecvt")
23399    (set_attr "mode" "TI")])
23400
23401 (define_insn "sse2_pshufhw"
23402   [(set (match_operand:V8HI 0 "register_operand" "=x")
23403         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23404                       (match_operand:SI 2 "immediate_operand" "i")]
23405                      UNSPEC_PSHUFHW))]
23406   "TARGET_SSE2"
23407   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23408   [(set_attr "type" "ssecvt")
23409    (set_attr "mode" "TI")])
23410
23411 ;; MMX mask-generating comparisons
23412
23413 (define_insn "eqv16qi3"
23414   [(set (match_operand:V16QI 0 "register_operand" "=x")
23415         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23416                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23417   "TARGET_SSE2"
23418   "pcmpeqb\t{%2, %0|%0, %2}"
23419   [(set_attr "type" "ssecmp")
23420    (set_attr "mode" "TI")])
23421
23422 (define_insn "eqv8hi3"
23423   [(set (match_operand:V8HI 0 "register_operand" "=x")
23424         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23425                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23426   "TARGET_SSE2"
23427   "pcmpeqw\t{%2, %0|%0, %2}"
23428   [(set_attr "type" "ssecmp")
23429    (set_attr "mode" "TI")])
23430
23431 (define_insn "eqv4si3"
23432   [(set (match_operand:V4SI 0 "register_operand" "=x")
23433         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23434                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23435   "TARGET_SSE2"
23436   "pcmpeqd\t{%2, %0|%0, %2}"
23437   [(set_attr "type" "ssecmp")
23438    (set_attr "mode" "TI")])
23439
23440 (define_insn "gtv16qi3"
23441   [(set (match_operand:V16QI 0 "register_operand" "=x")
23442         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23443                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23444   "TARGET_SSE2"
23445   "pcmpgtb\t{%2, %0|%0, %2}"
23446   [(set_attr "type" "ssecmp")
23447    (set_attr "mode" "TI")])
23448
23449 (define_insn "gtv8hi3"
23450   [(set (match_operand:V8HI 0 "register_operand" "=x")
23451         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23452                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23453   "TARGET_SSE2"
23454   "pcmpgtw\t{%2, %0|%0, %2}"
23455   [(set_attr "type" "ssecmp")
23456    (set_attr "mode" "TI")])
23457
23458 (define_insn "gtv4si3"
23459   [(set (match_operand:V4SI 0 "register_operand" "=x")
23460         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23461                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23462   "TARGET_SSE2"
23463   "pcmpgtd\t{%2, %0|%0, %2}"
23464   [(set_attr "type" "ssecmp")
23465    (set_attr "mode" "TI")])
23466
23467
23468 ;; MMX max/min insns
23469
23470 (define_insn "umaxv16qi3"
23471   [(set (match_operand:V16QI 0 "register_operand" "=x")
23472         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23473                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23474   "TARGET_SSE2"
23475   "pmaxub\t{%2, %0|%0, %2}"
23476   [(set_attr "type" "sseiadd")
23477    (set_attr "mode" "TI")])
23478
23479 (define_insn "smaxv8hi3"
23480   [(set (match_operand:V8HI 0 "register_operand" "=x")
23481         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23482                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23483   "TARGET_SSE2"
23484   "pmaxsw\t{%2, %0|%0, %2}"
23485   [(set_attr "type" "sseiadd")
23486    (set_attr "mode" "TI")])
23487
23488 (define_insn "uminv16qi3"
23489   [(set (match_operand:V16QI 0 "register_operand" "=x")
23490         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23491                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23492   "TARGET_SSE2"
23493   "pminub\t{%2, %0|%0, %2}"
23494   [(set_attr "type" "sseiadd")
23495    (set_attr "mode" "TI")])
23496
23497 (define_insn "sminv8hi3"
23498   [(set (match_operand:V8HI 0 "register_operand" "=x")
23499         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23500                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23501   "TARGET_SSE2"
23502   "pminsw\t{%2, %0|%0, %2}"
23503   [(set_attr "type" "sseiadd")
23504    (set_attr "mode" "TI")])
23505
23506
23507 ;; MMX shifts
23508
23509 (define_insn "ashrv8hi3"
23510   [(set (match_operand:V8HI 0 "register_operand" "=x")
23511         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23512                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23513   "TARGET_SSE2"
23514   "psraw\t{%2, %0|%0, %2}"
23515   [(set_attr "type" "sseishft")
23516    (set_attr "mode" "TI")])
23517
23518 (define_insn "ashrv4si3"
23519   [(set (match_operand:V4SI 0 "register_operand" "=x")
23520         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23521                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23522   "TARGET_SSE2"
23523   "psrad\t{%2, %0|%0, %2}"
23524   [(set_attr "type" "sseishft")
23525    (set_attr "mode" "TI")])
23526
23527 (define_insn "lshrv8hi3"
23528   [(set (match_operand:V8HI 0 "register_operand" "=x")
23529         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23530                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23531   "TARGET_SSE2"
23532   "psrlw\t{%2, %0|%0, %2}"
23533   [(set_attr "type" "sseishft")
23534    (set_attr "mode" "TI")])
23535
23536 (define_insn "lshrv4si3"
23537   [(set (match_operand:V4SI 0 "register_operand" "=x")
23538         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23539                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23540   "TARGET_SSE2"
23541   "psrld\t{%2, %0|%0, %2}"
23542   [(set_attr "type" "sseishft")
23543    (set_attr "mode" "TI")])
23544
23545 (define_insn "lshrv2di3"
23546   [(set (match_operand:V2DI 0 "register_operand" "=x")
23547         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23548                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23549   "TARGET_SSE2"
23550   "psrlq\t{%2, %0|%0, %2}"
23551   [(set_attr "type" "sseishft")
23552    (set_attr "mode" "TI")])
23553
23554 (define_insn "ashlv8hi3"
23555   [(set (match_operand:V8HI 0 "register_operand" "=x")
23556         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23557                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23558   "TARGET_SSE2"
23559   "psllw\t{%2, %0|%0, %2}"
23560   [(set_attr "type" "sseishft")
23561    (set_attr "mode" "TI")])
23562
23563 (define_insn "ashlv4si3"
23564   [(set (match_operand:V4SI 0 "register_operand" "=x")
23565         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23566                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23567   "TARGET_SSE2"
23568   "pslld\t{%2, %0|%0, %2}"
23569   [(set_attr "type" "sseishft")
23570    (set_attr "mode" "TI")])
23571
23572 (define_insn "ashlv2di3"
23573   [(set (match_operand:V2DI 0 "register_operand" "=x")
23574         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23575                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23576   "TARGET_SSE2"
23577   "psllq\t{%2, %0|%0, %2}"
23578   [(set_attr "type" "sseishft")
23579    (set_attr "mode" "TI")])
23580
23581 (define_insn "ashrv8hi3_ti"
23582   [(set (match_operand:V8HI 0 "register_operand" "=x")
23583         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23584                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23585   "TARGET_SSE2"
23586   "psraw\t{%2, %0|%0, %2}"
23587   [(set_attr "type" "sseishft")
23588    (set_attr "mode" "TI")])
23589
23590 (define_insn "ashrv4si3_ti"
23591   [(set (match_operand:V4SI 0 "register_operand" "=x")
23592         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23593                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23594   "TARGET_SSE2"
23595   "psrad\t{%2, %0|%0, %2}"
23596   [(set_attr "type" "sseishft")
23597    (set_attr "mode" "TI")])
23598
23599 (define_insn "lshrv8hi3_ti"
23600   [(set (match_operand:V8HI 0 "register_operand" "=x")
23601         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23602                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23603   "TARGET_SSE2"
23604   "psrlw\t{%2, %0|%0, %2}"
23605   [(set_attr "type" "sseishft")
23606    (set_attr "mode" "TI")])
23607
23608 (define_insn "lshrv4si3_ti"
23609   [(set (match_operand:V4SI 0 "register_operand" "=x")
23610         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23611                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23612   "TARGET_SSE2"
23613   "psrld\t{%2, %0|%0, %2}"
23614   [(set_attr "type" "sseishft")
23615    (set_attr "mode" "TI")])
23616
23617 (define_insn "lshrv2di3_ti"
23618   [(set (match_operand:V2DI 0 "register_operand" "=x")
23619         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23620                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23621   "TARGET_SSE2"
23622   "psrlq\t{%2, %0|%0, %2}"
23623   [(set_attr "type" "sseishft")
23624    (set_attr "mode" "TI")])
23625
23626 (define_insn "ashlv8hi3_ti"
23627   [(set (match_operand:V8HI 0 "register_operand" "=x")
23628         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23629                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23630   "TARGET_SSE2"
23631   "psllw\t{%2, %0|%0, %2}"
23632   [(set_attr "type" "sseishft")
23633    (set_attr "mode" "TI")])
23634
23635 (define_insn "ashlv4si3_ti"
23636   [(set (match_operand:V4SI 0 "register_operand" "=x")
23637         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23638                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23639   "TARGET_SSE2"
23640   "pslld\t{%2, %0|%0, %2}"
23641   [(set_attr "type" "sseishft")
23642    (set_attr "mode" "TI")])
23643
23644 (define_insn "ashlv2di3_ti"
23645   [(set (match_operand:V2DI 0 "register_operand" "=x")
23646         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23647                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23648   "TARGET_SSE2"
23649   "psllq\t{%2, %0|%0, %2}"
23650   [(set_attr "type" "sseishft")
23651    (set_attr "mode" "TI")])
23652
23653 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23654 ;; we wouldn't need here it since we never generate TImode arithmetic.
23655
23656 ;; There has to be some kind of prize for the weirdest new instruction...
23657 (define_insn "sse2_ashlti3"
23658   [(set (match_operand:TI 0 "register_operand" "=x")
23659         (unspec:TI
23660          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23661                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23662                                (const_int 8)))] UNSPEC_NOP))]
23663   "TARGET_SSE2"
23664   "pslldq\t{%2, %0|%0, %2}"
23665   [(set_attr "type" "sseishft")
23666    (set_attr "mode" "TI")])
23667
23668 (define_insn "sse2_lshrti3"
23669   [(set (match_operand:TI 0 "register_operand" "=x")
23670         (unspec:TI
23671          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23672                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23673                                 (const_int 8)))] UNSPEC_NOP))]
23674   "TARGET_SSE2"
23675   "psrldq\t{%2, %0|%0, %2}"
23676   [(set_attr "type" "sseishft")
23677    (set_attr "mode" "TI")])
23678
23679 ;; SSE unpack
23680
23681 (define_insn "sse2_unpckhpd"
23682   [(set (match_operand:V2DF 0 "register_operand" "=x")
23683         (vec_concat:V2DF
23684          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23685                         (parallel [(const_int 1)]))
23686          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23687                         (parallel [(const_int 1)]))))]
23688   "TARGET_SSE2"
23689   "unpckhpd\t{%2, %0|%0, %2}"
23690   [(set_attr "type" "ssecvt")
23691    (set_attr "mode" "V2DF")])
23692
23693 (define_insn "sse2_unpcklpd"
23694   [(set (match_operand:V2DF 0 "register_operand" "=x")
23695         (vec_concat:V2DF
23696          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23697                         (parallel [(const_int 0)]))
23698          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23699                         (parallel [(const_int 0)]))))]
23700   "TARGET_SSE2"
23701   "unpcklpd\t{%2, %0|%0, %2}"
23702   [(set_attr "type" "ssecvt")
23703    (set_attr "mode" "V2DF")])
23704
23705 ;; MMX pack/unpack insns.
23706
23707 (define_insn "sse2_packsswb"
23708   [(set (match_operand:V16QI 0 "register_operand" "=x")
23709         (vec_concat:V16QI
23710          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23711          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23712   "TARGET_SSE2"
23713   "packsswb\t{%2, %0|%0, %2}"
23714   [(set_attr "type" "ssecvt")
23715    (set_attr "mode" "TI")])
23716
23717 (define_insn "sse2_packssdw"
23718   [(set (match_operand:V8HI 0 "register_operand" "=x")
23719         (vec_concat:V8HI
23720          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23721          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23722   "TARGET_SSE2"
23723   "packssdw\t{%2, %0|%0, %2}"
23724   [(set_attr "type" "ssecvt")
23725    (set_attr "mode" "TI")])
23726
23727 (define_insn "sse2_packuswb"
23728   [(set (match_operand:V16QI 0 "register_operand" "=x")
23729         (vec_concat:V16QI
23730          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23731          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23732   "TARGET_SSE2"
23733   "packuswb\t{%2, %0|%0, %2}"
23734   [(set_attr "type" "ssecvt")
23735    (set_attr "mode" "TI")])
23736
23737 (define_insn "sse2_punpckhbw"
23738   [(set (match_operand:V16QI 0 "register_operand" "=x")
23739         (vec_merge:V16QI
23740          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23741                            (parallel [(const_int 8) (const_int 0)
23742                                       (const_int 9) (const_int 1)
23743                                       (const_int 10) (const_int 2)
23744                                       (const_int 11) (const_int 3)
23745                                       (const_int 12) (const_int 4)
23746                                       (const_int 13) (const_int 5)
23747                                       (const_int 14) (const_int 6)
23748                                       (const_int 15) (const_int 7)]))
23749          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23750                            (parallel [(const_int 0) (const_int 8)
23751                                       (const_int 1) (const_int 9)
23752                                       (const_int 2) (const_int 10)
23753                                       (const_int 3) (const_int 11)
23754                                       (const_int 4) (const_int 12)
23755                                       (const_int 5) (const_int 13)
23756                                       (const_int 6) (const_int 14)
23757                                       (const_int 7) (const_int 15)]))
23758          (const_int 21845)))]
23759   "TARGET_SSE2"
23760   "punpckhbw\t{%2, %0|%0, %2}"
23761   [(set_attr "type" "ssecvt")
23762    (set_attr "mode" "TI")])
23763
23764 (define_insn "sse2_punpckhwd"
23765   [(set (match_operand:V8HI 0 "register_operand" "=x")
23766         (vec_merge:V8HI
23767          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23768                           (parallel [(const_int 4) (const_int 0)
23769                                      (const_int 5) (const_int 1)
23770                                      (const_int 6) (const_int 2)
23771                                      (const_int 7) (const_int 3)]))
23772          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23773                           (parallel [(const_int 0) (const_int 4)
23774                                      (const_int 1) (const_int 5)
23775                                      (const_int 2) (const_int 6)
23776                                      (const_int 3) (const_int 7)]))
23777          (const_int 85)))]
23778   "TARGET_SSE2"
23779   "punpckhwd\t{%2, %0|%0, %2}"
23780   [(set_attr "type" "ssecvt")
23781    (set_attr "mode" "TI")])
23782
23783 (define_insn "sse2_punpckhdq"
23784   [(set (match_operand:V4SI 0 "register_operand" "=x")
23785         (vec_merge:V4SI
23786          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23787                           (parallel [(const_int 2) (const_int 0)
23788                                      (const_int 3) (const_int 1)]))
23789          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23790                           (parallel [(const_int 0) (const_int 2)
23791                                      (const_int 1) (const_int 3)]))
23792          (const_int 5)))]
23793   "TARGET_SSE2"
23794   "punpckhdq\t{%2, %0|%0, %2}"
23795   [(set_attr "type" "ssecvt")
23796    (set_attr "mode" "TI")])
23797
23798 (define_insn "sse2_punpcklbw"
23799   [(set (match_operand:V16QI 0 "register_operand" "=x")
23800         (vec_merge:V16QI
23801          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23802                            (parallel [(const_int 0) (const_int 8)
23803                                       (const_int 1) (const_int 9)
23804                                       (const_int 2) (const_int 10)
23805                                       (const_int 3) (const_int 11)
23806                                       (const_int 4) (const_int 12)
23807                                       (const_int 5) (const_int 13)
23808                                       (const_int 6) (const_int 14)
23809                                       (const_int 7) (const_int 15)]))
23810          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23811                            (parallel [(const_int 8) (const_int 0)
23812                                       (const_int 9) (const_int 1)
23813                                       (const_int 10) (const_int 2)
23814                                       (const_int 11) (const_int 3)
23815                                       (const_int 12) (const_int 4)
23816                                       (const_int 13) (const_int 5)
23817                                       (const_int 14) (const_int 6)
23818                                       (const_int 15) (const_int 7)]))
23819          (const_int 21845)))]
23820   "TARGET_SSE2"
23821   "punpcklbw\t{%2, %0|%0, %2}"
23822   [(set_attr "type" "ssecvt")
23823    (set_attr "mode" "TI")])
23824
23825 (define_insn "sse2_punpcklwd"
23826   [(set (match_operand:V8HI 0 "register_operand" "=x")
23827         (vec_merge:V8HI
23828          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23829                           (parallel [(const_int 0) (const_int 4)
23830                                      (const_int 1) (const_int 5)
23831                                      (const_int 2) (const_int 6)
23832                                      (const_int 3) (const_int 7)]))
23833          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23834                           (parallel [(const_int 4) (const_int 0)
23835                                      (const_int 5) (const_int 1)
23836                                      (const_int 6) (const_int 2)
23837                                      (const_int 7) (const_int 3)]))
23838          (const_int 85)))]
23839   "TARGET_SSE2"
23840   "punpcklwd\t{%2, %0|%0, %2}"
23841   [(set_attr "type" "ssecvt")
23842    (set_attr "mode" "TI")])
23843
23844 (define_insn "sse2_punpckldq"
23845   [(set (match_operand:V4SI 0 "register_operand" "=x")
23846         (vec_merge:V4SI
23847          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23848                           (parallel [(const_int 0) (const_int 2)
23849                                      (const_int 1) (const_int 3)]))
23850          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23851                           (parallel [(const_int 2) (const_int 0)
23852                                      (const_int 3) (const_int 1)]))
23853          (const_int 5)))]
23854   "TARGET_SSE2"
23855   "punpckldq\t{%2, %0|%0, %2}"
23856   [(set_attr "type" "ssecvt")
23857    (set_attr "mode" "TI")])
23858
23859 (define_insn "sse2_punpcklqdq"
23860   [(set (match_operand:V2DI 0 "register_operand" "=x")
23861         (vec_merge:V2DI
23862          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23863                           (parallel [(const_int 1)
23864                                      (const_int 0)]))
23865          (match_operand:V2DI 1 "register_operand" "0")
23866          (const_int 1)))]
23867   "TARGET_SSE2"
23868   "punpcklqdq\t{%2, %0|%0, %2}"
23869   [(set_attr "type" "ssecvt")
23870    (set_attr "mode" "TI")])
23871
23872 (define_insn "sse2_punpckhqdq"
23873   [(set (match_operand:V2DI 0 "register_operand" "=x")
23874         (vec_merge:V2DI
23875          (match_operand:V2DI 1 "register_operand" "0")
23876          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23877                           (parallel [(const_int 1)
23878                                      (const_int 0)]))
23879          (const_int 1)))]
23880   "TARGET_SSE2"
23881   "punpckhqdq\t{%2, %0|%0, %2}"
23882   [(set_attr "type" "ssecvt")
23883    (set_attr "mode" "TI")])
23884
23885 ;; SSE2 moves
23886
23887 (define_insn "sse2_movapd"
23888   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23889         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23890                      UNSPEC_MOVA))]
23891   "TARGET_SSE2
23892    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23893   "movapd\t{%1, %0|%0, %1}"
23894   [(set_attr "type" "ssemov")
23895    (set_attr "mode" "V2DF")])
23896
23897 (define_insn "sse2_movupd"
23898   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23899         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23900                      UNSPEC_MOVU))]
23901   "TARGET_SSE2
23902    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23903   "movupd\t{%1, %0|%0, %1}"
23904   [(set_attr "type" "ssecvt")
23905    (set_attr "mode" "V2DF")])
23906
23907 (define_insn "sse2_movdqa"
23908   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23909         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23910                        UNSPEC_MOVA))]
23911   "TARGET_SSE2
23912    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23913   "movdqa\t{%1, %0|%0, %1}"
23914   [(set_attr "type" "ssemov")
23915    (set_attr "mode" "TI")])
23916
23917 (define_insn "sse2_movdqu"
23918   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23919         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23920                        UNSPEC_MOVU))]
23921   "TARGET_SSE2
23922    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23923   "movdqu\t{%1, %0|%0, %1}"
23924   [(set_attr "type" "ssecvt")
23925    (set_attr "mode" "TI")])
23926
23927 (define_insn "sse2_movdq2q"
23928   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23929         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23930                        (parallel [(const_int 0)])))]
23931   "TARGET_SSE2 && !TARGET_64BIT"
23932   "@
23933    movq\t{%1, %0|%0, %1}
23934    movdq2q\t{%1, %0|%0, %1}"
23935   [(set_attr "type" "ssecvt")
23936    (set_attr "mode" "TI")])
23937
23938 (define_insn "sse2_movdq2q_rex64"
23939   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23940         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23941                        (parallel [(const_int 0)])))]
23942   "TARGET_SSE2 && TARGET_64BIT"
23943   "@
23944    movq\t{%1, %0|%0, %1}
23945    movdq2q\t{%1, %0|%0, %1}
23946    movd\t{%1, %0|%0, %1}"
23947   [(set_attr "type" "ssecvt")
23948    (set_attr "mode" "TI")])
23949
23950 (define_insn "sse2_movq2dq"
23951   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23952         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23953                          (const_int 0)))]
23954   "TARGET_SSE2 && !TARGET_64BIT"
23955   "@
23956    movq\t{%1, %0|%0, %1}
23957    movq2dq\t{%1, %0|%0, %1}"
23958   [(set_attr "type" "ssecvt,ssemov")
23959    (set_attr "mode" "TI")])
23960
23961 (define_insn "sse2_movq2dq_rex64"
23962   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23963         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23964                          (const_int 0)))]
23965   "TARGET_SSE2 && TARGET_64BIT"
23966   "@
23967    movq\t{%1, %0|%0, %1}
23968    movq2dq\t{%1, %0|%0, %1}
23969    movd\t{%1, %0|%0, %1}"
23970   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23971    (set_attr "mode" "TI")])
23972
23973 (define_insn "sse2_movq"
23974   [(set (match_operand:V2DI 0 "register_operand" "=x")
23975         (vec_concat:V2DI (vec_select:DI
23976                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23977                           (parallel [(const_int 0)]))
23978                          (const_int 0)))]
23979   "TARGET_SSE2"
23980   "movq\t{%1, %0|%0, %1}"
23981   [(set_attr "type" "ssemov")
23982    (set_attr "mode" "TI")])
23983
23984 (define_insn "sse2_loadd"
23985   [(set (match_operand:V4SI 0 "register_operand" "=x")
23986         (vec_merge:V4SI
23987          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23988          (const_vector:V4SI [(const_int 0)
23989                              (const_int 0)
23990                              (const_int 0)
23991                              (const_int 0)])
23992          (const_int 1)))]
23993   "TARGET_SSE2"
23994   "movd\t{%1, %0|%0, %1}"
23995   [(set_attr "type" "ssemov")
23996    (set_attr "mode" "TI")])
23997
23998 (define_insn "sse2_stored"
23999   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24000         (vec_select:SI
24001          (match_operand:V4SI 1 "register_operand" "x")
24002          (parallel [(const_int 0)])))]
24003   "TARGET_SSE2"
24004   "movd\t{%1, %0|%0, %1}"
24005   [(set_attr "type" "ssemov")
24006    (set_attr "mode" "TI")])
24007
24008 (define_insn "sse2_movhpd"
24009   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24010         (vec_merge:V2DF
24011          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24012          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24013          (const_int 1)))]
24014   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24015   "movhpd\t{%2, %0|%0, %2}"
24016   [(set_attr "type" "ssecvt")
24017    (set_attr "mode" "V2DF")])
24018
24019 (define_expand "sse2_loadsd"
24020   [(match_operand:V2DF 0 "register_operand" "")
24021    (match_operand:DF 1 "memory_operand" "")]
24022   "TARGET_SSE2"
24023 {
24024   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24025                                 CONST0_RTX (V2DFmode)));
24026   DONE;
24027 })
24028
24029 (define_insn "sse2_loadsd_1"
24030   [(set (match_operand:V2DF 0 "register_operand" "=x")
24031         (vec_merge:V2DF
24032          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24033          (match_operand:V2DF 2 "const0_operand" "X")
24034          (const_int 1)))]
24035   "TARGET_SSE2"
24036   "movsd\t{%1, %0|%0, %1}"
24037   [(set_attr "type" "ssecvt")
24038    (set_attr "mode" "DF")])
24039
24040 (define_insn "sse2_movsd"
24041   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24042         (vec_merge:V2DF
24043          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24044          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24045          (const_int 2)))]
24046   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24047   "@movsd\t{%2, %0|%0, %2}
24048     movlpd\t{%2, %0|%0, %2}
24049     movlpd\t{%2, %0|%0, %2}"
24050   [(set_attr "type" "ssecvt")
24051    (set_attr "mode" "DF,V2DF,V2DF")])
24052
24053 (define_insn "sse2_storesd"
24054   [(set (match_operand:DF 0 "memory_operand" "=m")
24055         (vec_select:DF
24056          (match_operand:V2DF 1 "register_operand" "x")
24057          (parallel [(const_int 0)])))]
24058   "TARGET_SSE2"
24059   "movsd\t{%1, %0|%0, %1}"
24060   [(set_attr "type" "ssecvt")
24061    (set_attr "mode" "DF")])
24062
24063 (define_insn "sse2_shufpd"
24064   [(set (match_operand:V2DF 0 "register_operand" "=x")
24065         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24066                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24067                       (match_operand:SI 3 "immediate_operand" "i")]
24068                      UNSPEC_SHUFFLE))]
24069   "TARGET_SSE2"
24070   ;; @@@ check operand order for intel/nonintel syntax
24071   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24072   [(set_attr "type" "ssecvt")
24073    (set_attr "mode" "V2DF")])
24074
24075 (define_insn "sse2_clflush"
24076   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24077                     UNSPECV_CLFLUSH)]
24078   "TARGET_SSE2"
24079   "clflush\t%a0"
24080   [(set_attr "type" "sse")
24081    (set_attr "memory" "unknown")])
24082
24083 (define_expand "sse2_mfence"
24084   [(set (match_dup 0)
24085         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
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 "*mfence_insn"
24093   [(set (match_operand:BLK 0 "" "")
24094         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24095   "TARGET_SSE2"
24096   "mfence"
24097   [(set_attr "type" "sse")
24098    (set_attr "memory" "unknown")])
24099
24100 (define_expand "sse2_lfence"
24101   [(set (match_dup 0)
24102         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24103   "TARGET_SSE2"
24104 {
24105   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24106   MEM_VOLATILE_P (operands[0]) = 1;
24107 })
24108
24109 (define_insn "*lfence_insn"
24110   [(set (match_operand:BLK 0 "" "")
24111         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24112   "TARGET_SSE2"
24113   "lfence"
24114   [(set_attr "type" "sse")
24115    (set_attr "memory" "unknown")])
24116
24117 ;; SSE3
24118
24119 (define_insn "mwait"
24120   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24121                      (match_operand:SI 1 "register_operand" "c")]
24122                     UNSPECV_MWAIT)]
24123   "TARGET_SSE3"
24124   "mwait\t%0, %1"
24125   [(set_attr "length" "3")])
24126
24127 (define_insn "monitor"
24128   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24129                      (match_operand:SI 1 "register_operand" "c")
24130                      (match_operand:SI 2 "register_operand" "d")]
24131                     UNSPECV_MONITOR)]
24132   "TARGET_SSE3"
24133   "monitor\t%0, %1, %2"
24134   [(set_attr "length" "3")])
24135
24136 ;; SSE3 arithmetic
24137
24138 (define_insn "addsubv4sf3"
24139   [(set (match_operand:V4SF 0 "register_operand" "=x")
24140         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24141                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24142                      UNSPEC_ADDSUB))]
24143   "TARGET_SSE3"
24144   "addsubps\t{%2, %0|%0, %2}"
24145   [(set_attr "type" "sseadd")
24146    (set_attr "mode" "V4SF")])
24147
24148 (define_insn "addsubv2df3"
24149   [(set (match_operand:V2DF 0 "register_operand" "=x")
24150         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24151                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24152                      UNSPEC_ADDSUB))]
24153   "TARGET_SSE3"
24154   "addsubpd\t{%2, %0|%0, %2}"
24155   [(set_attr "type" "sseadd")
24156    (set_attr "mode" "V2DF")])
24157
24158 (define_insn "haddv4sf3"
24159   [(set (match_operand:V4SF 0 "register_operand" "=x")
24160         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24161                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24162                      UNSPEC_HADD))]
24163   "TARGET_SSE3"
24164   "haddps\t{%2, %0|%0, %2}"
24165   [(set_attr "type" "sseadd")
24166    (set_attr "mode" "V4SF")])
24167
24168 (define_insn "haddv2df3"
24169   [(set (match_operand:V2DF 0 "register_operand" "=x")
24170         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24171                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24172                      UNSPEC_HADD))]
24173   "TARGET_SSE3"
24174   "haddpd\t{%2, %0|%0, %2}"
24175   [(set_attr "type" "sseadd")
24176    (set_attr "mode" "V2DF")])
24177
24178 (define_insn "hsubv4sf3"
24179   [(set (match_operand:V4SF 0 "register_operand" "=x")
24180         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24181                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24182                      UNSPEC_HSUB))]
24183   "TARGET_SSE3"
24184   "hsubps\t{%2, %0|%0, %2}"
24185   [(set_attr "type" "sseadd")
24186    (set_attr "mode" "V4SF")])
24187
24188 (define_insn "hsubv2df3"
24189   [(set (match_operand:V2DF 0 "register_operand" "=x")
24190         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24191                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24192                      UNSPEC_HSUB))]
24193   "TARGET_SSE3"
24194   "hsubpd\t{%2, %0|%0, %2}"
24195   [(set_attr "type" "sseadd")
24196    (set_attr "mode" "V2DF")])
24197
24198 (define_insn "movshdup"
24199   [(set (match_operand:V4SF 0 "register_operand" "=x")
24200         (unspec:V4SF
24201          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24202   "TARGET_SSE3"
24203   "movshdup\t{%1, %0|%0, %1}"
24204   [(set_attr "type" "sse")
24205    (set_attr "mode" "V4SF")])
24206
24207 (define_insn "movsldup"
24208   [(set (match_operand:V4SF 0 "register_operand" "=x")
24209         (unspec:V4SF
24210          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24211   "TARGET_SSE3"
24212   "movsldup\t{%1, %0|%0, %1}"
24213   [(set_attr "type" "sse")
24214    (set_attr "mode" "V4SF")])
24215
24216 (define_insn "lddqu"
24217   [(set (match_operand:V16QI 0 "register_operand" "=x")
24218         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24219                        UNSPEC_LDQQU))]
24220   "TARGET_SSE3"
24221   "lddqu\t{%1, %0|%0, %1}"
24222   [(set_attr "type" "ssecvt")
24223    (set_attr "mode" "TI")])
24224
24225 (define_insn "loadddup"
24226   [(set (match_operand:V2DF 0 "register_operand" "=x")
24227         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24228   "TARGET_SSE3"
24229   "movddup\t{%1, %0|%0, %1}"
24230   [(set_attr "type" "ssecvt")
24231    (set_attr "mode" "DF")])
24232
24233 (define_insn "movddup"
24234   [(set (match_operand:V2DF 0 "register_operand" "=x")
24235         (vec_duplicate:V2DF
24236          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24237                         (parallel [(const_int 0)]))))]
24238   "TARGET_SSE3"
24239   "movddup\t{%1, %0|%0, %1}"
24240   [(set_attr "type" "ssecvt")
24241    (set_attr "mode" "DF")])