OSDN Git Service

PR target/17990
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1108  
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1116 {
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1126         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1127   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1128    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1129 {
1130   switch (get_attr_type (insn))
1131     {
1132     case TYPE_SSEMOV:
1133       if (get_attr_mode (insn) == MODE_TI)
1134         return "movdqa\t{%1, %0|%0, %1}";
1135       return "movd\t{%1, %0|%0, %1}";
1136
1137     case TYPE_MMXMOV:
1138       if (get_attr_mode (insn) == MODE_DI)
1139         return "movq\t{%1, %0|%0, %1}";
1140       return "movd\t{%1, %0|%0, %1}";
1141
1142     case TYPE_LEA:
1143       return "lea{l}\t{%1, %0|%0, %1}";
1144
1145     default:
1146       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1147         abort();
1148       return "mov{l}\t{%1, %0|%0, %1}";
1149     }
1150 }
1151   [(set (attr "type")
1152      (cond [(eq_attr "alternative" "2,3,4")
1153               (const_string "mmxmov")
1154             (eq_attr "alternative" "5,6,7")
1155               (const_string "ssemov")
1156             (and (ne (symbol_ref "flag_pic") (const_int 0))
1157                  (match_operand:SI 1 "symbolic_operand" ""))
1158               (const_string "lea")
1159            ]
1160            (const_string "imov")))
1161    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1162
1163 (define_insn "*movsi_1_nointernunit"
1164   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1165         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1166   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1168 {
1169   switch (get_attr_type (insn))
1170     {
1171     case TYPE_SSEMOV:
1172       if (get_attr_mode (insn) == MODE_TI)
1173         return "movdqa\t{%1, %0|%0, %1}";
1174       return "movd\t{%1, %0|%0, %1}";
1175
1176     case TYPE_MMXMOV:
1177       if (get_attr_mode (insn) == MODE_DI)
1178         return "movq\t{%1, %0|%0, %1}";
1179       return "movd\t{%1, %0|%0, %1}";
1180
1181     case TYPE_LEA:
1182       return "lea{l}\t{%1, %0|%0, %1}";
1183
1184     default:
1185       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1186         abort();
1187       return "mov{l}\t{%1, %0|%0, %1}";
1188     }
1189 }
1190   [(set (attr "type")
1191      (cond [(eq_attr "alternative" "2,3,4")
1192               (const_string "mmxmov")
1193             (eq_attr "alternative" "5,6,7")
1194               (const_string "ssemov")
1195             (and (ne (symbol_ref "flag_pic") (const_int 0))
1196                  (match_operand:SI 1 "symbolic_operand" ""))
1197               (const_string "lea")
1198            ]
1199            (const_string "imov")))
1200    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1201
1202 ;; Stores and loads of ax to arbitrary constant address.
1203 ;; We fake an second form of instruction to force reload to load address
1204 ;; into register when rax is not available
1205 (define_insn "*movabssi_1_rex64"
1206   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1207         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1208   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1209   "@
1210    movabs{l}\t{%1, %P0|%P0, %1}
1211    mov{l}\t{%1, %a0|%a0, %1}"
1212   [(set_attr "type" "imov")
1213    (set_attr "modrm" "0,*")
1214    (set_attr "length_address" "8,0")
1215    (set_attr "length_immediate" "0,*")
1216    (set_attr "memory" "store")
1217    (set_attr "mode" "SI")])
1218
1219 (define_insn "*movabssi_2_rex64"
1220   [(set (match_operand:SI 0 "register_operand" "=a,r")
1221         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1222   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1223   "@
1224    movabs{l}\t{%P1, %0|%0, %P1}
1225    mov{l}\t{%a1, %0|%0, %a1}"
1226   [(set_attr "type" "imov")
1227    (set_attr "modrm" "0,*")
1228    (set_attr "length_address" "8,0")
1229    (set_attr "length_immediate" "0")
1230    (set_attr "memory" "load")
1231    (set_attr "mode" "SI")])
1232
1233 (define_insn "*swapsi"
1234   [(set (match_operand:SI 0 "register_operand" "+r")
1235         (match_operand:SI 1 "register_operand" "+r"))
1236    (set (match_dup 1)
1237         (match_dup 0))]
1238   ""
1239   "xchg{l}\t%1, %0"
1240   [(set_attr "type" "imov")
1241    (set_attr "pent_pair" "np")
1242    (set_attr "athlon_decode" "vector")
1243    (set_attr "mode" "SI")
1244    (set_attr "modrm" "0")])
1245
1246 (define_expand "movhi"
1247   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248         (match_operand:HI 1 "general_operand" ""))]
1249   ""
1250   "ix86_expand_move (HImode, operands); DONE;")
1251
1252 (define_insn "*pushhi2"
1253   [(set (match_operand:HI 0 "push_operand" "=<,<")
1254         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1255   "!TARGET_64BIT"
1256   "@
1257    push{w}\t{|WORD PTR }%1
1258    push{w}\t%1"
1259   [(set_attr "type" "push")
1260    (set_attr "mode" "HI")])
1261
1262 ;; For 64BIT abi we always round up to 8 bytes.
1263 (define_insn "*pushhi2_rex64"
1264   [(set (match_operand:HI 0 "push_operand" "=X")
1265         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1266   "TARGET_64BIT"
1267   "push{q}\t%q1"
1268   [(set_attr "type" "push")
1269    (set_attr "mode" "QI")])
1270
1271 (define_insn "*movhi_1"
1272   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1274   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1275 {
1276   switch (get_attr_type (insn))
1277     {
1278     case TYPE_IMOVX:
1279       /* movzwl is faster than movw on p2 due to partial word stalls,
1280          though not as fast as an aligned movl.  */
1281       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1282     default:
1283       if (get_attr_mode (insn) == MODE_SI)
1284         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1285       else
1286         return "mov{w}\t{%1, %0|%0, %1}";
1287     }
1288 }
1289   [(set (attr "type")
1290      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291               (const_string "imov")
1292             (and (eq_attr "alternative" "0")
1293                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1294                           (const_int 0))
1295                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1296                           (const_int 0))))
1297               (const_string "imov")
1298             (and (eq_attr "alternative" "1,2")
1299                  (match_operand:HI 1 "aligned_operand" ""))
1300               (const_string "imov")
1301             (and (ne (symbol_ref "TARGET_MOVX")
1302                      (const_int 0))
1303                  (eq_attr "alternative" "0,2"))
1304               (const_string "imovx")
1305            ]
1306            (const_string "imov")))
1307     (set (attr "mode")
1308       (cond [(eq_attr "type" "imovx")
1309                (const_string "SI")
1310              (and (eq_attr "alternative" "1,2")
1311                   (match_operand:HI 1 "aligned_operand" ""))
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "0")
1314                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315                            (const_int 0))
1316                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1317                            (const_int 0))))
1318                (const_string "SI")
1319             ]
1320             (const_string "HI")))])
1321
1322 ;; Stores and loads of ax to arbitrary constant address.
1323 ;; We fake an second form of instruction to force reload to load address
1324 ;; into register when rax is not available
1325 (define_insn "*movabshi_1_rex64"
1326   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1329   "@
1330    movabs{w}\t{%1, %P0|%P0, %1}
1331    mov{w}\t{%1, %a0|%a0, %1}"
1332   [(set_attr "type" "imov")
1333    (set_attr "modrm" "0,*")
1334    (set_attr "length_address" "8,0")
1335    (set_attr "length_immediate" "0,*")
1336    (set_attr "memory" "store")
1337    (set_attr "mode" "HI")])
1338
1339 (define_insn "*movabshi_2_rex64"
1340   [(set (match_operand:HI 0 "register_operand" "=a,r")
1341         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1342   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1343   "@
1344    movabs{w}\t{%P1, %0|%0, %P1}
1345    mov{w}\t{%a1, %0|%0, %a1}"
1346   [(set_attr "type" "imov")
1347    (set_attr "modrm" "0,*")
1348    (set_attr "length_address" "8,0")
1349    (set_attr "length_immediate" "0")
1350    (set_attr "memory" "load")
1351    (set_attr "mode" "HI")])
1352
1353 (define_insn "*swaphi_1"
1354   [(set (match_operand:HI 0 "register_operand" "+r")
1355         (match_operand:HI 1 "register_operand" "+r"))
1356    (set (match_dup 1)
1357         (match_dup 0))]
1358   "TARGET_PARTIAL_REG_STALL"
1359   "xchg{w}\t%1, %0"
1360   [(set_attr "type" "imov")
1361    (set_attr "pent_pair" "np")
1362    (set_attr "mode" "HI")
1363    (set_attr "modrm" "0")])
1364
1365 (define_insn "*swaphi_2"
1366   [(set (match_operand:HI 0 "register_operand" "+r")
1367         (match_operand:HI 1 "register_operand" "+r"))
1368    (set (match_dup 1)
1369         (match_dup 0))]
1370   "! TARGET_PARTIAL_REG_STALL"
1371   "xchg{l}\t%k1, %k0"
1372   [(set_attr "type" "imov")
1373    (set_attr "pent_pair" "np")
1374    (set_attr "mode" "SI")
1375    (set_attr "modrm" "0")])
1376
1377 (define_expand "movstricthi"
1378   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1379         (match_operand:HI 1 "general_operand" ""))]
1380   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1381 {
1382   /* Don't generate memory->memory moves, go through a register */
1383   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384     operands[1] = force_reg (HImode, operands[1]);
1385 })
1386
1387 (define_insn "*movstricthi_1"
1388   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1389         (match_operand:HI 1 "general_operand" "rn,m"))]
1390   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1391    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1392   "mov{w}\t{%1, %0|%0, %1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "mode" "HI")])
1395
1396 (define_insn "*movstricthi_xor"
1397   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1398         (match_operand:HI 1 "const0_operand" "i"))
1399    (clobber (reg:CC FLAGS_REG))]
1400   "reload_completed
1401    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1402   "xor{w}\t{%0, %0|%0, %0}"
1403   [(set_attr "type" "alu1")
1404    (set_attr "mode" "HI")
1405    (set_attr "length_immediate" "0")])
1406
1407 (define_expand "movqi"
1408   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1409         (match_operand:QI 1 "general_operand" ""))]
1410   ""
1411   "ix86_expand_move (QImode, operands); DONE;")
1412
1413 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1414 ;; "push a byte".  But actually we use pushw, which has the effect
1415 ;; of rounding the amount pushed up to a halfword.
1416
1417 (define_insn "*pushqi2"
1418   [(set (match_operand:QI 0 "push_operand" "=X,X")
1419         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1420   "!TARGET_64BIT"
1421   "@
1422    push{w}\t{|word ptr }%1
1423    push{w}\t%w1"
1424   [(set_attr "type" "push")
1425    (set_attr "mode" "HI")])
1426
1427 ;; For 64BIT abi we always round up to 8 bytes.
1428 (define_insn "*pushqi2_rex64"
1429   [(set (match_operand:QI 0 "push_operand" "=X")
1430         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1431   "TARGET_64BIT"
1432   "push{q}\t%q1"
1433   [(set_attr "type" "push")
1434    (set_attr "mode" "QI")])
1435
1436 ;; Situation is quite tricky about when to choose full sized (SImode) move
1437 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1438 ;; partial register dependency machines (such as AMD Athlon), where QImode
1439 ;; moves issue extra dependency and for partial register stalls machines
1440 ;; that don't use QImode patterns (and QImode move cause stall on the next
1441 ;; instruction).
1442 ;;
1443 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444 ;; register stall machines with, where we use QImode instructions, since
1445 ;; partial register stall can be caused there.  Then we use movzx.
1446 (define_insn "*movqi_1"
1447   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1449   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1450 {
1451   switch (get_attr_type (insn))
1452     {
1453     case TYPE_IMOVX:
1454       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1455         abort ();
1456       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1457     default:
1458       if (get_attr_mode (insn) == MODE_SI)
1459         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1460       else
1461         return "mov{b}\t{%1, %0|%0, %1}";
1462     }
1463 }
1464   [(set (attr "type")
1465      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1466               (const_string "imov")
1467             (and (eq_attr "alternative" "3")
1468                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1469                           (const_int 0))
1470                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1471                           (const_int 0))))
1472               (const_string "imov")
1473             (eq_attr "alternative" "3,5")
1474               (const_string "imovx")
1475             (and (ne (symbol_ref "TARGET_MOVX")
1476                      (const_int 0))
1477                  (eq_attr "alternative" "2"))
1478               (const_string "imovx")
1479            ]
1480            (const_string "imov")))
1481    (set (attr "mode")
1482       (cond [(eq_attr "alternative" "3,4,5")
1483                (const_string "SI")
1484              (eq_attr "alternative" "6")
1485                (const_string "QI")
1486              (eq_attr "type" "imovx")
1487                (const_string "SI")
1488              (and (eq_attr "type" "imov")
1489                   (and (eq_attr "alternative" "0,1,2")
1490                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1491                            (const_int 0))))
1492                (const_string "SI")
1493              ;; Avoid partial register stalls when not using QImode arithmetic
1494              (and (eq_attr "type" "imov")
1495                   (and (eq_attr "alternative" "0,1,2")
1496                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1497                                 (const_int 0))
1498                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1499                                 (const_int 0)))))
1500                (const_string "SI")
1501            ]
1502            (const_string "QI")))])
1503
1504 (define_expand "reload_outqi"
1505   [(parallel [(match_operand:QI 0 "" "=m")
1506               (match_operand:QI 1 "register_operand" "r")
1507               (match_operand:QI 2 "register_operand" "=&q")])]
1508   ""
1509 {
1510   rtx op0, op1, op2;
1511   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1512
1513   if (reg_overlap_mentioned_p (op2, op0))
1514     abort ();
1515   if (! q_regs_operand (op1, QImode))
1516     {
1517       emit_insn (gen_movqi (op2, op1));
1518       op1 = op2;
1519     }
1520   emit_insn (gen_movqi (op0, op1));
1521   DONE;
1522 })
1523
1524 (define_insn "*swapqi"
1525   [(set (match_operand:QI 0 "register_operand" "+r")
1526         (match_operand:QI 1 "register_operand" "+r"))
1527    (set (match_dup 1)
1528         (match_dup 0))]
1529   ""
1530   "xchg{b}\t%1, %0"
1531   [(set_attr "type" "imov")
1532    (set_attr "pent_pair" "np")
1533    (set_attr "mode" "QI")
1534    (set_attr "modrm" "0")])
1535
1536 (define_expand "movstrictqi"
1537   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1538         (match_operand:QI 1 "general_operand" ""))]
1539   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1540 {
1541   /* Don't generate memory->memory moves, go through a register.  */
1542   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1543     operands[1] = force_reg (QImode, operands[1]);
1544 })
1545
1546 (define_insn "*movstrictqi_1"
1547   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1548         (match_operand:QI 1 "general_operand" "*qn,m"))]
1549   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1550    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1551   "mov{b}\t{%1, %0|%0, %1}"
1552   [(set_attr "type" "imov")
1553    (set_attr "mode" "QI")])
1554
1555 (define_insn "*movstrictqi_xor"
1556   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1557         (match_operand:QI 1 "const0_operand" "i"))
1558    (clobber (reg:CC FLAGS_REG))]
1559   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1560   "xor{b}\t{%0, %0|%0, %0}"
1561   [(set_attr "type" "alu1")
1562    (set_attr "mode" "QI")
1563    (set_attr "length_immediate" "0")])
1564
1565 (define_insn "*movsi_extv_1"
1566   [(set (match_operand:SI 0 "register_operand" "=R")
1567         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1568                          (const_int 8)
1569                          (const_int 8)))]
1570   ""
1571   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1572   [(set_attr "type" "imovx")
1573    (set_attr "mode" "SI")])
1574
1575 (define_insn "*movhi_extv_1"
1576   [(set (match_operand:HI 0 "register_operand" "=R")
1577         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1578                          (const_int 8)
1579                          (const_int 8)))]
1580   ""
1581   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1582   [(set_attr "type" "imovx")
1583    (set_attr "mode" "SI")])
1584
1585 (define_insn "*movqi_extv_1"
1586   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1587         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1588                          (const_int 8)
1589                          (const_int 8)))]
1590   "!TARGET_64BIT"
1591 {
1592   switch (get_attr_type (insn))
1593     {
1594     case TYPE_IMOVX:
1595       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1596     default:
1597       return "mov{b}\t{%h1, %0|%0, %h1}";
1598     }
1599 }
1600   [(set (attr "type")
1601      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1602                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1603                              (ne (symbol_ref "TARGET_MOVX")
1604                                  (const_int 0))))
1605         (const_string "imovx")
1606         (const_string "imov")))
1607    (set (attr "mode")
1608      (if_then_else (eq_attr "type" "imovx")
1609         (const_string "SI")
1610         (const_string "QI")))])
1611
1612 (define_insn "*movqi_extv_1_rex64"
1613   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1614         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1615                          (const_int 8)
1616                          (const_int 8)))]
1617   "TARGET_64BIT"
1618 {
1619   switch (get_attr_type (insn))
1620     {
1621     case TYPE_IMOVX:
1622       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1623     default:
1624       return "mov{b}\t{%h1, %0|%0, %h1}";
1625     }
1626 }
1627   [(set (attr "type")
1628      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630                              (ne (symbol_ref "TARGET_MOVX")
1631                                  (const_int 0))))
1632         (const_string "imovx")
1633         (const_string "imov")))
1634    (set (attr "mode")
1635      (if_then_else (eq_attr "type" "imovx")
1636         (const_string "SI")
1637         (const_string "QI")))])
1638
1639 ;; Stores and loads of ax to arbitrary constant address.
1640 ;; We fake an second form of instruction to force reload to load address
1641 ;; into register when rax is not available
1642 (define_insn "*movabsqi_1_rex64"
1643   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1644         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1645   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1646   "@
1647    movabs{b}\t{%1, %P0|%P0, %1}
1648    mov{b}\t{%1, %a0|%a0, %1}"
1649   [(set_attr "type" "imov")
1650    (set_attr "modrm" "0,*")
1651    (set_attr "length_address" "8,0")
1652    (set_attr "length_immediate" "0,*")
1653    (set_attr "memory" "store")
1654    (set_attr "mode" "QI")])
1655
1656 (define_insn "*movabsqi_2_rex64"
1657   [(set (match_operand:QI 0 "register_operand" "=a,r")
1658         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1659   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1660   "@
1661    movabs{b}\t{%P1, %0|%0, %P1}
1662    mov{b}\t{%a1, %0|%0, %a1}"
1663   [(set_attr "type" "imov")
1664    (set_attr "modrm" "0,*")
1665    (set_attr "length_address" "8,0")
1666    (set_attr "length_immediate" "0")
1667    (set_attr "memory" "load")
1668    (set_attr "mode" "QI")])
1669
1670 (define_insn "*movsi_extzv_1"
1671   [(set (match_operand:SI 0 "register_operand" "=R")
1672         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1673                          (const_int 8)
1674                          (const_int 8)))]
1675   ""
1676   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1677   [(set_attr "type" "imovx")
1678    (set_attr "mode" "SI")])
1679
1680 (define_insn "*movqi_extzv_2"
1681   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1682         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1683                                     (const_int 8)
1684                                     (const_int 8)) 0))]
1685   "!TARGET_64BIT"
1686 {
1687   switch (get_attr_type (insn))
1688     {
1689     case TYPE_IMOVX:
1690       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1691     default:
1692       return "mov{b}\t{%h1, %0|%0, %h1}";
1693     }
1694 }
1695   [(set (attr "type")
1696      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1697                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1698                              (ne (symbol_ref "TARGET_MOVX")
1699                                  (const_int 0))))
1700         (const_string "imovx")
1701         (const_string "imov")))
1702    (set (attr "mode")
1703      (if_then_else (eq_attr "type" "imovx")
1704         (const_string "SI")
1705         (const_string "QI")))])
1706
1707 (define_insn "*movqi_extzv_2_rex64"
1708   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1709         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1710                                     (const_int 8)
1711                                     (const_int 8)) 0))]
1712   "TARGET_64BIT"
1713 {
1714   switch (get_attr_type (insn))
1715     {
1716     case TYPE_IMOVX:
1717       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1718     default:
1719       return "mov{b}\t{%h1, %0|%0, %h1}";
1720     }
1721 }
1722   [(set (attr "type")
1723      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1724                         (ne (symbol_ref "TARGET_MOVX")
1725                             (const_int 0)))
1726         (const_string "imovx")
1727         (const_string "imov")))
1728    (set (attr "mode")
1729      (if_then_else (eq_attr "type" "imovx")
1730         (const_string "SI")
1731         (const_string "QI")))])
1732
1733 (define_insn "movsi_insv_1"
1734   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1735                          (const_int 8)
1736                          (const_int 8))
1737         (match_operand:SI 1 "general_operand" "Qmn"))]
1738   "!TARGET_64BIT"
1739   "mov{b}\t{%b1, %h0|%h0, %b1}"
1740   [(set_attr "type" "imov")
1741    (set_attr "mode" "QI")])
1742
1743 (define_insn "movdi_insv_1_rex64"
1744   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1745                          (const_int 8)
1746                          (const_int 8))
1747         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1748   "TARGET_64BIT"
1749   "mov{b}\t{%b1, %h0|%h0, %b1}"
1750   [(set_attr "type" "imov")
1751    (set_attr "mode" "QI")])
1752
1753 (define_insn "*movqi_insv_2"
1754   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1755                          (const_int 8)
1756                          (const_int 8))
1757         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1758                      (const_int 8)))]
1759   ""
1760   "mov{b}\t{%h1, %h0|%h0, %h1}"
1761   [(set_attr "type" "imov")
1762    (set_attr "mode" "QI")])
1763
1764 (define_expand "movdi"
1765   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1766         (match_operand:DI 1 "general_operand" ""))]
1767   ""
1768   "ix86_expand_move (DImode, operands); DONE;")
1769
1770 (define_insn "*pushdi"
1771   [(set (match_operand:DI 0 "push_operand" "=<")
1772         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1773   "!TARGET_64BIT"
1774   "#")
1775
1776 (define_insn "pushdi2_rex64"
1777   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1778         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1779   "TARGET_64BIT"
1780   "@
1781    push{q}\t%1
1782    #"
1783   [(set_attr "type" "push,multi")
1784    (set_attr "mode" "DI")])
1785
1786 ;; Convert impossible pushes of immediate to existing instructions.
1787 ;; First try to get scratch register and go through it.  In case this
1788 ;; fails, push sign extended lower part first and then overwrite
1789 ;; upper part by 32bit move.
1790 (define_peephole2
1791   [(match_scratch:DI 2 "r")
1792    (set (match_operand:DI 0 "push_operand" "")
1793         (match_operand:DI 1 "immediate_operand" ""))]
1794   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1795    && !x86_64_immediate_operand (operands[1], DImode)"
1796   [(set (match_dup 2) (match_dup 1))
1797    (set (match_dup 0) (match_dup 2))]
1798   "")
1799
1800 ;; We need to define this as both peepholer and splitter for case
1801 ;; peephole2 pass is not run.
1802 ;; "&& 1" is needed to keep it from matching the previous pattern.
1803 (define_peephole2
1804   [(set (match_operand:DI 0 "push_operand" "")
1805         (match_operand:DI 1 "immediate_operand" ""))]
1806   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1808   [(set (match_dup 0) (match_dup 1))
1809    (set (match_dup 2) (match_dup 3))]
1810   "split_di (operands + 1, 1, operands + 2, operands + 3);
1811    operands[1] = gen_lowpart (DImode, operands[2]);
1812    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1813                                                     GEN_INT (4)));
1814   ")
1815
1816 (define_split
1817   [(set (match_operand:DI 0 "push_operand" "")
1818         (match_operand:DI 1 "immediate_operand" ""))]
1819   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1820    && !symbolic_operand (operands[1], DImode)
1821    && !x86_64_immediate_operand (operands[1], DImode)"
1822   [(set (match_dup 0) (match_dup 1))
1823    (set (match_dup 2) (match_dup 3))]
1824   "split_di (operands + 1, 1, operands + 2, operands + 3);
1825    operands[1] = gen_lowpart (DImode, operands[2]);
1826    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1827                                                     GEN_INT (4)));
1828   ")
1829
1830 (define_insn "*pushdi2_prologue_rex64"
1831   [(set (match_operand:DI 0 "push_operand" "=<")
1832         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1833    (clobber (mem:BLK (scratch)))]
1834   "TARGET_64BIT"
1835   "push{q}\t%1"
1836   [(set_attr "type" "push")
1837    (set_attr "mode" "DI")])
1838
1839 (define_insn "*popdi1_epilogue_rex64"
1840   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1841         (mem:DI (reg:DI SP_REG)))
1842    (set (reg:DI SP_REG)
1843         (plus:DI (reg:DI SP_REG) (const_int 8)))
1844    (clobber (mem:BLK (scratch)))]
1845   "TARGET_64BIT"
1846   "pop{q}\t%0"
1847   [(set_attr "type" "pop")
1848    (set_attr "mode" "DI")])
1849
1850 (define_insn "popdi1"
1851   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1852         (mem:DI (reg:DI SP_REG)))
1853    (set (reg:DI SP_REG)
1854         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1855   "TARGET_64BIT"
1856   "pop{q}\t%0"
1857   [(set_attr "type" "pop")
1858    (set_attr "mode" "DI")])
1859
1860 (define_insn "*movdi_xor_rex64"
1861   [(set (match_operand:DI 0 "register_operand" "=r")
1862         (match_operand:DI 1 "const0_operand" "i"))
1863    (clobber (reg:CC FLAGS_REG))]
1864   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1865    && reload_completed"
1866   "xor{l}\t{%k0, %k0|%k0, %k0}"
1867   [(set_attr "type" "alu1")
1868    (set_attr "mode" "SI")
1869    (set_attr "length_immediate" "0")])
1870
1871 (define_insn "*movdi_or_rex64"
1872   [(set (match_operand:DI 0 "register_operand" "=r")
1873         (match_operand:DI 1 "const_int_operand" "i"))
1874    (clobber (reg:CC FLAGS_REG))]
1875   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1876    && reload_completed
1877    && operands[1] == constm1_rtx"
1878 {
1879   operands[1] = constm1_rtx;
1880   return "or{q}\t{%1, %0|%0, %1}";
1881 }
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "DI")
1884    (set_attr "length_immediate" "1")])
1885
1886 (define_insn "*movdi_2"
1887   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1888         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1889   "!TARGET_64BIT
1890    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1891   "@
1892    #
1893    #
1894    movq\t{%1, %0|%0, %1}
1895    movq\t{%1, %0|%0, %1}
1896    movq\t{%1, %0|%0, %1}
1897    movdqa\t{%1, %0|%0, %1}
1898    movq\t{%1, %0|%0, %1}"
1899   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1900    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1901
1902 (define_split
1903   [(set (match_operand:DI 0 "push_operand" "")
1904         (match_operand:DI 1 "general_operand" ""))]
1905   "!TARGET_64BIT && reload_completed
1906    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1907   [(const_int 0)]
1908   "ix86_split_long_move (operands); DONE;")
1909
1910 ;; %%% This multiword shite has got to go.
1911 (define_split
1912   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1913         (match_operand:DI 1 "general_operand" ""))]
1914   "!TARGET_64BIT && reload_completed
1915    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1916    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1917   [(const_int 0)]
1918   "ix86_split_long_move (operands); DONE;")
1919
1920 (define_insn "*movdi_1_rex64"
1921   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1922         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1923   "TARGET_64BIT
1924    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1925    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1926 {
1927   switch (get_attr_type (insn))
1928     {
1929     case TYPE_SSECVT:
1930       if (which_alternative == 11)
1931         return "movq2dq\t{%1, %0|%0, %1}";
1932       else
1933         return "movdq2q\t{%1, %0|%0, %1}";
1934     case TYPE_SSEMOV:
1935       if (get_attr_mode (insn) == MODE_TI)
1936           return "movdqa\t{%1, %0|%0, %1}";
1937       /* FALLTHRU */
1938     case TYPE_MMXMOV:
1939       /* Moves from and into integer register is done using movd opcode with
1940          REX prefix.  */
1941       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942           return "movd\t{%1, %0|%0, %1}";
1943       return "movq\t{%1, %0|%0, %1}";
1944     case TYPE_MULTI:
1945       return "#";
1946     case TYPE_LEA:
1947       return "lea{q}\t{%a1, %0|%0, %a1}";
1948     default:
1949       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1950         abort ();
1951       if (get_attr_mode (insn) == MODE_SI)
1952         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1953       else if (which_alternative == 2)
1954         return "movabs{q}\t{%1, %0|%0, %1}";
1955       else
1956         return "mov{q}\t{%1, %0|%0, %1}";
1957     }
1958 }
1959   [(set (attr "type")
1960      (cond [(eq_attr "alternative" "5,6,7")
1961               (const_string "mmxmov")
1962             (eq_attr "alternative" "8,9,10")
1963               (const_string "ssemov")
1964             (eq_attr "alternative" "11,12")
1965               (const_string "ssecvt")
1966             (eq_attr "alternative" "4")
1967               (const_string "multi")
1968             (and (ne (symbol_ref "flag_pic") (const_int 0))
1969                  (match_operand:DI 1 "symbolic_operand" ""))
1970               (const_string "lea")
1971            ]
1972            (const_string "imov")))
1973    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1974    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1975    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1976
1977 (define_insn "*movdi_1_rex64_nointerunit"
1978   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1979         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1980   "TARGET_64BIT
1981    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1982    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1983 {
1984   switch (get_attr_type (insn))
1985     {
1986     case TYPE_SSEMOV:
1987       if (get_attr_mode (insn) == MODE_TI)
1988           return "movdqa\t{%1, %0|%0, %1}";
1989       /* FALLTHRU */
1990     case TYPE_MMXMOV:
1991       return "movq\t{%1, %0|%0, %1}";
1992     case TYPE_MULTI:
1993       return "#";
1994     case TYPE_LEA:
1995       return "lea{q}\t{%a1, %0|%0, %a1}";
1996     default:
1997       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1998         abort ();
1999       if (get_attr_mode (insn) == MODE_SI)
2000         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2001       else if (which_alternative == 2)
2002         return "movabs{q}\t{%1, %0|%0, %1}";
2003       else
2004         return "mov{q}\t{%1, %0|%0, %1}";
2005     }
2006 }
2007   [(set (attr "type")
2008      (cond [(eq_attr "alternative" "5,6,7")
2009               (const_string "mmxmov")
2010             (eq_attr "alternative" "8,9,10")
2011               (const_string "ssemov")
2012             (eq_attr "alternative" "4")
2013               (const_string "multi")
2014             (and (ne (symbol_ref "flag_pic") (const_int 0))
2015                  (match_operand:DI 1 "symbolic_operand" ""))
2016               (const_string "lea")
2017            ]
2018            (const_string "imov")))
2019    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2020    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2021    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2022
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsdi_1_rex64"
2027   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2029   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030   "@
2031    movabs{q}\t{%1, %P0|%P0, %1}
2032    mov{q}\t{%1, %a0|%a0, %1}"
2033   [(set_attr "type" "imov")
2034    (set_attr "modrm" "0,*")
2035    (set_attr "length_address" "8,0")
2036    (set_attr "length_immediate" "0,*")
2037    (set_attr "memory" "store")
2038    (set_attr "mode" "DI")])
2039
2040 (define_insn "*movabsdi_2_rex64"
2041   [(set (match_operand:DI 0 "register_operand" "=a,r")
2042         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044   "@
2045    movabs{q}\t{%P1, %0|%0, %P1}
2046    mov{q}\t{%a1, %0|%0, %a1}"
2047   [(set_attr "type" "imov")
2048    (set_attr "modrm" "0,*")
2049    (set_attr "length_address" "8,0")
2050    (set_attr "length_immediate" "0")
2051    (set_attr "memory" "load")
2052    (set_attr "mode" "DI")])
2053
2054 ;; Convert impossible stores of immediate to existing instructions.
2055 ;; First try to get scratch register and go through it.  In case this
2056 ;; fails, move by 32bit parts.
2057 (define_peephole2
2058   [(match_scratch:DI 2 "r")
2059    (set (match_operand:DI 0 "memory_operand" "")
2060         (match_operand:DI 1 "immediate_operand" ""))]
2061   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2062    && !x86_64_immediate_operand (operands[1], DImode)"
2063   [(set (match_dup 2) (match_dup 1))
2064    (set (match_dup 0) (match_dup 2))]
2065   "")
2066
2067 ;; We need to define this as both peepholer and splitter for case
2068 ;; peephole2 pass is not run.
2069 ;; "&& 1" is needed to keep it from matching the previous pattern.
2070 (define_peephole2
2071   [(set (match_operand:DI 0 "memory_operand" "")
2072         (match_operand:DI 1 "immediate_operand" ""))]
2073   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2075   [(set (match_dup 2) (match_dup 3))
2076    (set (match_dup 4) (match_dup 5))]
2077   "split_di (operands, 2, operands + 2, operands + 4);")
2078
2079 (define_split
2080   [(set (match_operand:DI 0 "memory_operand" "")
2081         (match_operand:DI 1 "immediate_operand" ""))]
2082   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2083    && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode)"
2085   [(set (match_dup 2) (match_dup 3))
2086    (set (match_dup 4) (match_dup 5))]
2087   "split_di (operands, 2, operands + 2, operands + 4);")
2088
2089 (define_insn "*swapdi_rex64"
2090   [(set (match_operand:DI 0 "register_operand" "+r")
2091         (match_operand:DI 1 "register_operand" "+r"))
2092    (set (match_dup 1)
2093         (match_dup 0))]
2094   "TARGET_64BIT"
2095   "xchg{q}\t%1, %0"
2096   [(set_attr "type" "imov")
2097    (set_attr "pent_pair" "np")
2098    (set_attr "athlon_decode" "vector")
2099    (set_attr "mode" "DI")
2100    (set_attr "modrm" "0")])
2101
2102   
2103 (define_expand "movsf"
2104   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2105         (match_operand:SF 1 "general_operand" ""))]
2106   ""
2107   "ix86_expand_move (SFmode, operands); DONE;")
2108
2109 (define_insn "*pushsf"
2110   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2111         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2112   "!TARGET_64BIT"
2113 {
2114   switch (which_alternative)
2115     {
2116     case 1:
2117       return "push{l}\t%1";
2118
2119     default:
2120       /* This insn should be already split before reg-stack.  */
2121       abort ();
2122     }
2123 }
2124   [(set_attr "type" "multi,push,multi")
2125    (set_attr "mode" "SF,SI,SF")])
2126
2127 (define_insn "*pushsf_rex64"
2128   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2129         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2130   "TARGET_64BIT"
2131 {
2132   switch (which_alternative)
2133     {
2134     case 1:
2135       return "push{q}\t%q1";
2136
2137     default:
2138       /* This insn should be already split before reg-stack.  */
2139       abort ();
2140     }
2141 }
2142   [(set_attr "type" "multi,push,multi")
2143    (set_attr "mode" "SF,DI,SF")])
2144
2145 (define_split
2146   [(set (match_operand:SF 0 "push_operand" "")
2147         (match_operand:SF 1 "memory_operand" ""))]
2148   "reload_completed
2149    && GET_CODE (operands[1]) == MEM
2150    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2151    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2152   [(set (match_dup 0)
2153         (match_dup 1))]
2154   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2155
2156
2157 ;; %%% Kill this when call knows how to work this out.
2158 (define_split
2159   [(set (match_operand:SF 0 "push_operand" "")
2160         (match_operand:SF 1 "any_fp_register_operand" ""))]
2161   "!TARGET_64BIT"
2162   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2163    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2164
2165 (define_split
2166   [(set (match_operand:SF 0 "push_operand" "")
2167         (match_operand:SF 1 "any_fp_register_operand" ""))]
2168   "TARGET_64BIT"
2169   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2170    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2171
2172 (define_insn "*movsf_1"
2173   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2174         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2175   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2176    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2177    && (reload_in_progress || reload_completed
2178        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2179        || GET_CODE (operands[1]) != CONST_DOUBLE
2180        || memory_operand (operands[0], SFmode))" 
2181 {
2182   switch (which_alternative)
2183     {
2184     case 0:
2185       return output_387_reg_move (insn, operands);
2186
2187     case 1:
2188       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2189         return "fstp%z0\t%y0";
2190       else
2191         return "fst%z0\t%y0";
2192
2193     case 2:
2194       return standard_80387_constant_opcode (operands[1]);
2195
2196     case 3:
2197     case 4:
2198       return "mov{l}\t{%1, %0|%0, %1}";
2199     case 5:
2200       if (get_attr_mode (insn) == MODE_TI)
2201         return "pxor\t%0, %0";
2202       else
2203         return "xorps\t%0, %0";
2204     case 6:
2205       if (get_attr_mode (insn) == MODE_V4SF)
2206         return "movaps\t{%1, %0|%0, %1}";
2207       else
2208         return "movss\t{%1, %0|%0, %1}";
2209     case 7:
2210     case 8:
2211       return "movss\t{%1, %0|%0, %1}";
2212
2213     case 9:
2214     case 10:
2215       return "movd\t{%1, %0|%0, %1}";
2216
2217     case 11:
2218       return "movq\t{%1, %0|%0, %1}";
2219
2220     default:
2221       abort();
2222     }
2223 }
2224   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2225    (set (attr "mode")
2226         (cond [(eq_attr "alternative" "3,4,9,10")
2227                  (const_string "SI")
2228                (eq_attr "alternative" "5")
2229                  (if_then_else
2230                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2231                                  (const_int 0))
2232                              (ne (symbol_ref "TARGET_SSE2")
2233                                  (const_int 0)))
2234                         (eq (symbol_ref "optimize_size")
2235                             (const_int 0)))
2236                    (const_string "TI")
2237                    (const_string "V4SF"))
2238                /* For architectures resolving dependencies on
2239                   whole SSE registers use APS move to break dependency
2240                   chains, otherwise use short move to avoid extra work. 
2241
2242                   Do the same for architectures resolving dependencies on
2243                   the parts.  While in DF mode it is better to always handle
2244                   just register parts, the SF mode is different due to lack
2245                   of instructions to load just part of the register.  It is
2246                   better to maintain the whole registers in single format
2247                   to avoid problems on using packed logical operations.  */
2248                (eq_attr "alternative" "6")
2249                  (if_then_else
2250                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2251                             (const_int 0))
2252                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2253                             (const_int 0)))
2254                    (const_string "V4SF")
2255                    (const_string "SF"))
2256                (eq_attr "alternative" "11")
2257                  (const_string "DI")]
2258                (const_string "SF")))])
2259
2260 (define_insn "*movsf_1_nointerunit"
2261   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2262         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2263   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2264    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2265    && (reload_in_progress || reload_completed
2266        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2267        || GET_CODE (operands[1]) != CONST_DOUBLE
2268        || memory_operand (operands[0], SFmode))" 
2269 {
2270   switch (which_alternative)
2271     {
2272     case 0:
2273       return output_387_reg_move (insn, operands);
2274
2275     case 1:
2276       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2277         return "fstp%z0\t%y0";
2278       else
2279         return "fst%z0\t%y0";
2280
2281     case 2:
2282       return standard_80387_constant_opcode (operands[1]);
2283
2284     case 3:
2285     case 4:
2286       return "mov{l}\t{%1, %0|%0, %1}";
2287     case 5:
2288       if (get_attr_mode (insn) == MODE_TI)
2289         return "pxor\t%0, %0";
2290       else
2291         return "xorps\t%0, %0";
2292     case 6:
2293       if (get_attr_mode (insn) == MODE_V4SF)
2294         return "movaps\t{%1, %0|%0, %1}";
2295       else
2296         return "movss\t{%1, %0|%0, %1}";
2297     case 7:
2298     case 8:
2299       return "movss\t{%1, %0|%0, %1}";
2300
2301     case 9:
2302     case 10:
2303       return "movd\t{%1, %0|%0, %1}";
2304
2305     case 11:
2306       return "movq\t{%1, %0|%0, %1}";
2307
2308     default:
2309       abort();
2310     }
2311 }
2312   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2313    (set (attr "mode")
2314         (cond [(eq_attr "alternative" "3,4,9,10")
2315                  (const_string "SI")
2316                (eq_attr "alternative" "5")
2317                  (if_then_else
2318                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2319                                  (const_int 0))
2320                              (ne (symbol_ref "TARGET_SSE2")
2321                                  (const_int 0)))
2322                         (eq (symbol_ref "optimize_size")
2323                             (const_int 0)))
2324                    (const_string "TI")
2325                    (const_string "V4SF"))
2326                /* For architectures resolving dependencies on
2327                   whole SSE registers use APS move to break dependency
2328                   chains, otherwise use short move to avoid extra work. 
2329
2330                   Do the same for architectures resolving dependencies on
2331                   the parts.  While in DF mode it is better to always handle
2332                   just register parts, the SF mode is different due to lack
2333                   of instructions to load just part of the register.  It is
2334                   better to maintain the whole registers in single format
2335                   to avoid problems on using packed logical operations.  */
2336                (eq_attr "alternative" "6")
2337                  (if_then_else
2338                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2339                             (const_int 0))
2340                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2341                             (const_int 0)))
2342                    (const_string "V4SF")
2343                    (const_string "SF"))
2344                (eq_attr "alternative" "11")
2345                  (const_string "DI")]
2346                (const_string "SF")))])
2347
2348 (define_insn "*swapsf"
2349   [(set (match_operand:SF 0 "register_operand" "+f")
2350         (match_operand:SF 1 "register_operand" "+f"))
2351    (set (match_dup 1)
2352         (match_dup 0))]
2353   "reload_completed || !TARGET_SSE"
2354 {
2355   if (STACK_TOP_P (operands[0]))
2356     return "fxch\t%1";
2357   else
2358     return "fxch\t%0";
2359 }
2360   [(set_attr "type" "fxch")
2361    (set_attr "mode" "SF")])
2362
2363 (define_expand "movdf"
2364   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2365         (match_operand:DF 1 "general_operand" ""))]
2366   ""
2367   "ix86_expand_move (DFmode, operands); DONE;")
2368
2369 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2370 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2371 ;; On the average, pushdf using integers can be still shorter.  Allow this
2372 ;; pattern for optimize_size too.
2373
2374 (define_insn "*pushdf_nointeger"
2375   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2376         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2377   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2378 {
2379   /* This insn should be already split before reg-stack.  */
2380   abort ();
2381 }
2382   [(set_attr "type" "multi")
2383    (set_attr "mode" "DF,SI,SI,DF")])
2384
2385 (define_insn "*pushdf_integer"
2386   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2387         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2388   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2389 {
2390   /* This insn should be already split before reg-stack.  */
2391   abort ();
2392 }
2393   [(set_attr "type" "multi")
2394    (set_attr "mode" "DF,SI,DF")])
2395
2396 ;; %%% Kill this when call knows how to work this out.
2397 (define_split
2398   [(set (match_operand:DF 0 "push_operand" "")
2399         (match_operand:DF 1 "any_fp_register_operand" ""))]
2400   "!TARGET_64BIT && reload_completed"
2401   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2402    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2403   "")
2404
2405 (define_split
2406   [(set (match_operand:DF 0 "push_operand" "")
2407         (match_operand:DF 1 "any_fp_register_operand" ""))]
2408   "TARGET_64BIT && reload_completed"
2409   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2410    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2411   "")
2412
2413 (define_split
2414   [(set (match_operand:DF 0 "push_operand" "")
2415         (match_operand:DF 1 "general_operand" ""))]
2416   "reload_completed"
2417   [(const_int 0)]
2418   "ix86_split_long_move (operands); DONE;")
2419
2420 ;; Moving is usually shorter when only FP registers are used. This separate
2421 ;; movdf pattern avoids the use of integer registers for FP operations
2422 ;; when optimizing for size.
2423
2424 (define_insn "*movdf_nointeger"
2425   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2426         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2427   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2428    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2429    && (reload_in_progress || reload_completed
2430        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2431        || GET_CODE (operands[1]) != CONST_DOUBLE
2432        || memory_operand (operands[0], DFmode))" 
2433 {
2434   switch (which_alternative)
2435     {
2436     case 0:
2437       return output_387_reg_move (insn, operands);
2438
2439     case 1:
2440       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2441         return "fstp%z0\t%y0";
2442       else
2443         return "fst%z0\t%y0";
2444
2445     case 2:
2446       return standard_80387_constant_opcode (operands[1]);
2447
2448     case 3:
2449     case 4:
2450       return "#";
2451     case 5:
2452       switch (get_attr_mode (insn))
2453         {
2454         case MODE_V4SF:
2455           return "xorps\t%0, %0";
2456         case MODE_V2DF:
2457           return "xorpd\t%0, %0";
2458         case MODE_TI:
2459           return "pxor\t%0, %0";
2460         default:
2461           abort ();
2462         }
2463     case 6:
2464       switch (get_attr_mode (insn))
2465         {
2466         case MODE_V4SF:
2467           return "movaps\t{%1, %0|%0, %1}";
2468         case MODE_V2DF:
2469           return "movapd\t{%1, %0|%0, %1}";
2470         case MODE_DF:
2471           return "movsd\t{%1, %0|%0, %1}";
2472         default:
2473           abort ();
2474         }
2475     case 7:
2476       if (get_attr_mode (insn) == MODE_V2DF)
2477         return "movlpd\t{%1, %0|%0, %1}";
2478       else
2479         return "movsd\t{%1, %0|%0, %1}";
2480     case 8:
2481       return "movsd\t{%1, %0|%0, %1}";
2482
2483     default:
2484       abort();
2485     }
2486 }
2487   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2488    (set (attr "mode")
2489         (cond [(eq_attr "alternative" "3,4")
2490                  (const_string "SI")
2491                /* xorps is one byte shorter.  */
2492                (eq_attr "alternative" "5")
2493                  (cond [(ne (symbol_ref "optimize_size")
2494                             (const_int 0))
2495                           (const_string "V4SF")
2496                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2497                             (const_int 0))
2498                           (const_string "TI")]
2499                        (const_string "V2DF"))
2500                /* For architectures resolving dependencies on
2501                   whole SSE registers use APD move to break dependency
2502                   chains, otherwise use short move to avoid extra work.
2503
2504                   movaps encodes one byte shorter.  */
2505                (eq_attr "alternative" "6")
2506                  (cond
2507                   [(ne (symbol_ref "optimize_size")
2508                        (const_int 0))
2509                      (const_string "V4SF")
2510                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2511                        (const_int 0))
2512                      (const_string "V2DF")]
2513                    (const_string "DF"))
2514                /* For architectures resolving dependencies on register
2515                   parts we may avoid extra work to zero out upper part
2516                   of register.  */
2517                (eq_attr "alternative" "7")
2518                  (if_then_else
2519                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2520                        (const_int 0))
2521                    (const_string "V2DF")
2522                    (const_string "DF"))]
2523                (const_string "DF")))])
2524
2525 (define_insn "*movdf_integer"
2526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2527         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2528   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2529    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2530    && (reload_in_progress || reload_completed
2531        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2532        || GET_CODE (operands[1]) != CONST_DOUBLE
2533        || memory_operand (operands[0], DFmode))" 
2534 {
2535   switch (which_alternative)
2536     {
2537     case 0:
2538       return output_387_reg_move (insn, operands);
2539
2540     case 1:
2541       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2542         return "fstp%z0\t%y0";
2543       else
2544         return "fst%z0\t%y0";
2545
2546     case 2:
2547       return standard_80387_constant_opcode (operands[1]);
2548
2549     case 3:
2550     case 4:
2551       return "#";
2552
2553     case 5:
2554       switch (get_attr_mode (insn))
2555         {
2556         case MODE_V4SF:
2557           return "xorps\t%0, %0";
2558         case MODE_V2DF:
2559           return "xorpd\t%0, %0";
2560         case MODE_TI:
2561           return "pxor\t%0, %0";
2562         default:
2563           abort ();
2564         }
2565     case 6:
2566       switch (get_attr_mode (insn))
2567         {
2568         case MODE_V4SF:
2569           return "movaps\t{%1, %0|%0, %1}";
2570         case MODE_V2DF:
2571           return "movapd\t{%1, %0|%0, %1}";
2572         case MODE_DF:
2573           return "movsd\t{%1, %0|%0, %1}";
2574         default:
2575           abort ();
2576         }
2577     case 7:
2578       if (get_attr_mode (insn) == MODE_V2DF)
2579         return "movlpd\t{%1, %0|%0, %1}";
2580       else
2581         return "movsd\t{%1, %0|%0, %1}";
2582     case 8:
2583       return "movsd\t{%1, %0|%0, %1}";
2584
2585     default:
2586       abort();
2587     }
2588 }
2589   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2590    (set (attr "mode")
2591         (cond [(eq_attr "alternative" "3,4")
2592                  (const_string "SI")
2593                /* xorps is one byte shorter.  */
2594                (eq_attr "alternative" "5")
2595                  (cond [(ne (symbol_ref "optimize_size")
2596                             (const_int 0))
2597                           (const_string "V4SF")
2598                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2599                             (const_int 0))
2600                           (const_string "TI")]
2601                        (const_string "V2DF"))
2602                /* For architectures resolving dependencies on
2603                   whole SSE registers use APD move to break dependency
2604                   chains, otherwise use short move to avoid extra work.  
2605
2606                   movaps encodes one byte shorter.  */
2607                (eq_attr "alternative" "6")
2608                  (cond
2609                   [(ne (symbol_ref "optimize_size")
2610                        (const_int 0))
2611                      (const_string "V4SF")
2612                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2613                        (const_int 0))
2614                      (const_string "V2DF")]
2615                    (const_string "DF"))
2616                /* For architectures resolving dependencies on register
2617                   parts we may avoid extra work to zero out upper part
2618                   of register.  */
2619                (eq_attr "alternative" "7")
2620                  (if_then_else
2621                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2622                        (const_int 0))
2623                    (const_string "V2DF")
2624                    (const_string "DF"))]
2625                (const_string "DF")))])
2626
2627 (define_split
2628   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2629         (match_operand:DF 1 "general_operand" ""))]
2630   "reload_completed
2631    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2632    && ! (ANY_FP_REG_P (operands[0]) || 
2633          (GET_CODE (operands[0]) == SUBREG
2634           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2635    && ! (ANY_FP_REG_P (operands[1]) || 
2636          (GET_CODE (operands[1]) == SUBREG
2637           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2638   [(const_int 0)]
2639   "ix86_split_long_move (operands); DONE;")
2640
2641 (define_insn "*swapdf"
2642   [(set (match_operand:DF 0 "register_operand" "+f")
2643         (match_operand:DF 1 "register_operand" "+f"))
2644    (set (match_dup 1)
2645         (match_dup 0))]
2646   "reload_completed || !TARGET_SSE2"
2647 {
2648   if (STACK_TOP_P (operands[0]))
2649     return "fxch\t%1";
2650   else
2651     return "fxch\t%0";
2652 }
2653   [(set_attr "type" "fxch")
2654    (set_attr "mode" "DF")])
2655
2656 (define_expand "movxf"
2657   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2658         (match_operand:XF 1 "general_operand" ""))]
2659   ""
2660   "ix86_expand_move (XFmode, operands); DONE;")
2661
2662 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references.
2666 ;; (assuming that any given constant is pushed only once, but this ought to be
2667 ;;  handled elsewhere).
2668
2669 (define_insn "*pushxf_nointeger"
2670   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2671         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2672   "optimize_size"
2673 {
2674   /* This insn should be already split before reg-stack.  */
2675   abort ();
2676 }
2677   [(set_attr "type" "multi")
2678    (set_attr "mode" "XF,SI,SI")])
2679
2680 (define_insn "*pushxf_integer"
2681   [(set (match_operand:XF 0 "push_operand" "=<,<")
2682         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2683   "!optimize_size"
2684 {
2685   /* This insn should be already split before reg-stack.  */
2686   abort ();
2687 }
2688   [(set_attr "type" "multi")
2689    (set_attr "mode" "XF,SI")])
2690
2691 (define_split
2692   [(set (match_operand 0 "push_operand" "")
2693         (match_operand 1 "general_operand" ""))]
2694   "reload_completed
2695    && (GET_MODE (operands[0]) == XFmode
2696        || GET_MODE (operands[0]) == DFmode)
2697    && !ANY_FP_REG_P (operands[1])"
2698   [(const_int 0)]
2699   "ix86_split_long_move (operands); DONE;")
2700
2701 (define_split
2702   [(set (match_operand:XF 0 "push_operand" "")
2703         (match_operand:XF 1 "any_fp_register_operand" ""))]
2704   "!TARGET_64BIT"
2705   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2706    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2707   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2708
2709 (define_split
2710   [(set (match_operand:XF 0 "push_operand" "")
2711         (match_operand:XF 1 "any_fp_register_operand" ""))]
2712   "TARGET_64BIT"
2713   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2714    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2715   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2716
2717 ;; Do not use integer registers when optimizing for size
2718 (define_insn "*movxf_nointeger"
2719   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2720         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2721   "optimize_size
2722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2723    && (reload_in_progress || reload_completed
2724        || GET_CODE (operands[1]) != CONST_DOUBLE
2725        || memory_operand (operands[0], XFmode))" 
2726 {
2727   switch (which_alternative)
2728     {
2729     case 0:
2730       return output_387_reg_move (insn, operands);
2731
2732     case 1:
2733       /* There is no non-popping store to memory for XFmode.  So if
2734          we need one, follow the store with a load.  */
2735       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2736         return "fstp%z0\t%y0\;fld%z0\t%y0";
2737       else
2738         return "fstp%z0\t%y0";
2739
2740     case 2:
2741       return standard_80387_constant_opcode (operands[1]);
2742
2743     case 3: case 4:
2744       return "#";
2745     }
2746   abort();
2747 }
2748   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2749    (set_attr "mode" "XF,XF,XF,SI,SI")])
2750
2751 (define_insn "*movxf_integer"
2752   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2753         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2754   "!optimize_size
2755    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2756    && (reload_in_progress || reload_completed
2757        || GET_CODE (operands[1]) != CONST_DOUBLE
2758        || memory_operand (operands[0], XFmode))" 
2759 {
2760   switch (which_alternative)
2761     {
2762     case 0:
2763       return output_387_reg_move (insn, operands);
2764
2765     case 1:
2766       /* There is no non-popping store to memory for XFmode.  So if
2767          we need one, follow the store with a load.  */
2768       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2769         return "fstp%z0\t%y0\;fld%z0\t%y0";
2770       else
2771         return "fstp%z0\t%y0";
2772
2773     case 2:
2774       return standard_80387_constant_opcode (operands[1]);
2775
2776     case 3: case 4:
2777       return "#";
2778     }
2779   abort();
2780 }
2781   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2782    (set_attr "mode" "XF,XF,XF,SI,SI")])
2783
2784 (define_split
2785   [(set (match_operand 0 "nonimmediate_operand" "")
2786         (match_operand 1 "general_operand" ""))]
2787   "reload_completed
2788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789    && GET_MODE (operands[0]) == XFmode
2790    && ! (ANY_FP_REG_P (operands[0]) || 
2791          (GET_CODE (operands[0]) == SUBREG
2792           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2793    && ! (ANY_FP_REG_P (operands[1]) || 
2794          (GET_CODE (operands[1]) == SUBREG
2795           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2796   [(const_int 0)]
2797   "ix86_split_long_move (operands); DONE;")
2798
2799 (define_split
2800   [(set (match_operand 0 "register_operand" "")
2801         (match_operand 1 "memory_operand" ""))]
2802   "reload_completed
2803    && GET_CODE (operands[1]) == MEM
2804    && (GET_MODE (operands[0]) == XFmode
2805        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2806    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2807    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2808   [(set (match_dup 0) (match_dup 1))]
2809 {
2810   rtx c = get_pool_constant (XEXP (operands[1], 0));
2811   rtx r = operands[0];
2812
2813   if (GET_CODE (r) == SUBREG)
2814     r = SUBREG_REG (r);
2815
2816   if (SSE_REG_P (r))
2817     {
2818       if (!standard_sse_constant_p (c))
2819         FAIL;
2820     }
2821   else if (FP_REG_P (r))
2822     {
2823       if (!standard_80387_constant_p (c))
2824         FAIL;
2825     }
2826   else if (MMX_REG_P (r))
2827     FAIL;
2828
2829   operands[1] = c;
2830 })
2831
2832 (define_insn "swapxf"
2833   [(set (match_operand:XF 0 "register_operand" "+f")
2834         (match_operand:XF 1 "register_operand" "+f"))
2835    (set (match_dup 1)
2836         (match_dup 0))]
2837   ""
2838 {
2839   if (STACK_TOP_P (operands[0]))
2840     return "fxch\t%1";
2841   else
2842     return "fxch\t%0";
2843 }
2844   [(set_attr "type" "fxch")
2845    (set_attr "mode" "XF")])
2846 \f
2847 ;; Zero extension instructions
2848
2849 (define_expand "zero_extendhisi2"
2850   [(set (match_operand:SI 0 "register_operand" "")
2851      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2852   ""
2853 {
2854   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2855     {
2856       operands[1] = force_reg (HImode, operands[1]);
2857       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2858       DONE;
2859     }
2860 })
2861
2862 (define_insn "zero_extendhisi2_and"
2863   [(set (match_operand:SI 0 "register_operand" "=r")
2864      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2865    (clobber (reg:CC FLAGS_REG))]
2866   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2867   "#"
2868   [(set_attr "type" "alu1")
2869    (set_attr "mode" "SI")])
2870
2871 (define_split
2872   [(set (match_operand:SI 0 "register_operand" "")
2873         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2874    (clobber (reg:CC FLAGS_REG))]
2875   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2876   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2877               (clobber (reg:CC FLAGS_REG))])]
2878   "")
2879
2880 (define_insn "*zero_extendhisi2_movzwl"
2881   [(set (match_operand:SI 0 "register_operand" "=r")
2882      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2883   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2884   "movz{wl|x}\t{%1, %0|%0, %1}"
2885   [(set_attr "type" "imovx")
2886    (set_attr "mode" "SI")])
2887
2888 (define_expand "zero_extendqihi2"
2889   [(parallel
2890     [(set (match_operand:HI 0 "register_operand" "")
2891        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2892      (clobber (reg:CC FLAGS_REG))])]
2893   ""
2894   "")
2895
2896 (define_insn "*zero_extendqihi2_and"
2897   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2898      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2899    (clobber (reg:CC FLAGS_REG))]
2900   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2901   "#"
2902   [(set_attr "type" "alu1")
2903    (set_attr "mode" "HI")])
2904
2905 (define_insn "*zero_extendqihi2_movzbw_and"
2906   [(set (match_operand:HI 0 "register_operand" "=r,r")
2907      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2908    (clobber (reg:CC FLAGS_REG))]
2909   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2910   "#"
2911   [(set_attr "type" "imovx,alu1")
2912    (set_attr "mode" "HI")])
2913
2914 (define_insn "*zero_extendqihi2_movzbw"
2915   [(set (match_operand:HI 0 "register_operand" "=r")
2916      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2917   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2918   "movz{bw|x}\t{%1, %0|%0, %1}"
2919   [(set_attr "type" "imovx")
2920    (set_attr "mode" "HI")])
2921
2922 ;; For the movzbw case strip only the clobber
2923 (define_split
2924   [(set (match_operand:HI 0 "register_operand" "")
2925         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2926    (clobber (reg:CC FLAGS_REG))]
2927   "reload_completed 
2928    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2929    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2930   [(set (match_operand:HI 0 "register_operand" "")
2931         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2932
2933 ;; When source and destination does not overlap, clear destination
2934 ;; first and then do the movb
2935 (define_split
2936   [(set (match_operand:HI 0 "register_operand" "")
2937         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2938    (clobber (reg:CC FLAGS_REG))]
2939   "reload_completed
2940    && ANY_QI_REG_P (operands[0])
2941    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2942    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2943   [(set (match_dup 0) (const_int 0))
2944    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2945   "operands[2] = gen_lowpart (QImode, operands[0]);")
2946
2947 ;; Rest is handled by single and.
2948 (define_split
2949   [(set (match_operand:HI 0 "register_operand" "")
2950         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2951    (clobber (reg:CC FLAGS_REG))]
2952   "reload_completed
2953    && true_regnum (operands[0]) == true_regnum (operands[1])"
2954   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2955               (clobber (reg:CC FLAGS_REG))])]
2956   "")
2957
2958 (define_expand "zero_extendqisi2"
2959   [(parallel
2960     [(set (match_operand:SI 0 "register_operand" "")
2961        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2962      (clobber (reg:CC FLAGS_REG))])]
2963   ""
2964   "")
2965
2966 (define_insn "*zero_extendqisi2_and"
2967   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2968      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2969    (clobber (reg:CC FLAGS_REG))]
2970   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2971   "#"
2972   [(set_attr "type" "alu1")
2973    (set_attr "mode" "SI")])
2974
2975 (define_insn "*zero_extendqisi2_movzbw_and"
2976   [(set (match_operand:SI 0 "register_operand" "=r,r")
2977      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2978    (clobber (reg:CC FLAGS_REG))]
2979   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2980   "#"
2981   [(set_attr "type" "imovx,alu1")
2982    (set_attr "mode" "SI")])
2983
2984 (define_insn "*zero_extendqisi2_movzbw"
2985   [(set (match_operand:SI 0 "register_operand" "=r")
2986      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2987   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2988   "movz{bl|x}\t{%1, %0|%0, %1}"
2989   [(set_attr "type" "imovx")
2990    (set_attr "mode" "SI")])
2991
2992 ;; For the movzbl case strip only the clobber
2993 (define_split
2994   [(set (match_operand:SI 0 "register_operand" "")
2995         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2996    (clobber (reg:CC FLAGS_REG))]
2997   "reload_completed 
2998    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2999    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3000   [(set (match_dup 0)
3001         (zero_extend:SI (match_dup 1)))])
3002
3003 ;; When source and destination does not overlap, clear destination
3004 ;; first and then do the movb
3005 (define_split
3006   [(set (match_operand:SI 0 "register_operand" "")
3007         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && ANY_QI_REG_P (operands[0])
3011    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3012    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3013    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3014   [(set (match_dup 0) (const_int 0))
3015    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3016   "operands[2] = gen_lowpart (QImode, operands[0]);")
3017
3018 ;; Rest is handled by single and.
3019 (define_split
3020   [(set (match_operand:SI 0 "register_operand" "")
3021         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "reload_completed
3024    && true_regnum (operands[0]) == true_regnum (operands[1])"
3025   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3026               (clobber (reg:CC FLAGS_REG))])]
3027   "")
3028
3029 ;; %%% Kill me once multi-word ops are sane.
3030 (define_expand "zero_extendsidi2"
3031   [(set (match_operand:DI 0 "register_operand" "=r")
3032      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3033   ""
3034   "if (!TARGET_64BIT)
3035      {
3036        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3037        DONE;
3038      }
3039   ")
3040
3041 (define_insn "zero_extendsidi2_32"
3042   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3043         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3044    (clobber (reg:CC FLAGS_REG))]
3045   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3046   "@
3047    #
3048    #
3049    #
3050    movd\t{%1, %0|%0, %1}
3051    movd\t{%1, %0|%0, %1}"
3052   [(set_attr "mode" "SI,SI,SI,DI,TI")
3053    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3054
3055 (define_insn "*zero_extendsidi2_32_1"
3056   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3057         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3058    (clobber (reg:CC FLAGS_REG))]
3059   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3060   "@
3061    #
3062    #
3063    #
3064    movd\t{%1, %0|%0, %1}
3065    movd\t{%1, %0|%0, %1}"
3066   [(set_attr "mode" "SI,SI,SI,DI,TI")
3067    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3068
3069 (define_insn "zero_extendsidi2_rex64"
3070   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3071      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3072   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3073   "@
3074    mov\t{%k1, %k0|%k0, %k1}
3075    #
3076    movd\t{%1, %0|%0, %1}
3077    movd\t{%1, %0|%0, %1}"
3078   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3079    (set_attr "mode" "SI,DI,DI,TI")])
3080
3081 (define_insn "*zero_extendsidi2_rex64_1"
3082   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3083      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3084   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3085   "@
3086    mov\t{%k1, %k0|%k0, %k1}
3087    #
3088    movd\t{%1, %0|%0, %1}
3089    movd\t{%1, %0|%0, %1}"
3090   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3091    (set_attr "mode" "SI,DI,SI,SI")])
3092
3093 (define_split
3094   [(set (match_operand:DI 0 "memory_operand" "")
3095      (zero_extend:DI (match_dup 0)))]
3096   "TARGET_64BIT"
3097   [(set (match_dup 4) (const_int 0))]
3098   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3099
3100 (define_split 
3101   [(set (match_operand:DI 0 "register_operand" "")
3102         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3103    (clobber (reg:CC FLAGS_REG))]
3104   "!TARGET_64BIT && reload_completed
3105    && true_regnum (operands[0]) == true_regnum (operands[1])"
3106   [(set (match_dup 4) (const_int 0))]
3107   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3108
3109 (define_split 
3110   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3111         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3112    (clobber (reg:CC FLAGS_REG))]
3113   "!TARGET_64BIT && reload_completed
3114    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3115   [(set (match_dup 3) (match_dup 1))
3116    (set (match_dup 4) (const_int 0))]
3117   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3118
3119 (define_insn "zero_extendhidi2"
3120   [(set (match_operand:DI 0 "register_operand" "=r,r")
3121      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3122   "TARGET_64BIT"
3123   "@
3124    movz{wl|x}\t{%1, %k0|%k0, %1}
3125    movz{wq|x}\t{%1, %0|%0, %1}"
3126   [(set_attr "type" "imovx")
3127    (set_attr "mode" "SI,DI")])
3128
3129 (define_insn "zero_extendqidi2"
3130   [(set (match_operand:DI 0 "register_operand" "=r,r")
3131      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3132   "TARGET_64BIT"
3133   "@
3134    movz{bl|x}\t{%1, %k0|%k0, %1}
3135    movz{bq|x}\t{%1, %0|%0, %1}"
3136   [(set_attr "type" "imovx")
3137    (set_attr "mode" "SI,DI")])
3138 \f
3139 ;; Sign extension instructions
3140
3141 (define_expand "extendsidi2"
3142   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3143                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3144               (clobber (reg:CC FLAGS_REG))
3145               (clobber (match_scratch:SI 2 ""))])]
3146   ""
3147 {
3148   if (TARGET_64BIT)
3149     {
3150       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3151       DONE;
3152     }
3153 })
3154
3155 (define_insn "*extendsidi2_1"
3156   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3157         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3158    (clobber (reg:CC FLAGS_REG))
3159    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3160   "!TARGET_64BIT"
3161   "#")
3162
3163 (define_insn "extendsidi2_rex64"
3164   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3165         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3166   "TARGET_64BIT"
3167   "@
3168    {cltq|cdqe}
3169    movs{lq|x}\t{%1,%0|%0, %1}"
3170   [(set_attr "type" "imovx")
3171    (set_attr "mode" "DI")
3172    (set_attr "prefix_0f" "0")
3173    (set_attr "modrm" "0,1")])
3174
3175 (define_insn "extendhidi2"
3176   [(set (match_operand:DI 0 "register_operand" "=r")
3177         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3178   "TARGET_64BIT"
3179   "movs{wq|x}\t{%1,%0|%0, %1}"
3180   [(set_attr "type" "imovx")
3181    (set_attr "mode" "DI")])
3182
3183 (define_insn "extendqidi2"
3184   [(set (match_operand:DI 0 "register_operand" "=r")
3185         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3186   "TARGET_64BIT"
3187   "movs{bq|x}\t{%1,%0|%0, %1}"
3188    [(set_attr "type" "imovx")
3189     (set_attr "mode" "DI")])
3190
3191 ;; Extend to memory case when source register does die.
3192 (define_split 
3193   [(set (match_operand:DI 0 "memory_operand" "")
3194         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3195    (clobber (reg:CC FLAGS_REG))
3196    (clobber (match_operand:SI 2 "register_operand" ""))]
3197   "(reload_completed
3198     && dead_or_set_p (insn, operands[1])
3199     && !reg_mentioned_p (operands[1], operands[0]))"
3200   [(set (match_dup 3) (match_dup 1))
3201    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3202               (clobber (reg:CC FLAGS_REG))])
3203    (set (match_dup 4) (match_dup 1))]
3204   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205
3206 ;; Extend to memory case when source register does not die.
3207 (define_split 
3208   [(set (match_operand:DI 0 "memory_operand" "")
3209         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3210    (clobber (reg:CC FLAGS_REG))
3211    (clobber (match_operand:SI 2 "register_operand" ""))]
3212   "reload_completed"
3213   [(const_int 0)]
3214 {
3215   split_di (&operands[0], 1, &operands[3], &operands[4]);
3216
3217   emit_move_insn (operands[3], operands[1]);
3218
3219   /* Generate a cltd if possible and doing so it profitable.  */
3220   if (true_regnum (operands[1]) == 0
3221       && true_regnum (operands[2]) == 1
3222       && (optimize_size || TARGET_USE_CLTD))
3223     {
3224       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3225     }
3226   else
3227     {
3228       emit_move_insn (operands[2], operands[1]);
3229       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3230     }
3231   emit_move_insn (operands[4], operands[2]);
3232   DONE;
3233 })
3234
3235 ;; Extend to register case.  Optimize case where source and destination
3236 ;; registers match and cases where we can use cltd.
3237 (define_split 
3238   [(set (match_operand:DI 0 "register_operand" "")
3239         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3240    (clobber (reg:CC FLAGS_REG))
3241    (clobber (match_scratch:SI 2 ""))]
3242   "reload_completed"
3243   [(const_int 0)]
3244 {
3245   split_di (&operands[0], 1, &operands[3], &operands[4]);
3246
3247   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3248     emit_move_insn (operands[3], operands[1]);
3249
3250   /* Generate a cltd if possible and doing so it profitable.  */
3251   if (true_regnum (operands[3]) == 0
3252       && (optimize_size || TARGET_USE_CLTD))
3253     {
3254       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3255       DONE;
3256     }
3257
3258   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3259     emit_move_insn (operands[4], operands[1]);
3260
3261   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3262   DONE;
3263 })
3264
3265 (define_insn "extendhisi2"
3266   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3267         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3268   ""
3269 {
3270   switch (get_attr_prefix_0f (insn))
3271     {
3272     case 0:
3273       return "{cwtl|cwde}";
3274     default:
3275       return "movs{wl|x}\t{%1,%0|%0, %1}";
3276     }
3277 }
3278   [(set_attr "type" "imovx")
3279    (set_attr "mode" "SI")
3280    (set (attr "prefix_0f")
3281      ;; movsx is short decodable while cwtl is vector decoded.
3282      (if_then_else (and (eq_attr "cpu" "!k6")
3283                         (eq_attr "alternative" "0"))
3284         (const_string "0")
3285         (const_string "1")))
3286    (set (attr "modrm")
3287      (if_then_else (eq_attr "prefix_0f" "0")
3288         (const_string "0")
3289         (const_string "1")))])
3290
3291 (define_insn "*extendhisi2_zext"
3292   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3293         (zero_extend:DI
3294           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3295   "TARGET_64BIT"
3296 {
3297   switch (get_attr_prefix_0f (insn))
3298     {
3299     case 0:
3300       return "{cwtl|cwde}";
3301     default:
3302       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3303     }
3304 }
3305   [(set_attr "type" "imovx")
3306    (set_attr "mode" "SI")
3307    (set (attr "prefix_0f")
3308      ;; movsx is short decodable while cwtl is vector decoded.
3309      (if_then_else (and (eq_attr "cpu" "!k6")
3310                         (eq_attr "alternative" "0"))
3311         (const_string "0")
3312         (const_string "1")))
3313    (set (attr "modrm")
3314      (if_then_else (eq_attr "prefix_0f" "0")
3315         (const_string "0")
3316         (const_string "1")))])
3317
3318 (define_insn "extendqihi2"
3319   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3320         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3321   ""
3322 {
3323   switch (get_attr_prefix_0f (insn))
3324     {
3325     case 0:
3326       return "{cbtw|cbw}";
3327     default:
3328       return "movs{bw|x}\t{%1,%0|%0, %1}";
3329     }
3330 }
3331   [(set_attr "type" "imovx")
3332    (set_attr "mode" "HI")
3333    (set (attr "prefix_0f")
3334      ;; movsx is short decodable while cwtl is vector decoded.
3335      (if_then_else (and (eq_attr "cpu" "!k6")
3336                         (eq_attr "alternative" "0"))
3337         (const_string "0")
3338         (const_string "1")))
3339    (set (attr "modrm")
3340      (if_then_else (eq_attr "prefix_0f" "0")
3341         (const_string "0")
3342         (const_string "1")))])
3343
3344 (define_insn "extendqisi2"
3345   [(set (match_operand:SI 0 "register_operand" "=r")
3346         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3347   ""
3348   "movs{bl|x}\t{%1,%0|%0, %1}"
3349    [(set_attr "type" "imovx")
3350     (set_attr "mode" "SI")])
3351
3352 (define_insn "*extendqisi2_zext"
3353   [(set (match_operand:DI 0 "register_operand" "=r")
3354         (zero_extend:DI
3355           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3356   "TARGET_64BIT"
3357   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3358    [(set_attr "type" "imovx")
3359     (set_attr "mode" "SI")])
3360 \f
3361 ;; Conversions between float and double.
3362
3363 ;; These are all no-ops in the model used for the 80387.  So just
3364 ;; emit moves.
3365
3366 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3367 (define_insn "*dummy_extendsfdf2"
3368   [(set (match_operand:DF 0 "push_operand" "=<")
3369         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3370   "0"
3371   "#")
3372
3373 (define_split
3374   [(set (match_operand:DF 0 "push_operand" "")
3375         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3376   "!TARGET_64BIT"
3377   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3378    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3379
3380 (define_split
3381   [(set (match_operand:DF 0 "push_operand" "")
3382         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3383   "TARGET_64BIT"
3384   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3385    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3386
3387 (define_insn "*dummy_extendsfxf2"
3388   [(set (match_operand:XF 0 "push_operand" "=<")
3389         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3390   "0"
3391   "#")
3392
3393 (define_split
3394   [(set (match_operand:XF 0 "push_operand" "")
3395         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3396   ""
3397   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3398    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3399   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3400
3401 (define_split
3402   [(set (match_operand:XF 0 "push_operand" "")
3403         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3404   "TARGET_64BIT"
3405   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3406    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3407   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3408
3409 (define_split
3410   [(set (match_operand:XF 0 "push_operand" "")
3411         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3412   ""
3413   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3414    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3415   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3416
3417 (define_split
3418   [(set (match_operand:XF 0 "push_operand" "")
3419         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3420   "TARGET_64BIT"
3421   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3422    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3423   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3424
3425 (define_expand "extendsfdf2"
3426   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3427         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3428   "TARGET_80387 || TARGET_SSE2"
3429 {
3430   /* ??? Needed for compress_float_constant since all fp constants
3431      are LEGITIMATE_CONSTANT_P.  */
3432   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3433     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3434   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3435     operands[1] = force_reg (SFmode, operands[1]);
3436 })
3437
3438 (define_insn "*extendsfdf2_1"
3439   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3440         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3441   "(TARGET_80387 || TARGET_SSE2)
3442    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3443 {
3444   switch (which_alternative)
3445     {
3446     case 0:
3447       return output_387_reg_move (insn, operands);
3448
3449     case 1:
3450       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3451         return "fstp%z0\t%y0";
3452       else
3453         return "fst%z0\t%y0";
3454
3455     case 2:
3456       return "cvtss2sd\t{%1, %0|%0, %1}";
3457
3458     default:
3459       abort ();
3460     }
3461 }
3462   [(set_attr "type" "fmov,fmov,ssecvt")
3463    (set_attr "mode" "SF,XF,DF")])
3464
3465 (define_insn "*extendsfdf2_1_sse_only"
3466   [(set (match_operand:DF 0 "register_operand" "=Y")
3467         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3468   "!TARGET_80387 && TARGET_SSE2
3469    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3470   "cvtss2sd\t{%1, %0|%0, %1}"
3471   [(set_attr "type" "ssecvt")
3472    (set_attr "mode" "DF")])
3473
3474 (define_expand "extendsfxf2"
3475   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3476         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3477   "TARGET_80387"
3478 {
3479   /* ??? Needed for compress_float_constant since all fp constants
3480      are LEGITIMATE_CONSTANT_P.  */
3481   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3482     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3483   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3484     operands[1] = force_reg (SFmode, operands[1]);
3485 })
3486
3487 (define_insn "*extendsfxf2_1"
3488   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3489         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3490   "TARGET_80387
3491    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3492 {
3493   switch (which_alternative)
3494     {
3495     case 0:
3496       return output_387_reg_move (insn, operands);
3497
3498     case 1:
3499       /* There is no non-popping store to memory for XFmode.  So if
3500          we need one, follow the store with a load.  */
3501       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3502         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3503       else
3504         return "fstp%z0\t%y0";
3505
3506     default:
3507       abort ();
3508     }
3509 }
3510   [(set_attr "type" "fmov")
3511    (set_attr "mode" "SF,XF")])
3512
3513 (define_expand "extenddfxf2"
3514   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3515         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3516   "TARGET_80387"
3517 {
3518   /* ??? Needed for compress_float_constant since all fp constants
3519      are LEGITIMATE_CONSTANT_P.  */
3520   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3521     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3523     operands[1] = force_reg (DFmode, operands[1]);
3524 })
3525
3526 (define_insn "*extenddfxf2_1"
3527   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3528         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3529   "TARGET_80387
3530    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3531 {
3532   switch (which_alternative)
3533     {
3534     case 0:
3535       return output_387_reg_move (insn, operands);
3536
3537     case 1:
3538       /* There is no non-popping store to memory for XFmode.  So if
3539          we need one, follow the store with a load.  */
3540       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3541         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3542       else
3543         return "fstp%z0\t%y0";
3544
3545     default:
3546       abort ();
3547     }
3548 }
3549   [(set_attr "type" "fmov")
3550    (set_attr "mode" "DF,XF")])
3551
3552 ;; %%% This seems bad bad news.
3553 ;; This cannot output into an f-reg because there is no way to be sure
3554 ;; of truncating in that case.  Otherwise this is just like a simple move
3555 ;; insn.  So we pretend we can output to a reg in order to get better
3556 ;; register preferencing, but we really use a stack slot.
3557
3558 (define_expand "truncdfsf2"
3559   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3560                    (float_truncate:SF
3561                     (match_operand:DF 1 "register_operand" "")))
3562               (clobber (match_dup 2))])]
3563   "TARGET_80387 || TARGET_SSE2"
3564   "
3565    if (!TARGET_80387)
3566      {
3567         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3568         DONE;
3569      }
3570    else if (flag_unsafe_math_optimizations)
3571      {
3572         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3573         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3574         if (reg != operands[0])
3575           emit_move_insn (operands[0], reg);
3576         DONE;
3577      }
3578    else
3579      operands[2] = assign_386_stack_local (SFmode, 0);
3580 ")
3581
3582 (define_insn "truncdfsf2_noop"
3583   [(set (match_operand:SF 0 "register_operand" "=f")
3584         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3585   "TARGET_80387 && flag_unsafe_math_optimizations"
3586 {
3587   return output_387_reg_move (insn, operands);
3588 }
3589   [(set_attr "type" "fmov")
3590    (set_attr "mode" "SF")])
3591
3592 (define_insn "*truncdfsf2_1"
3593   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3594         (float_truncate:SF
3595          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3596    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3597   "TARGET_80387 && !TARGET_SSE2"
3598 {
3599   switch (which_alternative)
3600     {
3601     case 0:
3602       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3603         return "fstp%z0\t%y0";
3604       else
3605         return "fst%z0\t%y0";
3606     default:
3607       abort ();
3608     }
3609 }
3610   [(set_attr "type" "fmov,multi,multi,multi")
3611    (set_attr "mode" "SF,SF,SF,SF")])
3612
3613 (define_insn "*truncdfsf2_1_sse"
3614   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3615         (float_truncate:SF
3616          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3617    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3618   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3619 {
3620   switch (which_alternative)
3621     {
3622     case 0:
3623       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624         return "fstp%z0\t%y0";
3625       else
3626         return "fst%z0\t%y0";
3627     case 4:
3628       return "#";
3629     default:
3630       abort ();
3631     }
3632 }
3633   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3634    (set_attr "mode" "SF,SF,SF,SF,DF")])
3635
3636 (define_insn "*truncdfsf2_1_sse_nooverlap"
3637   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3638         (float_truncate:SF
3639          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3640    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3641   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3642 {
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3647         return "fstp%z0\t%y0";
3648       else
3649         return "fst%z0\t%y0";
3650     case 4:
3651       return "#";
3652     default:
3653       abort ();
3654     }
3655 }
3656   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3657    (set_attr "mode" "SF,SF,SF,SF,DF")])
3658
3659 (define_insn "*truncdfsf2_2"
3660   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3661         (float_truncate:SF
3662          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3663   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3664    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3665 {
3666   switch (which_alternative)
3667     {
3668     case 0:
3669     case 1:
3670       return "cvtsd2ss\t{%1, %0|%0, %1}";
3671     case 2:
3672       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3673         return "fstp%z0\t%y0";
3674       else
3675         return "fst%z0\t%y0";
3676     default:
3677       abort ();
3678     }
3679 }
3680   [(set_attr "type" "ssecvt,ssecvt,fmov")
3681    (set_attr "athlon_decode" "vector,double,*")
3682    (set_attr "mode" "SF,SF,SF")])
3683
3684 (define_insn "*truncdfsf2_2_nooverlap"
3685   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3686         (float_truncate:SF
3687          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3688   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3689    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3690 {
3691   switch (which_alternative)
3692     {
3693     case 0:
3694       return "#";
3695     case 1:
3696       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697         return "fstp%z0\t%y0";
3698       else
3699         return "fst%z0\t%y0";
3700     default:
3701       abort ();
3702     }
3703 }
3704   [(set_attr "type" "ssecvt,fmov")
3705    (set_attr "mode" "DF,SF")])
3706
3707 (define_insn "*truncdfsf2_3"
3708   [(set (match_operand:SF 0 "memory_operand" "=m")
3709         (float_truncate:SF
3710          (match_operand:DF 1 "register_operand" "f")))]
3711   "TARGET_80387"
3712 {
3713   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3714     return "fstp%z0\t%y0";
3715   else
3716     return "fst%z0\t%y0";
3717 }
3718   [(set_attr "type" "fmov")
3719    (set_attr "mode" "SF")])
3720
3721 (define_insn "truncdfsf2_sse_only"
3722   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3723         (float_truncate:SF
3724          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3725   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3726   "cvtsd2ss\t{%1, %0|%0, %1}"
3727   [(set_attr "type" "ssecvt")
3728    (set_attr "athlon_decode" "vector,double")
3729    (set_attr "mode" "SF")])
3730
3731 (define_insn "*truncdfsf2_sse_only_nooverlap"
3732   [(set (match_operand:SF 0 "register_operand" "=&Y")
3733         (float_truncate:SF
3734          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3735   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3736   "#"
3737   [(set_attr "type" "ssecvt")
3738    (set_attr "mode" "DF")])
3739
3740 (define_split
3741   [(set (match_operand:SF 0 "memory_operand" "")
3742         (float_truncate:SF
3743          (match_operand:DF 1 "register_operand" "")))
3744    (clobber (match_operand:SF 2 "memory_operand" ""))]
3745   "TARGET_80387"
3746   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3747   "")
3748
3749 ; Avoid possible reformatting penalty on the destination by first
3750 ; zeroing it out
3751 (define_split
3752   [(set (match_operand:SF 0 "register_operand" "")
3753         (float_truncate:SF
3754          (match_operand:DF 1 "nonimmediate_operand" "")))
3755    (clobber (match_operand 2 "" ""))]
3756   "TARGET_80387 && reload_completed
3757    && SSE_REG_P (operands[0])
3758    && !STACK_REG_P (operands[1])"
3759   [(const_int 0)]
3760 {
3761   rtx src, dest;
3762   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3763     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3764   else
3765     {
3766       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3767       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3768       /* simplify_gen_subreg refuses to widen memory references.  */
3769       if (GET_CODE (src) == SUBREG)
3770         alter_subreg (&src);
3771       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3772         abort ();
3773       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3774       emit_insn (gen_cvtsd2ss (dest, dest, src));
3775     }
3776   DONE;
3777 })
3778
3779 (define_split
3780   [(set (match_operand:SF 0 "register_operand" "")
3781         (float_truncate:SF
3782          (match_operand:DF 1 "nonimmediate_operand" "")))]
3783   "TARGET_80387 && reload_completed
3784    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3785   [(const_int 0)]
3786 {
3787   rtx src, dest;
3788   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3789   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3790   /* simplify_gen_subreg refuses to widen memory references.  */
3791   if (GET_CODE (src) == SUBREG)
3792     alter_subreg (&src);
3793   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3794     abort ();
3795   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3796   emit_insn (gen_cvtsd2ss (dest, dest, src));
3797   DONE;
3798 })
3799
3800 (define_split
3801   [(set (match_operand:SF 0 "register_operand" "")
3802         (float_truncate:SF
3803          (match_operand:DF 1 "fp_register_operand" "")))
3804    (clobber (match_operand:SF 2 "memory_operand" ""))]
3805   "TARGET_80387 && reload_completed"
3806   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3807    (set (match_dup 0) (match_dup 2))]
3808   "")
3809
3810 (define_expand "truncxfsf2"
3811   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3812                    (float_truncate:SF
3813                     (match_operand:XF 1 "register_operand" "")))
3814               (clobber (match_dup 2))])]
3815   "TARGET_80387"
3816   "
3817   if (flag_unsafe_math_optimizations)
3818     {
3819       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3821       if (reg != operands[0])
3822         emit_move_insn (operands[0], reg);
3823       DONE;
3824     }
3825   else
3826     operands[2] = assign_386_stack_local (SFmode, 0);
3827   ")
3828
3829 (define_insn "truncxfsf2_noop"
3830   [(set (match_operand:SF 0 "register_operand" "=f")
3831         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3832   "TARGET_80387 && flag_unsafe_math_optimizations"
3833 {
3834   return output_387_reg_move (insn, operands);
3835 }
3836   [(set_attr "type" "fmov")
3837    (set_attr "mode" "SF")])
3838
3839 (define_insn "*truncxfsf2_1"
3840   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3841         (float_truncate:SF
3842          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844   "TARGET_80387"
3845 {
3846   switch (which_alternative)
3847     {
3848     case 0:
3849       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850         return "fstp%z0\t%y0";
3851       else
3852         return "fst%z0\t%y0";
3853     default:
3854       abort();
3855     }
3856 }
3857   [(set_attr "type" "fmov,multi,multi,multi")
3858    (set_attr "mode" "SF")])
3859
3860 (define_insn "*truncxfsf2_2"
3861   [(set (match_operand:SF 0 "memory_operand" "=m")
3862         (float_truncate:SF
3863          (match_operand:XF 1 "register_operand" "f")))]
3864   "TARGET_80387"
3865 {
3866   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867     return "fstp%z0\t%y0";
3868   else
3869     return "fst%z0\t%y0";
3870 }
3871   [(set_attr "type" "fmov")
3872    (set_attr "mode" "SF")])
3873
3874 (define_split
3875   [(set (match_operand:SF 0 "memory_operand" "")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "")))
3878    (clobber (match_operand:SF 2 "memory_operand" ""))]
3879   "TARGET_80387"
3880   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3881   "")
3882
3883 (define_split
3884   [(set (match_operand:SF 0 "register_operand" "")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "")))
3887    (clobber (match_operand:SF 2 "memory_operand" ""))]
3888   "TARGET_80387 && reload_completed"
3889   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3890    (set (match_dup 0) (match_dup 2))]
3891   "")
3892
3893 (define_expand "truncxfdf2"
3894   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3895                    (float_truncate:DF
3896                     (match_operand:XF 1 "register_operand" "")))
3897               (clobber (match_dup 2))])]
3898   "TARGET_80387"
3899   "
3900   if (flag_unsafe_math_optimizations)
3901     {
3902       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3903       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3904       if (reg != operands[0])
3905         emit_move_insn (operands[0], reg);
3906       DONE;
3907     }
3908   else
3909     operands[2] = assign_386_stack_local (DFmode, 0);
3910   ")
3911
3912 (define_insn "truncxfdf2_noop"
3913   [(set (match_operand:DF 0 "register_operand" "=f")
3914         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3915   "TARGET_80387 && flag_unsafe_math_optimizations"
3916 {
3917   return output_387_reg_move (insn, operands);
3918 }
3919   [(set_attr "type" "fmov")
3920    (set_attr "mode" "DF")])
3921
3922 (define_insn "*truncxfdf2_1"
3923   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3924         (float_truncate:DF
3925          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3926    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3927   "TARGET_80387"
3928 {
3929   switch (which_alternative)
3930     {
3931     case 0:
3932       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933         return "fstp%z0\t%y0";
3934       else
3935         return "fst%z0\t%y0";
3936     default:
3937       abort();
3938     }
3939   abort ();
3940 }
3941   [(set_attr "type" "fmov,multi,multi,multi")
3942    (set_attr "mode" "DF")])
3943
3944 (define_insn "*truncxfdf2_2"
3945   [(set (match_operand:DF 0 "memory_operand" "=m")
3946         (float_truncate:DF
3947           (match_operand:XF 1 "register_operand" "f")))]
3948   "TARGET_80387"
3949 {
3950   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3951     return "fstp%z0\t%y0";
3952   else
3953     return "fst%z0\t%y0";
3954 }
3955   [(set_attr "type" "fmov")
3956    (set_attr "mode" "DF")])
3957
3958 (define_split
3959   [(set (match_operand:DF 0 "memory_operand" "")
3960         (float_truncate:DF
3961          (match_operand:XF 1 "register_operand" "")))
3962    (clobber (match_operand:DF 2 "memory_operand" ""))]
3963   "TARGET_80387"
3964   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3965   "")
3966
3967 (define_split
3968   [(set (match_operand:DF 0 "register_operand" "")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "")))
3971    (clobber (match_operand:DF 2 "memory_operand" ""))]
3972   "TARGET_80387 && reload_completed"
3973   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3974    (set (match_dup 0) (match_dup 2))]
3975   "")
3976
3977 \f
3978 ;; %%% Break up all these bad boys.
3979
3980 ;; Signed conversion to DImode.
3981
3982 (define_expand "fix_truncxfdi2"
3983   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3984                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3985               (clobber (reg:CC FLAGS_REG))])]
3986   "TARGET_80387"
3987   "")
3988
3989 (define_expand "fix_truncdfdi2"
3990   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
3994 {
3995   if (TARGET_64BIT && TARGET_SSE2)
3996    {
3997      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3998      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
3999      if (out != operands[0])
4000         emit_move_insn (operands[0], out);
4001      DONE;
4002    }
4003 })
4004
4005 (define_expand "fix_truncsfdi2"
4006   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4007                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4008               (clobber (reg:CC FLAGS_REG))])] 
4009   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4010 {
4011   if (TARGET_SSE && TARGET_64BIT)
4012    {
4013      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4014      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4015      if (out != operands[0])
4016         emit_move_insn (operands[0], out);
4017      DONE;
4018    }
4019 })
4020
4021 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4022 ;; of the machinery.
4023 (define_insn_and_split "*fix_truncdi_1"
4024   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4025         (fix:DI (match_operand 1 "register_operand" "f,f")))
4026    (clobber (reg:CC FLAGS_REG))]
4027   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4028    && !reload_completed && !reload_in_progress
4029    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4030   "#"
4031   "&& 1"
4032   [(const_int 0)]
4033 {
4034   ix86_optimize_mode_switching = 1;
4035   operands[2] = assign_386_stack_local (HImode, 1);
4036   operands[3] = assign_386_stack_local (HImode, 2);
4037   if (memory_operand (operands[0], VOIDmode))
4038     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4039                                        operands[2], operands[3]));
4040   else
4041     {
4042       operands[4] = assign_386_stack_local (DImode, 0);
4043       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4044                                            operands[2], operands[3],
4045                                            operands[4]));
4046     }
4047   DONE;
4048 }
4049   [(set_attr "type" "fistp")
4050    (set_attr "i387_cw" "trunc")
4051    (set_attr "mode" "DI")])
4052
4053 (define_insn "fix_truncdi_nomemory"
4054   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4055         (fix:DI (match_operand 1 "register_operand" "f,f")))
4056    (use (match_operand:HI 2 "memory_operand" "m,m"))
4057    (use (match_operand:HI 3 "memory_operand" "m,m"))
4058    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4059    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4060   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4061    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4062   "#"
4063   [(set_attr "type" "fistp")
4064    (set_attr "i387_cw" "trunc")
4065    (set_attr "mode" "DI")])
4066
4067 (define_insn "fix_truncdi_memory"
4068   [(set (match_operand:DI 0 "memory_operand" "=m")
4069         (fix:DI (match_operand 1 "register_operand" "f")))
4070    (use (match_operand:HI 2 "memory_operand" "m"))
4071    (use (match_operand:HI 3 "memory_operand" "m"))
4072    (clobber (match_scratch:DF 4 "=&1f"))]
4073   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4074    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4075   "* return output_fix_trunc (insn, operands);"
4076   [(set_attr "type" "fistp")
4077    (set_attr "i387_cw" "trunc")
4078    (set_attr "mode" "DI")])
4079
4080 (define_split 
4081   [(set (match_operand:DI 0 "register_operand" "")
4082         (fix:DI (match_operand 1 "register_operand" "")))
4083    (use (match_operand:HI 2 "memory_operand" ""))
4084    (use (match_operand:HI 3 "memory_operand" ""))
4085    (clobber (match_operand:DI 4 "memory_operand" ""))
4086    (clobber (match_scratch 5 ""))]
4087   "reload_completed"
4088   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4089               (use (match_dup 2))
4090               (use (match_dup 3))
4091               (clobber (match_dup 5))])
4092    (set (match_dup 0) (match_dup 4))]
4093   "")
4094
4095 (define_split 
4096   [(set (match_operand:DI 0 "memory_operand" "")
4097         (fix:DI (match_operand 1 "register_operand" "")))
4098    (use (match_operand:HI 2 "memory_operand" ""))
4099    (use (match_operand:HI 3 "memory_operand" ""))
4100    (clobber (match_operand:DI 4 "memory_operand" ""))
4101    (clobber (match_scratch 5 ""))]
4102   "reload_completed"
4103   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4104               (use (match_dup 2))
4105               (use (match_dup 3))
4106               (clobber (match_dup 5))])]
4107   "")
4108
4109 ;; When SSE available, it is always faster to use it!
4110 (define_insn "fix_truncsfdi_sse"
4111   [(set (match_operand:DI 0 "register_operand" "=r,r")
4112         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4113   "TARGET_64BIT && TARGET_SSE"
4114   "cvttss2si{q}\t{%1, %0|%0, %1}"
4115   [(set_attr "type" "sseicvt")
4116    (set_attr "mode" "SF")
4117    (set_attr "athlon_decode" "double,vector")])
4118
4119 ;; Avoid vector decoded form of the instruction.
4120 (define_peephole2
4121   [(match_scratch:SF 2 "x")
4122    (set (match_operand:DI 0 "register_operand" "")
4123         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4124   "TARGET_K8 && !optimize_size"
4125   [(set (match_dup 2) (match_dup 1))
4126    (set (match_dup 0) (fix:DI (match_dup 2)))]
4127   "")
4128
4129 (define_insn "fix_truncdfdi_sse"
4130   [(set (match_operand:DI 0 "register_operand" "=r,r")
4131         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4132   "TARGET_64BIT && TARGET_SSE2"
4133   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4134   [(set_attr "type" "sseicvt,sseicvt")
4135    (set_attr "mode" "DF")
4136    (set_attr "athlon_decode" "double,vector")])
4137
4138 ;; Avoid vector decoded form of the instruction.
4139 (define_peephole2
4140   [(match_scratch:DF 2 "Y")
4141    (set (match_operand:DI 0 "register_operand" "")
4142         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4143   "TARGET_K8 && !optimize_size"
4144   [(set (match_dup 2) (match_dup 1))
4145    (set (match_dup 0) (fix:DI (match_dup 2)))]
4146   "")
4147
4148 ;; Signed conversion to SImode.
4149
4150 (define_expand "fix_truncxfsi2"
4151   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4152                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4153               (clobber (reg:CC FLAGS_REG))])]
4154   "TARGET_80387"
4155   "")
4156
4157 (define_expand "fix_truncdfsi2"
4158   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387 || TARGET_SSE2"
4162 {
4163   if (TARGET_SSE2)
4164    {
4165      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4166      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4167      if (out != operands[0])
4168         emit_move_insn (operands[0], out);
4169      DONE;
4170    }
4171 })
4172
4173 (define_expand "fix_truncsfsi2"
4174   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4175                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4176               (clobber (reg:CC FLAGS_REG))])] 
4177   "TARGET_80387 || TARGET_SSE"
4178 {
4179   if (TARGET_SSE)
4180    {
4181      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4182      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4183      if (out != operands[0])
4184         emit_move_insn (operands[0], out);
4185      DONE;
4186    }
4187 })
4188
4189 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4190 ;; of the machinery.
4191 (define_insn_and_split "*fix_truncsi_1"
4192   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4193         (fix:SI (match_operand 1 "register_operand" "f,f")))
4194    (clobber (reg:CC FLAGS_REG))]
4195   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4196    && !reload_completed && !reload_in_progress
4197    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4198   "#"
4199   "&& 1"
4200   [(const_int 0)]
4201 {
4202   ix86_optimize_mode_switching = 1;
4203   operands[2] = assign_386_stack_local (HImode, 1);
4204   operands[3] = assign_386_stack_local (HImode, 2);
4205   if (memory_operand (operands[0], VOIDmode))
4206     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4207                                        operands[2], operands[3]));
4208   else
4209     {
4210       operands[4] = assign_386_stack_local (SImode, 0);
4211       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4212                                            operands[2], operands[3],
4213                                            operands[4]));
4214     }
4215   DONE;
4216 }
4217   [(set_attr "type" "fistp")
4218    (set_attr "i387_cw" "trunc")
4219    (set_attr "mode" "SI")])
4220
4221 (define_insn "fix_truncsi_nomemory"
4222   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4223         (fix:SI (match_operand 1 "register_operand" "f,f")))
4224    (use (match_operand:HI 2 "memory_operand" "m,m"))
4225    (use (match_operand:HI 3 "memory_operand" "m,m"))
4226    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4227   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4229   "#"
4230   [(set_attr "type" "fistp")
4231    (set_attr "i387_cw" "trunc")
4232    (set_attr "mode" "SI")])
4233
4234 (define_insn "fix_truncsi_memory"
4235   [(set (match_operand:SI 0 "memory_operand" "=m")
4236         (fix:SI (match_operand 1 "register_operand" "f")))
4237    (use (match_operand:HI 2 "memory_operand" "m"))
4238    (use (match_operand:HI 3 "memory_operand" "m"))]
4239   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4240    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4241   "* return output_fix_trunc (insn, operands);"
4242   [(set_attr "type" "fistp")
4243    (set_attr "i387_cw" "trunc")
4244    (set_attr "mode" "SI")])
4245
4246 ;; When SSE available, it is always faster to use it!
4247 (define_insn "fix_truncsfsi_sse"
4248   [(set (match_operand:SI 0 "register_operand" "=r,r")
4249         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4250   "TARGET_SSE"
4251   "cvttss2si\t{%1, %0|%0, %1}"
4252   [(set_attr "type" "sseicvt")
4253    (set_attr "mode" "DF")
4254    (set_attr "athlon_decode" "double,vector")])
4255
4256 ;; Avoid vector decoded form of the instruction.
4257 (define_peephole2
4258   [(match_scratch:SF 2 "x")
4259    (set (match_operand:SI 0 "register_operand" "")
4260         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4261   "TARGET_K8 && !optimize_size"
4262   [(set (match_dup 2) (match_dup 1))
4263    (set (match_dup 0) (fix:SI (match_dup 2)))]
4264   "")
4265
4266 (define_insn "fix_truncdfsi_sse"
4267   [(set (match_operand:SI 0 "register_operand" "=r,r")
4268         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4269   "TARGET_SSE2"
4270   "cvttsd2si\t{%1, %0|%0, %1}"
4271   [(set_attr "type" "sseicvt")
4272    (set_attr "mode" "DF")
4273    (set_attr "athlon_decode" "double,vector")])
4274
4275 ;; Avoid vector decoded form of the instruction.
4276 (define_peephole2
4277   [(match_scratch:DF 2 "Y")
4278    (set (match_operand:SI 0 "register_operand" "")
4279         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4280   "TARGET_K8 && !optimize_size"
4281   [(set (match_dup 2) (match_dup 1))
4282    (set (match_dup 0) (fix:SI (match_dup 2)))]
4283   "")
4284
4285 (define_split 
4286   [(set (match_operand:SI 0 "register_operand" "")
4287         (fix:SI (match_operand 1 "register_operand" "")))
4288    (use (match_operand:HI 2 "memory_operand" ""))
4289    (use (match_operand:HI 3 "memory_operand" ""))
4290    (clobber (match_operand:SI 4 "memory_operand" ""))]
4291   "reload_completed"
4292   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4293               (use (match_dup 2))
4294               (use (match_dup 3))])
4295    (set (match_dup 0) (match_dup 4))]
4296   "")
4297
4298 (define_split 
4299   [(set (match_operand:SI 0 "memory_operand" "")
4300         (fix:SI (match_operand 1 "register_operand" "")))
4301    (use (match_operand:HI 2 "memory_operand" ""))
4302    (use (match_operand:HI 3 "memory_operand" ""))
4303    (clobber (match_operand:SI 4 "memory_operand" ""))]
4304   "reload_completed"
4305   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4306               (use (match_dup 2))
4307               (use (match_dup 3))])]
4308   "")
4309
4310 ;; Signed conversion to HImode.
4311
4312 (define_expand "fix_truncxfhi2"
4313   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4314                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4315               (clobber (reg:CC FLAGS_REG))])] 
4316   "TARGET_80387"
4317   "")
4318
4319 (define_expand "fix_truncdfhi2"
4320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4322               (clobber (reg:CC FLAGS_REG))])]
4323   "TARGET_80387 && !TARGET_SSE2"
4324   "")
4325
4326 (define_expand "fix_truncsfhi2"
4327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4329                (clobber (reg:CC FLAGS_REG))])]
4330   "TARGET_80387 && !TARGET_SSE"
4331   "")
4332
4333 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4334 ;; of the machinery.
4335 (define_insn_and_split "*fix_trunchi_1"
4336   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4337         (fix:HI (match_operand 1 "register_operand" "f,f")))
4338    (clobber (reg:CC FLAGS_REG))]
4339   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !reload_completed && !reload_in_progress
4341    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342   "#"
4343   "&& 1"
4344   [(const_int 0)]
4345 {
4346   ix86_optimize_mode_switching = 1;
4347   operands[2] = assign_386_stack_local (HImode, 1);
4348   operands[3] = assign_386_stack_local (HImode, 2);
4349   if (memory_operand (operands[0], VOIDmode))
4350     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4351                                        operands[2], operands[3]));
4352   else
4353     {
4354       operands[4] = assign_386_stack_local (HImode, 0);
4355       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4356                                            operands[2], operands[3],
4357                                            operands[4]));
4358     }
4359   DONE;
4360 }
4361   [(set_attr "type" "fistp")
4362    (set_attr "i387_cw" "trunc")
4363    (set_attr "mode" "HI")])
4364
4365 (define_insn "fix_trunchi_nomemory"
4366   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4367         (fix:HI (match_operand 1 "register_operand" "f,f")))
4368    (use (match_operand:HI 2 "memory_operand" "m,m"))
4369    (use (match_operand:HI 3 "memory_operand" "m,m"))
4370    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4371   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373   "#"
4374   [(set_attr "type" "fistp")
4375    (set_attr "i387_cw" "trunc")
4376    (set_attr "mode" "HI")])
4377
4378 (define_insn "fix_trunchi_memory"
4379   [(set (match_operand:HI 0 "memory_operand" "=m")
4380         (fix:HI (match_operand 1 "register_operand" "f")))
4381    (use (match_operand:HI 2 "memory_operand" "m"))
4382    (use (match_operand:HI 3 "memory_operand" "m"))]
4383   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4385   "* return output_fix_trunc (insn, operands);"
4386   [(set_attr "type" "fistp")
4387    (set_attr "i387_cw" "trunc")
4388    (set_attr "mode" "HI")])
4389
4390 (define_split 
4391   [(set (match_operand:HI 0 "memory_operand" "")
4392         (fix:HI (match_operand 1 "register_operand" "")))
4393    (use (match_operand:HI 2 "memory_operand" ""))
4394    (use (match_operand:HI 3 "memory_operand" ""))
4395    (clobber (match_operand:HI 4 "memory_operand" ""))]
4396   "reload_completed"
4397   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4398               (use (match_dup 2))
4399               (use (match_dup 3))])]
4400   "")
4401
4402 (define_split 
4403   [(set (match_operand:HI 0 "register_operand" "")
4404         (fix:HI (match_operand 1 "register_operand" "")))
4405    (use (match_operand:HI 2 "memory_operand" ""))
4406    (use (match_operand:HI 3 "memory_operand" ""))
4407    (clobber (match_operand:HI 4 "memory_operand" ""))]
4408   "reload_completed"
4409   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4410               (use (match_dup 2))
4411               (use (match_dup 3))
4412               (clobber (match_dup 4))])
4413    (set (match_dup 0) (match_dup 4))]
4414   "")
4415
4416 (define_insn "x86_fnstcw_1"
4417   [(set (match_operand:HI 0 "memory_operand" "=m")
4418         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4419   "TARGET_80387"
4420   "fnstcw\t%0"
4421   [(set_attr "length" "2")
4422    (set_attr "mode" "HI")
4423    (set_attr "unit" "i387")])
4424
4425 (define_insn "x86_fldcw_1"
4426   [(set (reg:HI FPSR_REG)
4427         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4428   "TARGET_80387"
4429   "fldcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")
4433    (set_attr "athlon_decode" "vector")])
4434 \f
4435 ;; Conversion between fixed point and floating point.
4436
4437 ;; Even though we only accept memory inputs, the backend _really_
4438 ;; wants to be able to do this between registers.
4439
4440 (define_expand "floathisf2"
4441   [(set (match_operand:SF 0 "register_operand" "")
4442         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4443   "TARGET_SSE || TARGET_80387"
4444 {
4445   if (TARGET_SSE && TARGET_SSE_MATH)
4446     {
4447       emit_insn (gen_floatsisf2 (operands[0],
4448                                  convert_to_mode (SImode, operands[1], 0)));
4449       DONE;
4450     }
4451 })
4452
4453 (define_insn "*floathisf2_1"
4454   [(set (match_operand:SF 0 "register_operand" "=f,f")
4455         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4456   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4457   "@
4458    fild%z1\t%1
4459    #"
4460   [(set_attr "type" "fmov,multi")
4461    (set_attr "mode" "SF")
4462    (set_attr "fp_int_src" "true")])
4463
4464 (define_expand "floatsisf2"
4465   [(set (match_operand:SF 0 "register_operand" "")
4466         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4467   "TARGET_SSE || TARGET_80387"
4468   "")
4469
4470 (define_insn "*floatsisf2_i387"
4471   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4472         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4473   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4474   "@
4475    fild%z1\t%1
4476    #
4477    cvtsi2ss\t{%1, %0|%0, %1}
4478    cvtsi2ss\t{%1, %0|%0, %1}"
4479   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4480    (set_attr "mode" "SF")
4481    (set_attr "athlon_decode" "*,*,vector,double")
4482    (set_attr "fp_int_src" "true")])
4483
4484 (define_insn "*floatsisf2_sse"
4485   [(set (match_operand:SF 0 "register_operand" "=x,x")
4486         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4487   "TARGET_SSE"
4488   "cvtsi2ss\t{%1, %0|%0, %1}"
4489   [(set_attr "type" "sseicvt")
4490    (set_attr "mode" "SF")
4491    (set_attr "athlon_decode" "vector,double")
4492    (set_attr "fp_int_src" "true")])
4493
4494 ; Avoid possible reformatting penalty on the destination by first
4495 ; zeroing it out
4496 (define_split
4497   [(set (match_operand:SF 0 "register_operand" "")
4498         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4499   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4500    && SSE_REG_P (operands[0])"
4501   [(const_int 0)]
4502 {
4503   rtx dest;
4504   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4505   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4506   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4507   DONE;
4508 })
4509
4510 (define_expand "floatdisf2"
4511   [(set (match_operand:SF 0 "register_operand" "")
4512         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4514   "")
4515
4516 (define_insn "*floatdisf2_i387_only"
4517   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4518         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4519   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4520   "@
4521    fild%z1\t%1
4522    #"
4523   [(set_attr "type" "fmov,multi")
4524    (set_attr "mode" "SF")
4525    (set_attr "fp_int_src" "true")])
4526
4527 (define_insn "*floatdisf2_i387"
4528   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4529         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4530   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4531   "@
4532    fild%z1\t%1
4533    #
4534    cvtsi2ss{q}\t{%1, %0|%0, %1}
4535    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4537    (set_attr "mode" "SF")
4538    (set_attr "athlon_decode" "*,*,vector,double")
4539    (set_attr "fp_int_src" "true")])
4540
4541 (define_insn "*floatdisf2_sse"
4542   [(set (match_operand:SF 0 "register_operand" "=x,x")
4543         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4544   "TARGET_64BIT && TARGET_SSE"
4545   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4546   [(set_attr "type" "sseicvt")
4547    (set_attr "mode" "SF")
4548    (set_attr "athlon_decode" "vector,double")
4549    (set_attr "fp_int_src" "true")])
4550
4551 ; Avoid possible reformatting penalty on the destination by first
4552 ; zeroing it out
4553 (define_split
4554   [(set (match_operand:SF 0 "register_operand" "")
4555         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4557    && SSE_REG_P (operands[0])"
4558   [(const_int 0)]
4559 {
4560   rtx dest;
4561   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4562   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4563   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4564   DONE;
4565 })
4566
4567 (define_expand "floathidf2"
4568   [(set (match_operand:DF 0 "register_operand" "")
4569         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4570   "TARGET_SSE2 || TARGET_80387"
4571 {
4572   if (TARGET_SSE && TARGET_SSE_MATH)
4573     {
4574       emit_insn (gen_floatsidf2 (operands[0],
4575                                  convert_to_mode (SImode, operands[1], 0)));
4576       DONE;
4577     }
4578 })
4579
4580 (define_insn "*floathidf2_1"
4581   [(set (match_operand:DF 0 "register_operand" "=f,f")
4582         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4583   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4584   "@
4585    fild%z1\t%1
4586    #"
4587   [(set_attr "type" "fmov,multi")
4588    (set_attr "mode" "DF")
4589    (set_attr "fp_int_src" "true")])
4590
4591 (define_expand "floatsidf2"
4592   [(set (match_operand:DF 0 "register_operand" "")
4593         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4594   "TARGET_80387 || TARGET_SSE2"
4595   "")
4596
4597 (define_insn "*floatsidf2_i387"
4598   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4599         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4600   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4601   "@
4602    fild%z1\t%1
4603    #
4604    cvtsi2sd\t{%1, %0|%0, %1}
4605    cvtsi2sd\t{%1, %0|%0, %1}"
4606   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4607    (set_attr "mode" "DF")
4608    (set_attr "athlon_decode" "*,*,double,direct")
4609    (set_attr "fp_int_src" "true")])
4610
4611 (define_insn "*floatsidf2_sse"
4612   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4613         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4614   "TARGET_SSE2"
4615   "cvtsi2sd\t{%1, %0|%0, %1}"
4616   [(set_attr "type" "sseicvt")
4617    (set_attr "mode" "DF")
4618    (set_attr "athlon_decode" "double,direct")
4619    (set_attr "fp_int_src" "true")])
4620
4621 (define_expand "floatdidf2"
4622   [(set (match_operand:DF 0 "register_operand" "")
4623         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4625   "")
4626
4627 (define_insn "*floatdidf2_i387_only"
4628   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4629         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4630   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4631   "@
4632    fild%z1\t%1
4633    #"
4634   [(set_attr "type" "fmov,multi")
4635    (set_attr "mode" "DF")
4636    (set_attr "fp_int_src" "true")])
4637
4638 (define_insn "*floatdidf2_i387"
4639   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4640         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4641   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4642   "@
4643    fild%z1\t%1
4644    #
4645    cvtsi2sd{q}\t{%1, %0|%0, %1}
4646    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4648    (set_attr "mode" "DF")
4649    (set_attr "athlon_decode" "*,*,double,direct")
4650    (set_attr "fp_int_src" "true")])
4651
4652 (define_insn "*floatdidf2_sse"
4653   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4654         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4655   "TARGET_SSE2"
4656   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4657   [(set_attr "type" "sseicvt")
4658    (set_attr "mode" "DF")
4659    (set_attr "athlon_decode" "double,direct")
4660    (set_attr "fp_int_src" "true")])
4661
4662 (define_insn "floathixf2"
4663   [(set (match_operand:XF 0 "register_operand" "=f,f")
4664         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4665   "TARGET_80387"
4666   "@
4667    fild%z1\t%1
4668    #"
4669   [(set_attr "type" "fmov,multi")
4670    (set_attr "mode" "XF")
4671    (set_attr "fp_int_src" "true")])
4672
4673 (define_insn "floatsixf2"
4674   [(set (match_operand:XF 0 "register_operand" "=f,f")
4675         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4676   "TARGET_80387"
4677   "@
4678    fild%z1\t%1
4679    #"
4680   [(set_attr "type" "fmov,multi")
4681    (set_attr "mode" "XF")
4682    (set_attr "fp_int_src" "true")])
4683
4684 (define_insn "floatdixf2"
4685   [(set (match_operand:XF 0 "register_operand" "=f,f")
4686         (float:XF (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" "XF")
4693    (set_attr "fp_int_src" "true")])
4694
4695 ;; %%% Kill these when reload knows how to do it.
4696 (define_split
4697   [(set (match_operand 0 "fp_register_operand" "")
4698         (float (match_operand 1 "register_operand" "")))]
4699   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4700   [(const_int 0)]
4701 {
4702   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4703   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4704   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4705   ix86_free_from_memory (GET_MODE (operands[1]));
4706   DONE;
4707 })
4708
4709 (define_expand "floatunssisf2"
4710   [(use (match_operand:SF 0 "register_operand" ""))
4711    (use (match_operand:SI 1 "register_operand" ""))]
4712   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4713   "x86_emit_floatuns (operands); DONE;")
4714
4715 (define_expand "floatunsdisf2"
4716   [(use (match_operand:SF 0 "register_operand" ""))
4717    (use (match_operand:DI 1 "register_operand" ""))]
4718   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4719   "x86_emit_floatuns (operands); DONE;")
4720
4721 (define_expand "floatunsdidf2"
4722   [(use (match_operand:DF 0 "register_operand" ""))
4723    (use (match_operand:DI 1 "register_operand" ""))]
4724   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4725   "x86_emit_floatuns (operands); DONE;")
4726 \f
4727 ;; SSE extract/set expanders
4728
4729 (define_expand "vec_setv2df"
4730   [(match_operand:V2DF 0 "register_operand" "")
4731    (match_operand:DF 1 "register_operand" "")
4732    (match_operand 2 "const_int_operand" "")]
4733   "TARGET_SSE2"
4734 {
4735   switch (INTVAL (operands[2]))
4736     {
4737     case 0:
4738       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4739                                  simplify_gen_subreg (V2DFmode, operands[1],
4740                                                       DFmode, 0)));
4741       break;
4742     case 1:
4743       {
4744         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4745
4746         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4747       }
4748       break;
4749     default:
4750       abort ();
4751     }
4752   DONE;
4753 })
4754
4755 (define_expand "vec_extractv2df"
4756   [(match_operand:DF 0 "register_operand" "")
4757    (match_operand:V2DF 1 "register_operand" "")
4758    (match_operand 2 "const_int_operand" "")]
4759   "TARGET_SSE2"
4760 {
4761   switch (INTVAL (operands[2]))
4762     {
4763     case 0:
4764       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4765       break;
4766     case 1:
4767       {
4768         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4769
4770         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4771       }
4772       break;
4773     default:
4774       abort ();
4775     }
4776   DONE;
4777 })
4778
4779 (define_expand "vec_initv2df"
4780   [(match_operand:V2DF 0 "register_operand" "")
4781    (match_operand 1 "" "")]
4782   "TARGET_SSE2"
4783 {
4784   ix86_expand_vector_init (operands[0], operands[1]);
4785   DONE;
4786 })
4787
4788 (define_expand "vec_setv4sf"
4789   [(match_operand:V4SF 0 "register_operand" "")
4790    (match_operand:SF 1 "register_operand" "")
4791    (match_operand 2 "const_int_operand" "")]
4792   "TARGET_SSE"
4793 {
4794   switch (INTVAL (operands[2]))
4795     {
4796     case 0:
4797       emit_insn (gen_sse_movss (operands[0], operands[0],
4798                                 simplify_gen_subreg (V4SFmode, operands[1],
4799                                                      SFmode, 0)));
4800       break;
4801     case 1:
4802       {
4803         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4804         rtx tmp = gen_reg_rtx (V4SFmode);
4805  
4806         emit_move_insn (tmp, operands[0]);
4807         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4808         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4809         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4810                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4811       }
4812       break;
4813     case 2:
4814       {
4815         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4816         rtx tmp = gen_reg_rtx (V4SFmode);
4817
4818         emit_move_insn (tmp, operands[0]);
4819         emit_insn (gen_sse_movss (tmp, tmp, op1));
4820         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4821                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4822       }
4823       break;
4824     case 3:
4825       {
4826         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4827         rtx tmp = gen_reg_rtx (V4SFmode);
4828
4829         emit_move_insn (tmp, operands[0]);
4830         emit_insn (gen_sse_movss (tmp, tmp, op1));
4831         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4832                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4833       }
4834       break;
4835     default:
4836       abort ();
4837     }
4838   DONE;
4839 })
4840
4841 (define_expand "vec_extractv4sf"
4842   [(match_operand:SF 0 "register_operand" "")
4843    (match_operand:V4SF 1 "register_operand" "")
4844    (match_operand 2 "const_int_operand" "")]
4845   "TARGET_SSE"
4846 {
4847   switch (INTVAL (operands[2]))
4848     {
4849     case 0:
4850       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4851       break;
4852     case 1:
4853       {
4854         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4855         rtx tmp = gen_reg_rtx (V4SFmode);
4856  
4857         emit_move_insn (tmp, operands[1]);
4858         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4859                                    const1_rtx));
4860       }
4861       break;
4862     case 2:
4863       {
4864         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4865         rtx tmp = gen_reg_rtx (V4SFmode);
4866  
4867         emit_move_insn (tmp, operands[1]);
4868         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4869       }
4870       break;
4871     case 3:
4872       {
4873         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4874         rtx tmp = gen_reg_rtx (V4SFmode);
4875  
4876         emit_move_insn (tmp, operands[1]);
4877         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4878                                    GEN_INT (3)));
4879       }
4880       break;
4881     default:
4882       abort ();
4883     }
4884   DONE;
4885 })
4886
4887 (define_expand "vec_initv4sf"
4888   [(match_operand:V4SF 0 "register_operand" "")
4889    (match_operand 1 "" "")]
4890   "TARGET_SSE"
4891 {
4892   ix86_expand_vector_init (operands[0], operands[1]);
4893   DONE;
4894 })
4895 \f
4896 ;; Add instructions
4897
4898 ;; %%% splits for addsidi3
4899 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4900 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4901 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4902
4903 (define_expand "adddi3"
4904   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4905         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4906                  (match_operand:DI 2 "x86_64_general_operand" "")))
4907    (clobber (reg:CC FLAGS_REG))]
4908   ""
4909   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4910
4911 (define_insn "*adddi3_1"
4912   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4913         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4914                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4915    (clobber (reg:CC FLAGS_REG))]
4916   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4917   "#")
4918
4919 (define_split
4920   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4921         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4922                  (match_operand:DI 2 "general_operand" "")))
4923    (clobber (reg:CC FLAGS_REG))]
4924   "!TARGET_64BIT && reload_completed"
4925   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4926                                           UNSPEC_ADD_CARRY))
4927               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4928    (parallel [(set (match_dup 3)
4929                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4930                                      (match_dup 4))
4931                             (match_dup 5)))
4932               (clobber (reg:CC FLAGS_REG))])]
4933   "split_di (operands+0, 1, operands+0, operands+3);
4934    split_di (operands+1, 1, operands+1, operands+4);
4935    split_di (operands+2, 1, operands+2, operands+5);")
4936
4937 (define_insn "adddi3_carry_rex64"
4938   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4939           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4940                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4941                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4942    (clobber (reg:CC FLAGS_REG))]
4943   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4944   "adc{q}\t{%2, %0|%0, %2}"
4945   [(set_attr "type" "alu")
4946    (set_attr "pent_pair" "pu")
4947    (set_attr "mode" "DI")])
4948
4949 (define_insn "*adddi3_cc_rex64"
4950   [(set (reg:CC FLAGS_REG)
4951         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4952                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4953                    UNSPEC_ADD_CARRY))
4954    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4955         (plus:DI (match_dup 1) (match_dup 2)))]
4956   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4957   "add{q}\t{%2, %0|%0, %2}"
4958   [(set_attr "type" "alu")
4959    (set_attr "mode" "DI")])
4960
4961 (define_insn "addqi3_carry"
4962   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4963           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4964                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4965                    (match_operand:QI 2 "general_operand" "qi,qm")))
4966    (clobber (reg:CC FLAGS_REG))]
4967   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4968   "adc{b}\t{%2, %0|%0, %2}"
4969   [(set_attr "type" "alu")
4970    (set_attr "pent_pair" "pu")
4971    (set_attr "mode" "QI")])
4972
4973 (define_insn "addhi3_carry"
4974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4975           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4976                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4977                    (match_operand:HI 2 "general_operand" "ri,rm")))
4978    (clobber (reg:CC FLAGS_REG))]
4979   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4980   "adc{w}\t{%2, %0|%0, %2}"
4981   [(set_attr "type" "alu")
4982    (set_attr "pent_pair" "pu")
4983    (set_attr "mode" "HI")])
4984
4985 (define_insn "addsi3_carry"
4986   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4987           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4988                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4989                    (match_operand:SI 2 "general_operand" "ri,rm")))
4990    (clobber (reg:CC FLAGS_REG))]
4991   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4992   "adc{l}\t{%2, %0|%0, %2}"
4993   [(set_attr "type" "alu")
4994    (set_attr "pent_pair" "pu")
4995    (set_attr "mode" "SI")])
4996
4997 (define_insn "*addsi3_carry_zext"
4998   [(set (match_operand:DI 0 "register_operand" "=r")
4999           (zero_extend:DI 
5000             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5001                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5002                      (match_operand:SI 2 "general_operand" "rim"))))
5003    (clobber (reg:CC FLAGS_REG))]
5004   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5005   "adc{l}\t{%2, %k0|%k0, %2}"
5006   [(set_attr "type" "alu")
5007    (set_attr "pent_pair" "pu")
5008    (set_attr "mode" "SI")])
5009
5010 (define_insn "*addsi3_cc"
5011   [(set (reg:CC FLAGS_REG)
5012         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5013                     (match_operand:SI 2 "general_operand" "ri,rm")]
5014                    UNSPEC_ADD_CARRY))
5015    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5016         (plus:SI (match_dup 1) (match_dup 2)))]
5017   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5018   "add{l}\t{%2, %0|%0, %2}"
5019   [(set_attr "type" "alu")
5020    (set_attr "mode" "SI")])
5021
5022 (define_insn "addqi3_cc"
5023   [(set (reg:CC FLAGS_REG)
5024         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5025                     (match_operand:QI 2 "general_operand" "qi,qm")]
5026                    UNSPEC_ADD_CARRY))
5027    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5028         (plus:QI (match_dup 1) (match_dup 2)))]
5029   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5030   "add{b}\t{%2, %0|%0, %2}"
5031   [(set_attr "type" "alu")
5032    (set_attr "mode" "QI")])
5033
5034 (define_expand "addsi3"
5035   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5036                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5037                             (match_operand:SI 2 "general_operand" "")))
5038               (clobber (reg:CC FLAGS_REG))])]
5039   ""
5040   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5041
5042 (define_insn "*lea_1"
5043   [(set (match_operand:SI 0 "register_operand" "=r")
5044         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5045   "!TARGET_64BIT"
5046   "lea{l}\t{%a1, %0|%0, %a1}"
5047   [(set_attr "type" "lea")
5048    (set_attr "mode" "SI")])
5049
5050 (define_insn "*lea_1_rex64"
5051   [(set (match_operand:SI 0 "register_operand" "=r")
5052         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5053   "TARGET_64BIT"
5054   "lea{l}\t{%a1, %0|%0, %a1}"
5055   [(set_attr "type" "lea")
5056    (set_attr "mode" "SI")])
5057
5058 (define_insn "*lea_1_zext"
5059   [(set (match_operand:DI 0 "register_operand" "=r")
5060         (zero_extend:DI
5061          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5062   "TARGET_64BIT"
5063   "lea{l}\t{%a1, %k0|%k0, %a1}"
5064   [(set_attr "type" "lea")
5065    (set_attr "mode" "SI")])
5066
5067 (define_insn "*lea_2_rex64"
5068   [(set (match_operand:DI 0 "register_operand" "=r")
5069         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5070   "TARGET_64BIT"
5071   "lea{q}\t{%a1, %0|%0, %a1}"
5072   [(set_attr "type" "lea")
5073    (set_attr "mode" "DI")])
5074
5075 ;; The lea patterns for non-Pmodes needs to be matched by several
5076 ;; insns converted to real lea by splitters.
5077
5078 (define_insn_and_split "*lea_general_1"
5079   [(set (match_operand 0 "register_operand" "=r")
5080         (plus (plus (match_operand 1 "index_register_operand" "l")
5081                     (match_operand 2 "register_operand" "r"))
5082               (match_operand 3 "immediate_operand" "i")))]
5083   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5084     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5085    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5086    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5087    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5088    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5089        || GET_MODE (operands[3]) == VOIDmode)"
5090   "#"
5091   "&& reload_completed"
5092   [(const_int 0)]
5093 {
5094   rtx pat;
5095   operands[0] = gen_lowpart (SImode, operands[0]);
5096   operands[1] = gen_lowpart (Pmode, operands[1]);
5097   operands[2] = gen_lowpart (Pmode, operands[2]);
5098   operands[3] = gen_lowpart (Pmode, operands[3]);
5099   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5100                       operands[3]);
5101   if (Pmode != SImode)
5102     pat = gen_rtx_SUBREG (SImode, pat, 0);
5103   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5104   DONE;
5105 }
5106   [(set_attr "type" "lea")
5107    (set_attr "mode" "SI")])
5108
5109 (define_insn_and_split "*lea_general_1_zext"
5110   [(set (match_operand:DI 0 "register_operand" "=r")
5111         (zero_extend:DI
5112           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5113                             (match_operand:SI 2 "register_operand" "r"))
5114                    (match_operand:SI 3 "immediate_operand" "i"))))]
5115   "TARGET_64BIT"
5116   "#"
5117   "&& reload_completed"
5118   [(set (match_dup 0)
5119         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5120                                                      (match_dup 2))
5121                                             (match_dup 3)) 0)))]
5122 {
5123   operands[1] = gen_lowpart (Pmode, operands[1]);
5124   operands[2] = gen_lowpart (Pmode, operands[2]);
5125   operands[3] = gen_lowpart (Pmode, operands[3]);
5126 }
5127   [(set_attr "type" "lea")
5128    (set_attr "mode" "SI")])
5129
5130 (define_insn_and_split "*lea_general_2"
5131   [(set (match_operand 0 "register_operand" "=r")
5132         (plus (mult (match_operand 1 "index_register_operand" "l")
5133                     (match_operand 2 "const248_operand" "i"))
5134               (match_operand 3 "nonmemory_operand" "ri")))]
5135   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5136     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5137    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5138    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5139    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5140        || GET_MODE (operands[3]) == VOIDmode)"
5141   "#"
5142   "&& reload_completed"
5143   [(const_int 0)]
5144 {
5145   rtx pat;
5146   operands[0] = gen_lowpart (SImode, operands[0]);
5147   operands[1] = gen_lowpart (Pmode, operands[1]);
5148   operands[3] = gen_lowpart (Pmode, operands[3]);
5149   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5150                       operands[3]);
5151   if (Pmode != SImode)
5152     pat = gen_rtx_SUBREG (SImode, pat, 0);
5153   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5154   DONE;
5155 }
5156   [(set_attr "type" "lea")
5157    (set_attr "mode" "SI")])
5158
5159 (define_insn_and_split "*lea_general_2_zext"
5160   [(set (match_operand:DI 0 "register_operand" "=r")
5161         (zero_extend:DI
5162           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5163                             (match_operand:SI 2 "const248_operand" "n"))
5164                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5165   "TARGET_64BIT"
5166   "#"
5167   "&& reload_completed"
5168   [(set (match_dup 0)
5169         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5170                                                      (match_dup 2))
5171                                             (match_dup 3)) 0)))]
5172 {
5173   operands[1] = gen_lowpart (Pmode, operands[1]);
5174   operands[3] = gen_lowpart (Pmode, operands[3]);
5175 }
5176   [(set_attr "type" "lea")
5177    (set_attr "mode" "SI")])
5178
5179 (define_insn_and_split "*lea_general_3"
5180   [(set (match_operand 0 "register_operand" "=r")
5181         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5182                           (match_operand 2 "const248_operand" "i"))
5183                     (match_operand 3 "register_operand" "r"))
5184               (match_operand 4 "immediate_operand" "i")))]
5185   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5186     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5187    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5188    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5189    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5190   "#"
5191   "&& reload_completed"
5192   [(const_int 0)]
5193 {
5194   rtx pat;
5195   operands[0] = gen_lowpart (SImode, operands[0]);
5196   operands[1] = gen_lowpart (Pmode, operands[1]);
5197   operands[3] = gen_lowpart (Pmode, operands[3]);
5198   operands[4] = gen_lowpart (Pmode, operands[4]);
5199   pat = gen_rtx_PLUS (Pmode,
5200                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5201                                                          operands[2]),
5202                                     operands[3]),
5203                       operands[4]);
5204   if (Pmode != SImode)
5205     pat = gen_rtx_SUBREG (SImode, pat, 0);
5206   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5207   DONE;
5208 }
5209   [(set_attr "type" "lea")
5210    (set_attr "mode" "SI")])
5211
5212 (define_insn_and_split "*lea_general_3_zext"
5213   [(set (match_operand:DI 0 "register_operand" "=r")
5214         (zero_extend:DI
5215           (plus:SI (plus:SI (mult:SI
5216                               (match_operand:SI 1 "index_register_operand" "l")
5217                               (match_operand:SI 2 "const248_operand" "n"))
5218                             (match_operand:SI 3 "register_operand" "r"))
5219                    (match_operand:SI 4 "immediate_operand" "i"))))]
5220   "TARGET_64BIT"
5221   "#"
5222   "&& reload_completed"
5223   [(set (match_dup 0)
5224         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5225                                                               (match_dup 2))
5226                                                      (match_dup 3))
5227                                             (match_dup 4)) 0)))]
5228 {
5229   operands[1] = gen_lowpart (Pmode, operands[1]);
5230   operands[3] = gen_lowpart (Pmode, operands[3]);
5231   operands[4] = gen_lowpart (Pmode, operands[4]);
5232 }
5233   [(set_attr "type" "lea")
5234    (set_attr "mode" "SI")])
5235
5236 (define_insn "*adddi_1_rex64"
5237   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5238         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5239                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5240    (clobber (reg:CC FLAGS_REG))]
5241   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5242 {
5243   switch (get_attr_type (insn))
5244     {
5245     case TYPE_LEA:
5246       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5247       return "lea{q}\t{%a2, %0|%0, %a2}";
5248
5249     case TYPE_INCDEC:
5250       if (! rtx_equal_p (operands[0], operands[1]))
5251         abort ();
5252       if (operands[2] == const1_rtx)
5253         return "inc{q}\t%0";
5254       else if (operands[2] == constm1_rtx)
5255         return "dec{q}\t%0";
5256       else
5257         abort ();
5258
5259     default:
5260       if (! rtx_equal_p (operands[0], operands[1]))
5261         abort ();
5262
5263       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5264          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5265       if (GET_CODE (operands[2]) == CONST_INT
5266           /* Avoid overflows.  */
5267           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5268           && (INTVAL (operands[2]) == 128
5269               || (INTVAL (operands[2]) < 0
5270                   && INTVAL (operands[2]) != -128)))
5271         {
5272           operands[2] = GEN_INT (-INTVAL (operands[2]));
5273           return "sub{q}\t{%2, %0|%0, %2}";
5274         }
5275       return "add{q}\t{%2, %0|%0, %2}";
5276     }
5277 }
5278   [(set (attr "type")
5279      (cond [(eq_attr "alternative" "2")
5280               (const_string "lea")
5281             ; Current assemblers are broken and do not allow @GOTOFF in
5282             ; ought but a memory context.
5283             (match_operand:DI 2 "pic_symbolic_operand" "")
5284               (const_string "lea")
5285             (match_operand:DI 2 "incdec_operand" "")
5286               (const_string "incdec")
5287            ]
5288            (const_string "alu")))
5289    (set_attr "mode" "DI")])
5290
5291 ;; Convert lea to the lea pattern to avoid flags dependency.
5292 (define_split
5293   [(set (match_operand:DI 0 "register_operand" "")
5294         (plus:DI (match_operand:DI 1 "register_operand" "")
5295                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5296    (clobber (reg:CC FLAGS_REG))]
5297   "TARGET_64BIT && reload_completed
5298    && true_regnum (operands[0]) != true_regnum (operands[1])"
5299   [(set (match_dup 0)
5300         (plus:DI (match_dup 1)
5301                  (match_dup 2)))]
5302   "")
5303
5304 (define_insn "*adddi_2_rex64"
5305   [(set (reg FLAGS_REG)
5306         (compare
5307           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5308                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5309           (const_int 0)))                       
5310    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5311         (plus:DI (match_dup 1) (match_dup 2)))]
5312   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5313    && ix86_binary_operator_ok (PLUS, DImode, operands)
5314    /* Current assemblers are broken and do not allow @GOTOFF in
5315       ought but a memory context.  */
5316    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5317 {
5318   switch (get_attr_type (insn))
5319     {
5320     case TYPE_INCDEC:
5321       if (! rtx_equal_p (operands[0], operands[1]))
5322         abort ();
5323       if (operands[2] == const1_rtx)
5324         return "inc{q}\t%0";
5325       else if (operands[2] == constm1_rtx)
5326         return "dec{q}\t%0";
5327       else
5328         abort ();
5329
5330     default:
5331       if (! rtx_equal_p (operands[0], operands[1]))
5332         abort ();
5333       /* ???? We ought to handle there the 32bit case too
5334          - do we need new constraint?  */
5335       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5336          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5337       if (GET_CODE (operands[2]) == CONST_INT
5338           /* Avoid overflows.  */
5339           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5340           && (INTVAL (operands[2]) == 128
5341               || (INTVAL (operands[2]) < 0
5342                   && INTVAL (operands[2]) != -128)))
5343         {
5344           operands[2] = GEN_INT (-INTVAL (operands[2]));
5345           return "sub{q}\t{%2, %0|%0, %2}";
5346         }
5347       return "add{q}\t{%2, %0|%0, %2}";
5348     }
5349 }
5350   [(set (attr "type")
5351      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5352         (const_string "incdec")
5353         (const_string "alu")))
5354    (set_attr "mode" "DI")])
5355
5356 (define_insn "*adddi_3_rex64"
5357   [(set (reg FLAGS_REG)
5358         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5359                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5360    (clobber (match_scratch:DI 0 "=r"))]
5361   "TARGET_64BIT
5362    && ix86_match_ccmode (insn, CCZmode)
5363    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5364    /* Current assemblers are broken and do not allow @GOTOFF in
5365       ought but a memory context.  */
5366    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5367 {
5368   switch (get_attr_type (insn))
5369     {
5370     case TYPE_INCDEC:
5371       if (! rtx_equal_p (operands[0], operands[1]))
5372         abort ();
5373       if (operands[2] == const1_rtx)
5374         return "inc{q}\t%0";
5375       else if (operands[2] == constm1_rtx)
5376         return "dec{q}\t%0";
5377       else
5378         abort ();
5379
5380     default:
5381       if (! rtx_equal_p (operands[0], operands[1]))
5382         abort ();
5383       /* ???? We ought to handle there the 32bit case too
5384          - do we need new constraint?  */
5385       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5386          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5387       if (GET_CODE (operands[2]) == CONST_INT
5388           /* Avoid overflows.  */
5389           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5390           && (INTVAL (operands[2]) == 128
5391               || (INTVAL (operands[2]) < 0
5392                   && INTVAL (operands[2]) != -128)))
5393         {
5394           operands[2] = GEN_INT (-INTVAL (operands[2]));
5395           return "sub{q}\t{%2, %0|%0, %2}";
5396         }
5397       return "add{q}\t{%2, %0|%0, %2}";
5398     }
5399 }
5400   [(set (attr "type")
5401      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5402         (const_string "incdec")
5403         (const_string "alu")))
5404    (set_attr "mode" "DI")])
5405
5406 ; For comparisons against 1, -1 and 128, we may generate better code
5407 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5408 ; is matched then.  We can't accept general immediate, because for
5409 ; case of overflows,  the result is messed up.
5410 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5411 ; when negated.
5412 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5413 ; only for comparisons not depending on it.
5414 (define_insn "*adddi_4_rex64"
5415   [(set (reg FLAGS_REG)
5416         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5417                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5418    (clobber (match_scratch:DI 0 "=rm"))]
5419   "TARGET_64BIT
5420    &&  ix86_match_ccmode (insn, CCGCmode)"
5421 {
5422   switch (get_attr_type (insn))
5423     {
5424     case TYPE_INCDEC:
5425       if (operands[2] == constm1_rtx)
5426         return "inc{q}\t%0";
5427       else if (operands[2] == const1_rtx)
5428         return "dec{q}\t%0";
5429       else
5430         abort();
5431
5432     default:
5433       if (! rtx_equal_p (operands[0], operands[1]))
5434         abort ();
5435       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5436          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5437       if ((INTVAL (operands[2]) == -128
5438            || (INTVAL (operands[2]) > 0
5439                && INTVAL (operands[2]) != 128))
5440           /* Avoid overflows.  */
5441           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5442         return "sub{q}\t{%2, %0|%0, %2}";
5443       operands[2] = GEN_INT (-INTVAL (operands[2]));
5444       return "add{q}\t{%2, %0|%0, %2}";
5445     }
5446 }
5447   [(set (attr "type")
5448      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5449         (const_string "incdec")
5450         (const_string "alu")))
5451    (set_attr "mode" "DI")])
5452
5453 (define_insn "*adddi_5_rex64"
5454   [(set (reg FLAGS_REG)
5455         (compare
5456           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5457                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5458           (const_int 0)))                       
5459    (clobber (match_scratch:DI 0 "=r"))]
5460   "TARGET_64BIT
5461    && ix86_match_ccmode (insn, CCGOCmode)
5462    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5463    /* Current assemblers are broken and do not allow @GOTOFF in
5464       ought but a memory context.  */
5465    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5466 {
5467   switch (get_attr_type (insn))
5468     {
5469     case TYPE_INCDEC:
5470       if (! rtx_equal_p (operands[0], operands[1]))
5471         abort ();
5472       if (operands[2] == const1_rtx)
5473         return "inc{q}\t%0";
5474       else if (operands[2] == constm1_rtx)
5475         return "dec{q}\t%0";
5476       else
5477         abort();
5478
5479     default:
5480       if (! rtx_equal_p (operands[0], operands[1]))
5481         abort ();
5482       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5483          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5484       if (GET_CODE (operands[2]) == CONST_INT
5485           /* Avoid overflows.  */
5486           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5487           && (INTVAL (operands[2]) == 128
5488               || (INTVAL (operands[2]) < 0
5489                   && INTVAL (operands[2]) != -128)))
5490         {
5491           operands[2] = GEN_INT (-INTVAL (operands[2]));
5492           return "sub{q}\t{%2, %0|%0, %2}";
5493         }
5494       return "add{q}\t{%2, %0|%0, %2}";
5495     }
5496 }
5497   [(set (attr "type")
5498      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5499         (const_string "incdec")
5500         (const_string "alu")))
5501    (set_attr "mode" "DI")])
5502
5503
5504 (define_insn "*addsi_1"
5505   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5506         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5507                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5508    (clobber (reg:CC FLAGS_REG))]
5509   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5510 {
5511   switch (get_attr_type (insn))
5512     {
5513     case TYPE_LEA:
5514       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5515       return "lea{l}\t{%a2, %0|%0, %a2}";
5516
5517     case TYPE_INCDEC:
5518       if (! rtx_equal_p (operands[0], operands[1]))
5519         abort ();
5520       if (operands[2] == const1_rtx)
5521         return "inc{l}\t%0";
5522       else if (operands[2] == constm1_rtx)
5523         return "dec{l}\t%0";
5524       else
5525         abort();
5526
5527     default:
5528       if (! rtx_equal_p (operands[0], operands[1]))
5529         abort ();
5530
5531       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5532          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5533       if (GET_CODE (operands[2]) == CONST_INT
5534           && (INTVAL (operands[2]) == 128
5535               || (INTVAL (operands[2]) < 0
5536                   && INTVAL (operands[2]) != -128)))
5537         {
5538           operands[2] = GEN_INT (-INTVAL (operands[2]));
5539           return "sub{l}\t{%2, %0|%0, %2}";
5540         }
5541       return "add{l}\t{%2, %0|%0, %2}";
5542     }
5543 }
5544   [(set (attr "type")
5545      (cond [(eq_attr "alternative" "2")
5546               (const_string "lea")
5547             ; Current assemblers are broken and do not allow @GOTOFF in
5548             ; ought but a memory context.
5549             (match_operand:SI 2 "pic_symbolic_operand" "")
5550               (const_string "lea")
5551             (match_operand:SI 2 "incdec_operand" "")
5552               (const_string "incdec")
5553            ]
5554            (const_string "alu")))
5555    (set_attr "mode" "SI")])
5556
5557 ;; Convert lea to the lea pattern to avoid flags dependency.
5558 (define_split
5559   [(set (match_operand 0 "register_operand" "")
5560         (plus (match_operand 1 "register_operand" "")
5561               (match_operand 2 "nonmemory_operand" "")))
5562    (clobber (reg:CC FLAGS_REG))]
5563   "reload_completed
5564    && true_regnum (operands[0]) != true_regnum (operands[1])"
5565   [(const_int 0)]
5566 {
5567   rtx pat;
5568   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5569      may confuse gen_lowpart.  */
5570   if (GET_MODE (operands[0]) != Pmode)
5571     {
5572       operands[1] = gen_lowpart (Pmode, operands[1]);
5573       operands[2] = gen_lowpart (Pmode, operands[2]);
5574     }
5575   operands[0] = gen_lowpart (SImode, operands[0]);
5576   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5577   if (Pmode != SImode)
5578     pat = gen_rtx_SUBREG (SImode, pat, 0);
5579   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5580   DONE;
5581 })
5582
5583 ;; It may seem that nonimmediate operand is proper one for operand 1.
5584 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5585 ;; we take care in ix86_binary_operator_ok to not allow two memory
5586 ;; operands so proper swapping will be done in reload.  This allow
5587 ;; patterns constructed from addsi_1 to match.
5588 (define_insn "addsi_1_zext"
5589   [(set (match_operand:DI 0 "register_operand" "=r,r")
5590         (zero_extend:DI
5591           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5592                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5593    (clobber (reg:CC FLAGS_REG))]
5594   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5595 {
5596   switch (get_attr_type (insn))
5597     {
5598     case TYPE_LEA:
5599       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5600       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5601
5602     case TYPE_INCDEC:
5603       if (operands[2] == const1_rtx)
5604         return "inc{l}\t%k0";
5605       else if (operands[2] == constm1_rtx)
5606         return "dec{l}\t%k0";
5607       else
5608         abort();
5609
5610     default:
5611       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5612          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5613       if (GET_CODE (operands[2]) == CONST_INT
5614           && (INTVAL (operands[2]) == 128
5615               || (INTVAL (operands[2]) < 0
5616                   && INTVAL (operands[2]) != -128)))
5617         {
5618           operands[2] = GEN_INT (-INTVAL (operands[2]));
5619           return "sub{l}\t{%2, %k0|%k0, %2}";
5620         }
5621       return "add{l}\t{%2, %k0|%k0, %2}";
5622     }
5623 }
5624   [(set (attr "type")
5625      (cond [(eq_attr "alternative" "1")
5626               (const_string "lea")
5627             ; Current assemblers are broken and do not allow @GOTOFF in
5628             ; ought but a memory context.
5629             (match_operand:SI 2 "pic_symbolic_operand" "")
5630               (const_string "lea")
5631             (match_operand:SI 2 "incdec_operand" "")
5632               (const_string "incdec")
5633            ]
5634            (const_string "alu")))
5635    (set_attr "mode" "SI")])
5636
5637 ;; Convert lea to the lea pattern to avoid flags dependency.
5638 (define_split
5639   [(set (match_operand:DI 0 "register_operand" "")
5640         (zero_extend:DI
5641           (plus:SI (match_operand:SI 1 "register_operand" "")
5642                    (match_operand:SI 2 "nonmemory_operand" ""))))
5643    (clobber (reg:CC FLAGS_REG))]
5644   "TARGET_64BIT && reload_completed
5645    && true_regnum (operands[0]) != true_regnum (operands[1])"
5646   [(set (match_dup 0)
5647         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5648 {
5649   operands[1] = gen_lowpart (Pmode, operands[1]);
5650   operands[2] = gen_lowpart (Pmode, operands[2]);
5651 })
5652
5653 (define_insn "*addsi_2"
5654   [(set (reg FLAGS_REG)
5655         (compare
5656           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5657                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5658           (const_int 0)))                       
5659    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5660         (plus:SI (match_dup 1) (match_dup 2)))]
5661   "ix86_match_ccmode (insn, CCGOCmode)
5662    && ix86_binary_operator_ok (PLUS, SImode, operands)
5663    /* Current assemblers are broken and do not allow @GOTOFF in
5664       ought but a memory context.  */
5665    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5666 {
5667   switch (get_attr_type (insn))
5668     {
5669     case TYPE_INCDEC:
5670       if (! rtx_equal_p (operands[0], operands[1]))
5671         abort ();
5672       if (operands[2] == const1_rtx)
5673         return "inc{l}\t%0";
5674       else if (operands[2] == constm1_rtx)
5675         return "dec{l}\t%0";
5676       else
5677         abort();
5678
5679     default:
5680       if (! rtx_equal_p (operands[0], operands[1]))
5681         abort ();
5682       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5683          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5684       if (GET_CODE (operands[2]) == CONST_INT
5685           && (INTVAL (operands[2]) == 128
5686               || (INTVAL (operands[2]) < 0
5687                   && INTVAL (operands[2]) != -128)))
5688         {
5689           operands[2] = GEN_INT (-INTVAL (operands[2]));
5690           return "sub{l}\t{%2, %0|%0, %2}";
5691         }
5692       return "add{l}\t{%2, %0|%0, %2}";
5693     }
5694 }
5695   [(set (attr "type")
5696      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5697         (const_string "incdec")
5698         (const_string "alu")))
5699    (set_attr "mode" "SI")])
5700
5701 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5702 (define_insn "*addsi_2_zext"
5703   [(set (reg FLAGS_REG)
5704         (compare
5705           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5706                    (match_operand:SI 2 "general_operand" "rmni"))
5707           (const_int 0)))                       
5708    (set (match_operand:DI 0 "register_operand" "=r")
5709         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5710   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5711    && ix86_binary_operator_ok (PLUS, SImode, operands)
5712    /* Current assemblers are broken and do not allow @GOTOFF in
5713       ought but a memory context.  */
5714    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5715 {
5716   switch (get_attr_type (insn))
5717     {
5718     case TYPE_INCDEC:
5719       if (operands[2] == const1_rtx)
5720         return "inc{l}\t%k0";
5721       else if (operands[2] == constm1_rtx)
5722         return "dec{l}\t%k0";
5723       else
5724         abort();
5725
5726     default:
5727       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5728          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5729       if (GET_CODE (operands[2]) == CONST_INT
5730           && (INTVAL (operands[2]) == 128
5731               || (INTVAL (operands[2]) < 0
5732                   && INTVAL (operands[2]) != -128)))
5733         {
5734           operands[2] = GEN_INT (-INTVAL (operands[2]));
5735           return "sub{l}\t{%2, %k0|%k0, %2}";
5736         }
5737       return "add{l}\t{%2, %k0|%k0, %2}";
5738     }
5739 }
5740   [(set (attr "type")
5741      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5742         (const_string "incdec")
5743         (const_string "alu")))
5744    (set_attr "mode" "SI")])
5745
5746 (define_insn "*addsi_3"
5747   [(set (reg FLAGS_REG)
5748         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5749                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5750    (clobber (match_scratch:SI 0 "=r"))]
5751   "ix86_match_ccmode (insn, CCZmode)
5752    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5753    /* Current assemblers are broken and do not allow @GOTOFF in
5754       ought but a memory context.  */
5755    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5756 {
5757   switch (get_attr_type (insn))
5758     {
5759     case TYPE_INCDEC:
5760       if (! rtx_equal_p (operands[0], operands[1]))
5761         abort ();
5762       if (operands[2] == const1_rtx)
5763         return "inc{l}\t%0";
5764       else if (operands[2] == constm1_rtx)
5765         return "dec{l}\t%0";
5766       else
5767         abort();
5768
5769     default:
5770       if (! rtx_equal_p (operands[0], operands[1]))
5771         abort ();
5772       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5773          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5774       if (GET_CODE (operands[2]) == CONST_INT
5775           && (INTVAL (operands[2]) == 128
5776               || (INTVAL (operands[2]) < 0
5777                   && INTVAL (operands[2]) != -128)))
5778         {
5779           operands[2] = GEN_INT (-INTVAL (operands[2]));
5780           return "sub{l}\t{%2, %0|%0, %2}";
5781         }
5782       return "add{l}\t{%2, %0|%0, %2}";
5783     }
5784 }
5785   [(set (attr "type")
5786      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5787         (const_string "incdec")
5788         (const_string "alu")))
5789    (set_attr "mode" "SI")])
5790
5791 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5792 (define_insn "*addsi_3_zext"
5793   [(set (reg FLAGS_REG)
5794         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5795                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5796    (set (match_operand:DI 0 "register_operand" "=r")
5797         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5798   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5799    && ix86_binary_operator_ok (PLUS, SImode, operands)
5800    /* Current assemblers are broken and do not allow @GOTOFF in
5801       ought but a memory context.  */
5802    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5803 {
5804   switch (get_attr_type (insn))
5805     {
5806     case TYPE_INCDEC:
5807       if (operands[2] == const1_rtx)
5808         return "inc{l}\t%k0";
5809       else if (operands[2] == constm1_rtx)
5810         return "dec{l}\t%k0";
5811       else
5812         abort();
5813
5814     default:
5815       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5816          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5817       if (GET_CODE (operands[2]) == CONST_INT
5818           && (INTVAL (operands[2]) == 128
5819               || (INTVAL (operands[2]) < 0
5820                   && INTVAL (operands[2]) != -128)))
5821         {
5822           operands[2] = GEN_INT (-INTVAL (operands[2]));
5823           return "sub{l}\t{%2, %k0|%k0, %2}";
5824         }
5825       return "add{l}\t{%2, %k0|%k0, %2}";
5826     }
5827 }
5828   [(set (attr "type")
5829      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5830         (const_string "incdec")
5831         (const_string "alu")))
5832    (set_attr "mode" "SI")])
5833
5834 ; For comparisons against 1, -1 and 128, we may generate better code
5835 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5836 ; is matched then.  We can't accept general immediate, because for
5837 ; case of overflows,  the result is messed up.
5838 ; This pattern also don't hold of 0x80000000, since the value overflows
5839 ; when negated.
5840 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5841 ; only for comparisons not depending on it.
5842 (define_insn "*addsi_4"
5843   [(set (reg FLAGS_REG)
5844         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5845                  (match_operand:SI 2 "const_int_operand" "n")))
5846    (clobber (match_scratch:SI 0 "=rm"))]
5847   "ix86_match_ccmode (insn, CCGCmode)
5848    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5849 {
5850   switch (get_attr_type (insn))
5851     {
5852     case TYPE_INCDEC:
5853       if (operands[2] == constm1_rtx)
5854         return "inc{l}\t%0";
5855       else if (operands[2] == const1_rtx)
5856         return "dec{l}\t%0";
5857       else
5858         abort();
5859
5860     default:
5861       if (! rtx_equal_p (operands[0], operands[1]))
5862         abort ();
5863       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5864          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5865       if ((INTVAL (operands[2]) == -128
5866            || (INTVAL (operands[2]) > 0
5867                && INTVAL (operands[2]) != 128)))
5868         return "sub{l}\t{%2, %0|%0, %2}";
5869       operands[2] = GEN_INT (-INTVAL (operands[2]));
5870       return "add{l}\t{%2, %0|%0, %2}";
5871     }
5872 }
5873   [(set (attr "type")
5874      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5875         (const_string "incdec")
5876         (const_string "alu")))
5877    (set_attr "mode" "SI")])
5878
5879 (define_insn "*addsi_5"
5880   [(set (reg FLAGS_REG)
5881         (compare
5882           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5883                    (match_operand:SI 2 "general_operand" "rmni"))
5884           (const_int 0)))                       
5885    (clobber (match_scratch:SI 0 "=r"))]
5886   "ix86_match_ccmode (insn, CCGOCmode)
5887    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5888    /* Current assemblers are broken and do not allow @GOTOFF in
5889       ought but a memory context.  */
5890    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5891 {
5892   switch (get_attr_type (insn))
5893     {
5894     case TYPE_INCDEC:
5895       if (! rtx_equal_p (operands[0], operands[1]))
5896         abort ();
5897       if (operands[2] == const1_rtx)
5898         return "inc{l}\t%0";
5899       else if (operands[2] == constm1_rtx)
5900         return "dec{l}\t%0";
5901       else
5902         abort();
5903
5904     default:
5905       if (! rtx_equal_p (operands[0], operands[1]))
5906         abort ();
5907       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5908          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5909       if (GET_CODE (operands[2]) == CONST_INT
5910           && (INTVAL (operands[2]) == 128
5911               || (INTVAL (operands[2]) < 0
5912                   && INTVAL (operands[2]) != -128)))
5913         {
5914           operands[2] = GEN_INT (-INTVAL (operands[2]));
5915           return "sub{l}\t{%2, %0|%0, %2}";
5916         }
5917       return "add{l}\t{%2, %0|%0, %2}";
5918     }
5919 }
5920   [(set (attr "type")
5921      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5922         (const_string "incdec")
5923         (const_string "alu")))
5924    (set_attr "mode" "SI")])
5925
5926 (define_expand "addhi3"
5927   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5928                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5929                             (match_operand:HI 2 "general_operand" "")))
5930               (clobber (reg:CC FLAGS_REG))])]
5931   "TARGET_HIMODE_MATH"
5932   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5933
5934 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5935 ;; type optimizations enabled by define-splits.  This is not important
5936 ;; for PII, and in fact harmful because of partial register stalls.
5937
5938 (define_insn "*addhi_1_lea"
5939   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5940         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5941                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5942    (clobber (reg:CC FLAGS_REG))]
5943   "!TARGET_PARTIAL_REG_STALL
5944    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5945 {
5946   switch (get_attr_type (insn))
5947     {
5948     case TYPE_LEA:
5949       return "#";
5950     case TYPE_INCDEC:
5951       if (operands[2] == const1_rtx)
5952         return "inc{w}\t%0";
5953       else if (operands[2] == constm1_rtx)
5954         return "dec{w}\t%0";
5955       abort();
5956
5957     default:
5958       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5959          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5960       if (GET_CODE (operands[2]) == CONST_INT
5961           && (INTVAL (operands[2]) == 128
5962               || (INTVAL (operands[2]) < 0
5963                   && INTVAL (operands[2]) != -128)))
5964         {
5965           operands[2] = GEN_INT (-INTVAL (operands[2]));
5966           return "sub{w}\t{%2, %0|%0, %2}";
5967         }
5968       return "add{w}\t{%2, %0|%0, %2}";
5969     }
5970 }
5971   [(set (attr "type")
5972      (if_then_else (eq_attr "alternative" "2")
5973         (const_string "lea")
5974         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5975            (const_string "incdec")
5976            (const_string "alu"))))
5977    (set_attr "mode" "HI,HI,SI")])
5978
5979 (define_insn "*addhi_1"
5980   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5981         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5982                  (match_operand:HI 2 "general_operand" "ri,rm")))
5983    (clobber (reg:CC FLAGS_REG))]
5984   "TARGET_PARTIAL_REG_STALL
5985    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5986 {
5987   switch (get_attr_type (insn))
5988     {
5989     case TYPE_INCDEC:
5990       if (operands[2] == const1_rtx)
5991         return "inc{w}\t%0";
5992       else if (operands[2] == constm1_rtx)
5993         return "dec{w}\t%0";
5994       abort();
5995
5996     default:
5997       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5998          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5999       if (GET_CODE (operands[2]) == CONST_INT
6000           && (INTVAL (operands[2]) == 128
6001               || (INTVAL (operands[2]) < 0
6002                   && INTVAL (operands[2]) != -128)))
6003         {
6004           operands[2] = GEN_INT (-INTVAL (operands[2]));
6005           return "sub{w}\t{%2, %0|%0, %2}";
6006         }
6007       return "add{w}\t{%2, %0|%0, %2}";
6008     }
6009 }
6010   [(set (attr "type")
6011      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6012         (const_string "incdec")
6013         (const_string "alu")))
6014    (set_attr "mode" "HI")])
6015
6016 (define_insn "*addhi_2"
6017   [(set (reg FLAGS_REG)
6018         (compare
6019           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6020                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6021           (const_int 0)))                       
6022    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6023         (plus:HI (match_dup 1) (match_dup 2)))]
6024   "ix86_match_ccmode (insn, CCGOCmode)
6025    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6026 {
6027   switch (get_attr_type (insn))
6028     {
6029     case TYPE_INCDEC:
6030       if (operands[2] == const1_rtx)
6031         return "inc{w}\t%0";
6032       else if (operands[2] == constm1_rtx)
6033         return "dec{w}\t%0";
6034       abort();
6035
6036     default:
6037       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6038          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6039       if (GET_CODE (operands[2]) == CONST_INT
6040           && (INTVAL (operands[2]) == 128
6041               || (INTVAL (operands[2]) < 0
6042                   && INTVAL (operands[2]) != -128)))
6043         {
6044           operands[2] = GEN_INT (-INTVAL (operands[2]));
6045           return "sub{w}\t{%2, %0|%0, %2}";
6046         }
6047       return "add{w}\t{%2, %0|%0, %2}";
6048     }
6049 }
6050   [(set (attr "type")
6051      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6052         (const_string "incdec")
6053         (const_string "alu")))
6054    (set_attr "mode" "HI")])
6055
6056 (define_insn "*addhi_3"
6057   [(set (reg FLAGS_REG)
6058         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6059                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6060    (clobber (match_scratch:HI 0 "=r"))]
6061   "ix86_match_ccmode (insn, CCZmode)
6062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6063 {
6064   switch (get_attr_type (insn))
6065     {
6066     case TYPE_INCDEC:
6067       if (operands[2] == const1_rtx)
6068         return "inc{w}\t%0";
6069       else if (operands[2] == constm1_rtx)
6070         return "dec{w}\t%0";
6071       abort();
6072
6073     default:
6074       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6075          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6076       if (GET_CODE (operands[2]) == CONST_INT
6077           && (INTVAL (operands[2]) == 128
6078               || (INTVAL (operands[2]) < 0
6079                   && INTVAL (operands[2]) != -128)))
6080         {
6081           operands[2] = GEN_INT (-INTVAL (operands[2]));
6082           return "sub{w}\t{%2, %0|%0, %2}";
6083         }
6084       return "add{w}\t{%2, %0|%0, %2}";
6085     }
6086 }
6087   [(set (attr "type")
6088      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6089         (const_string "incdec")
6090         (const_string "alu")))
6091    (set_attr "mode" "HI")])
6092
6093 ; See comments above addsi_3_imm for details.
6094 (define_insn "*addhi_4"
6095   [(set (reg FLAGS_REG)
6096         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6097                  (match_operand:HI 2 "const_int_operand" "n")))
6098    (clobber (match_scratch:HI 0 "=rm"))]
6099   "ix86_match_ccmode (insn, CCGCmode)
6100    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6101 {
6102   switch (get_attr_type (insn))
6103     {
6104     case TYPE_INCDEC:
6105       if (operands[2] == constm1_rtx)
6106         return "inc{w}\t%0";
6107       else if (operands[2] == const1_rtx)
6108         return "dec{w}\t%0";
6109       else
6110         abort();
6111
6112     default:
6113       if (! rtx_equal_p (operands[0], operands[1]))
6114         abort ();
6115       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6116          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6117       if ((INTVAL (operands[2]) == -128
6118            || (INTVAL (operands[2]) > 0
6119                && INTVAL (operands[2]) != 128)))
6120         return "sub{w}\t{%2, %0|%0, %2}";
6121       operands[2] = GEN_INT (-INTVAL (operands[2]));
6122       return "add{w}\t{%2, %0|%0, %2}";
6123     }
6124 }
6125   [(set (attr "type")
6126      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6127         (const_string "incdec")
6128         (const_string "alu")))
6129    (set_attr "mode" "SI")])
6130
6131
6132 (define_insn "*addhi_5"
6133   [(set (reg FLAGS_REG)
6134         (compare
6135           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6136                    (match_operand:HI 2 "general_operand" "rmni"))
6137           (const_int 0)))                       
6138    (clobber (match_scratch:HI 0 "=r"))]
6139   "ix86_match_ccmode (insn, CCGOCmode)
6140    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6141 {
6142   switch (get_attr_type (insn))
6143     {
6144     case TYPE_INCDEC:
6145       if (operands[2] == const1_rtx)
6146         return "inc{w}\t%0";
6147       else if (operands[2] == constm1_rtx)
6148         return "dec{w}\t%0";
6149       abort();
6150
6151     default:
6152       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6153          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6154       if (GET_CODE (operands[2]) == CONST_INT
6155           && (INTVAL (operands[2]) == 128
6156               || (INTVAL (operands[2]) < 0
6157                   && INTVAL (operands[2]) != -128)))
6158         {
6159           operands[2] = GEN_INT (-INTVAL (operands[2]));
6160           return "sub{w}\t{%2, %0|%0, %2}";
6161         }
6162       return "add{w}\t{%2, %0|%0, %2}";
6163     }
6164 }
6165   [(set (attr "type")
6166      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6167         (const_string "incdec")
6168         (const_string "alu")))
6169    (set_attr "mode" "HI")])
6170
6171 (define_expand "addqi3"
6172   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6173                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6174                             (match_operand:QI 2 "general_operand" "")))
6175               (clobber (reg:CC FLAGS_REG))])]
6176   "TARGET_QIMODE_MATH"
6177   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6178
6179 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6180 (define_insn "*addqi_1_lea"
6181   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6182         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6183                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6184    (clobber (reg:CC FLAGS_REG))]
6185   "!TARGET_PARTIAL_REG_STALL
6186    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6187 {
6188   int widen = (which_alternative == 2);
6189   switch (get_attr_type (insn))
6190     {
6191     case TYPE_LEA:
6192       return "#";
6193     case TYPE_INCDEC:
6194       if (operands[2] == const1_rtx)
6195         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6196       else if (operands[2] == constm1_rtx)
6197         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6198       abort();
6199
6200     default:
6201       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6202          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6203       if (GET_CODE (operands[2]) == CONST_INT
6204           && (INTVAL (operands[2]) == 128
6205               || (INTVAL (operands[2]) < 0
6206                   && INTVAL (operands[2]) != -128)))
6207         {
6208           operands[2] = GEN_INT (-INTVAL (operands[2]));
6209           if (widen)
6210             return "sub{l}\t{%2, %k0|%k0, %2}";
6211           else
6212             return "sub{b}\t{%2, %0|%0, %2}";
6213         }
6214       if (widen)
6215         return "add{l}\t{%k2, %k0|%k0, %k2}";
6216       else
6217         return "add{b}\t{%2, %0|%0, %2}";
6218     }
6219 }
6220   [(set (attr "type")
6221      (if_then_else (eq_attr "alternative" "3")
6222         (const_string "lea")
6223         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6224            (const_string "incdec")
6225            (const_string "alu"))))
6226    (set_attr "mode" "QI,QI,SI,SI")])
6227
6228 (define_insn "*addqi_1"
6229   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6230         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6231                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6232    (clobber (reg:CC FLAGS_REG))]
6233   "TARGET_PARTIAL_REG_STALL
6234    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6235 {
6236   int widen = (which_alternative == 2);
6237   switch (get_attr_type (insn))
6238     {
6239     case TYPE_INCDEC:
6240       if (operands[2] == const1_rtx)
6241         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6242       else if (operands[2] == constm1_rtx)
6243         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6244       abort();
6245
6246     default:
6247       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6248          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6249       if (GET_CODE (operands[2]) == CONST_INT
6250           && (INTVAL (operands[2]) == 128
6251               || (INTVAL (operands[2]) < 0
6252                   && INTVAL (operands[2]) != -128)))
6253         {
6254           operands[2] = GEN_INT (-INTVAL (operands[2]));
6255           if (widen)
6256             return "sub{l}\t{%2, %k0|%k0, %2}";
6257           else
6258             return "sub{b}\t{%2, %0|%0, %2}";
6259         }
6260       if (widen)
6261         return "add{l}\t{%k2, %k0|%k0, %k2}";
6262       else
6263         return "add{b}\t{%2, %0|%0, %2}";
6264     }
6265 }
6266   [(set (attr "type")
6267      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6268         (const_string "incdec")
6269         (const_string "alu")))
6270    (set_attr "mode" "QI,QI,SI")])
6271
6272 (define_insn "*addqi_1_slp"
6273   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6274         (plus:QI (match_dup 0)
6275                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6276    (clobber (reg:CC FLAGS_REG))]
6277   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6278    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6279 {
6280   switch (get_attr_type (insn))
6281     {
6282     case TYPE_INCDEC:
6283       if (operands[1] == const1_rtx)
6284         return "inc{b}\t%0";
6285       else if (operands[1] == constm1_rtx)
6286         return "dec{b}\t%0";
6287       abort();
6288
6289     default:
6290       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6291       if (GET_CODE (operands[1]) == CONST_INT
6292           && INTVAL (operands[1]) < 0)
6293         {
6294           operands[1] = GEN_INT (-INTVAL (operands[1]));
6295           return "sub{b}\t{%1, %0|%0, %1}";
6296         }
6297       return "add{b}\t{%1, %0|%0, %1}";
6298     }
6299 }
6300   [(set (attr "type")
6301      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6302         (const_string "incdec")
6303         (const_string "alu1")))
6304    (set_attr "mode" "QI")])
6305
6306 (define_insn "*addqi_2"
6307   [(set (reg FLAGS_REG)
6308         (compare
6309           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6310                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6311           (const_int 0)))
6312    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6313         (plus:QI (match_dup 1) (match_dup 2)))]
6314   "ix86_match_ccmode (insn, CCGOCmode)
6315    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6316 {
6317   switch (get_attr_type (insn))
6318     {
6319     case TYPE_INCDEC:
6320       if (operands[2] == const1_rtx)
6321         return "inc{b}\t%0";
6322       else if (operands[2] == constm1_rtx
6323                || (GET_CODE (operands[2]) == CONST_INT
6324                    && INTVAL (operands[2]) == 255))
6325         return "dec{b}\t%0";
6326       abort();
6327
6328     default:
6329       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6330       if (GET_CODE (operands[2]) == CONST_INT
6331           && INTVAL (operands[2]) < 0)
6332         {
6333           operands[2] = GEN_INT (-INTVAL (operands[2]));
6334           return "sub{b}\t{%2, %0|%0, %2}";
6335         }
6336       return "add{b}\t{%2, %0|%0, %2}";
6337     }
6338 }
6339   [(set (attr "type")
6340      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6341         (const_string "incdec")
6342         (const_string "alu")))
6343    (set_attr "mode" "QI")])
6344
6345 (define_insn "*addqi_3"
6346   [(set (reg FLAGS_REG)
6347         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6348                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6349    (clobber (match_scratch:QI 0 "=q"))]
6350   "ix86_match_ccmode (insn, CCZmode)
6351    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6352 {
6353   switch (get_attr_type (insn))
6354     {
6355     case TYPE_INCDEC:
6356       if (operands[2] == const1_rtx)
6357         return "inc{b}\t%0";
6358       else if (operands[2] == constm1_rtx
6359                || (GET_CODE (operands[2]) == CONST_INT
6360                    && INTVAL (operands[2]) == 255))
6361         return "dec{b}\t%0";
6362       abort();
6363
6364     default:
6365       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6366       if (GET_CODE (operands[2]) == CONST_INT
6367           && INTVAL (operands[2]) < 0)
6368         {
6369           operands[2] = GEN_INT (-INTVAL (operands[2]));
6370           return "sub{b}\t{%2, %0|%0, %2}";
6371         }
6372       return "add{b}\t{%2, %0|%0, %2}";
6373     }
6374 }
6375   [(set (attr "type")
6376      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6377         (const_string "incdec")
6378         (const_string "alu")))
6379    (set_attr "mode" "QI")])
6380
6381 ; See comments above addsi_3_imm for details.
6382 (define_insn "*addqi_4"
6383   [(set (reg FLAGS_REG)
6384         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6385                  (match_operand:QI 2 "const_int_operand" "n")))
6386    (clobber (match_scratch:QI 0 "=qm"))]
6387   "ix86_match_ccmode (insn, CCGCmode)
6388    && (INTVAL (operands[2]) & 0xff) != 0x80"
6389 {
6390   switch (get_attr_type (insn))
6391     {
6392     case TYPE_INCDEC:
6393       if (operands[2] == constm1_rtx
6394           || (GET_CODE (operands[2]) == CONST_INT
6395               && INTVAL (operands[2]) == 255))
6396         return "inc{b}\t%0";
6397       else if (operands[2] == const1_rtx)
6398         return "dec{b}\t%0";
6399       else
6400         abort();
6401
6402     default:
6403       if (! rtx_equal_p (operands[0], operands[1]))
6404         abort ();
6405       if (INTVAL (operands[2]) < 0)
6406         {
6407           operands[2] = GEN_INT (-INTVAL (operands[2]));
6408           return "add{b}\t{%2, %0|%0, %2}";
6409         }
6410       return "sub{b}\t{%2, %0|%0, %2}";
6411     }
6412 }
6413   [(set (attr "type")
6414      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6415         (const_string "incdec")
6416         (const_string "alu")))
6417    (set_attr "mode" "QI")])
6418
6419
6420 (define_insn "*addqi_5"
6421   [(set (reg FLAGS_REG)
6422         (compare
6423           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6424                    (match_operand:QI 2 "general_operand" "qmni"))
6425           (const_int 0)))
6426    (clobber (match_scratch:QI 0 "=q"))]
6427   "ix86_match_ccmode (insn, CCGOCmode)
6428    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6429 {
6430   switch (get_attr_type (insn))
6431     {
6432     case TYPE_INCDEC:
6433       if (operands[2] == const1_rtx)
6434         return "inc{b}\t%0";
6435       else if (operands[2] == constm1_rtx
6436                || (GET_CODE (operands[2]) == CONST_INT
6437                    && INTVAL (operands[2]) == 255))
6438         return "dec{b}\t%0";
6439       abort();
6440
6441     default:
6442       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6443       if (GET_CODE (operands[2]) == CONST_INT
6444           && INTVAL (operands[2]) < 0)
6445         {
6446           operands[2] = GEN_INT (-INTVAL (operands[2]));
6447           return "sub{b}\t{%2, %0|%0, %2}";
6448         }
6449       return "add{b}\t{%2, %0|%0, %2}";
6450     }
6451 }
6452   [(set (attr "type")
6453      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6454         (const_string "incdec")
6455         (const_string "alu")))
6456    (set_attr "mode" "QI")])
6457
6458
6459 (define_insn "addqi_ext_1"
6460   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6461                          (const_int 8)
6462                          (const_int 8))
6463         (plus:SI
6464           (zero_extract:SI
6465             (match_operand 1 "ext_register_operand" "0")
6466             (const_int 8)
6467             (const_int 8))
6468           (match_operand:QI 2 "general_operand" "Qmn")))
6469    (clobber (reg:CC FLAGS_REG))]
6470   "!TARGET_64BIT"
6471 {
6472   switch (get_attr_type (insn))
6473     {
6474     case TYPE_INCDEC:
6475       if (operands[2] == const1_rtx)
6476         return "inc{b}\t%h0";
6477       else if (operands[2] == constm1_rtx
6478                || (GET_CODE (operands[2]) == CONST_INT
6479                    && INTVAL (operands[2]) == 255))
6480         return "dec{b}\t%h0";
6481       abort();
6482
6483     default:
6484       return "add{b}\t{%2, %h0|%h0, %2}";
6485     }
6486 }
6487   [(set (attr "type")
6488      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6489         (const_string "incdec")
6490         (const_string "alu")))
6491    (set_attr "mode" "QI")])
6492
6493 (define_insn "*addqi_ext_1_rex64"
6494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6495                          (const_int 8)
6496                          (const_int 8))
6497         (plus:SI
6498           (zero_extract:SI
6499             (match_operand 1 "ext_register_operand" "0")
6500             (const_int 8)
6501             (const_int 8))
6502           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6503    (clobber (reg:CC FLAGS_REG))]
6504   "TARGET_64BIT"
6505 {
6506   switch (get_attr_type (insn))
6507     {
6508     case TYPE_INCDEC:
6509       if (operands[2] == const1_rtx)
6510         return "inc{b}\t%h0";
6511       else if (operands[2] == constm1_rtx
6512                || (GET_CODE (operands[2]) == CONST_INT
6513                    && INTVAL (operands[2]) == 255))
6514         return "dec{b}\t%h0";
6515       abort();
6516
6517     default:
6518       return "add{b}\t{%2, %h0|%h0, %2}";
6519     }
6520 }
6521   [(set (attr "type")
6522      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6523         (const_string "incdec")
6524         (const_string "alu")))
6525    (set_attr "mode" "QI")])
6526
6527 (define_insn "*addqi_ext_2"
6528   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6529                          (const_int 8)
6530                          (const_int 8))
6531         (plus:SI
6532           (zero_extract:SI
6533             (match_operand 1 "ext_register_operand" "%0")
6534             (const_int 8)
6535             (const_int 8))
6536           (zero_extract:SI
6537             (match_operand 2 "ext_register_operand" "Q")
6538             (const_int 8)
6539             (const_int 8))))
6540    (clobber (reg:CC FLAGS_REG))]
6541   ""
6542   "add{b}\t{%h2, %h0|%h0, %h2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "mode" "QI")])
6545
6546 ;; The patterns that match these are at the end of this file.
6547
6548 (define_expand "addxf3"
6549   [(set (match_operand:XF 0 "register_operand" "")
6550         (plus:XF (match_operand:XF 1 "register_operand" "")
6551                  (match_operand:XF 2 "register_operand" "")))]
6552   "TARGET_80387"
6553   "")
6554
6555 (define_expand "adddf3"
6556   [(set (match_operand:DF 0 "register_operand" "")
6557         (plus:DF (match_operand:DF 1 "register_operand" "")
6558                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6559   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6560   "")
6561
6562 (define_expand "addsf3"
6563   [(set (match_operand:SF 0 "register_operand" "")
6564         (plus:SF (match_operand:SF 1 "register_operand" "")
6565                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6566   "TARGET_80387 || TARGET_SSE_MATH"
6567   "")
6568 \f
6569 ;; Subtract instructions
6570
6571 ;; %%% splits for subsidi3
6572
6573 (define_expand "subdi3"
6574   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6575                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6576                              (match_operand:DI 2 "x86_64_general_operand" "")))
6577               (clobber (reg:CC FLAGS_REG))])]
6578   ""
6579   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6580
6581 (define_insn "*subdi3_1"
6582   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6583         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6584                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6587   "#")
6588
6589 (define_split
6590   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6591         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6592                   (match_operand:DI 2 "general_operand" "")))
6593    (clobber (reg:CC FLAGS_REG))]
6594   "!TARGET_64BIT && reload_completed"
6595   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6596               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6597    (parallel [(set (match_dup 3)
6598                    (minus:SI (match_dup 4)
6599                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6600                                       (match_dup 5))))
6601               (clobber (reg:CC FLAGS_REG))])]
6602   "split_di (operands+0, 1, operands+0, operands+3);
6603    split_di (operands+1, 1, operands+1, operands+4);
6604    split_di (operands+2, 1, operands+2, operands+5);")
6605
6606 (define_insn "subdi3_carry_rex64"
6607   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6608           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6610                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6613   "sbb{q}\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "pent_pair" "pu")
6616    (set_attr "mode" "DI")])
6617
6618 (define_insn "*subdi_1_rex64"
6619   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6620         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6621                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6622    (clobber (reg:CC FLAGS_REG))]
6623   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6624   "sub{q}\t{%2, %0|%0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "mode" "DI")])
6627
6628 (define_insn "*subdi_2_rex64"
6629   [(set (reg FLAGS_REG)
6630         (compare
6631           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6632                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6633           (const_int 0)))
6634    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6635         (minus:DI (match_dup 1) (match_dup 2)))]
6636   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6637    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6638   "sub{q}\t{%2, %0|%0, %2}"
6639   [(set_attr "type" "alu")
6640    (set_attr "mode" "DI")])
6641
6642 (define_insn "*subdi_3_rex63"
6643   [(set (reg FLAGS_REG)
6644         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6645                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6646    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6647         (minus:DI (match_dup 1) (match_dup 2)))]
6648   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6649    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650   "sub{q}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "DI")])
6653
6654 (define_insn "subqi3_carry"
6655   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6656           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6657             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6658                (match_operand:QI 2 "general_operand" "qi,qm"))))
6659    (clobber (reg:CC FLAGS_REG))]
6660   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6661   "sbb{b}\t{%2, %0|%0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "pent_pair" "pu")
6664    (set_attr "mode" "QI")])
6665
6666 (define_insn "subhi3_carry"
6667   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6668           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6669             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6670                (match_operand:HI 2 "general_operand" "ri,rm"))))
6671    (clobber (reg:CC FLAGS_REG))]
6672   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6673   "sbb{w}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "pent_pair" "pu")
6676    (set_attr "mode" "HI")])
6677
6678 (define_insn "subsi3_carry"
6679   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6680           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6681             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6682                (match_operand:SI 2 "general_operand" "ri,rm"))))
6683    (clobber (reg:CC FLAGS_REG))]
6684   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6685   "sbb{l}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "pent_pair" "pu")
6688    (set_attr "mode" "SI")])
6689
6690 (define_insn "subsi3_carry_zext"
6691   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6692           (zero_extend:DI
6693             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6694               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6695                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6696    (clobber (reg:CC FLAGS_REG))]
6697   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6698   "sbb{l}\t{%2, %k0|%k0, %2}"
6699   [(set_attr "type" "alu")
6700    (set_attr "pent_pair" "pu")
6701    (set_attr "mode" "SI")])
6702
6703 (define_expand "subsi3"
6704   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6705                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6706                              (match_operand:SI 2 "general_operand" "")))
6707               (clobber (reg:CC FLAGS_REG))])]
6708   ""
6709   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6710
6711 (define_insn "*subsi_1"
6712   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6714                   (match_operand:SI 2 "general_operand" "ri,rm")))
6715    (clobber (reg:CC FLAGS_REG))]
6716   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6717   "sub{l}\t{%2, %0|%0, %2}"
6718   [(set_attr "type" "alu")
6719    (set_attr "mode" "SI")])
6720
6721 (define_insn "*subsi_1_zext"
6722   [(set (match_operand:DI 0 "register_operand" "=r")
6723         (zero_extend:DI
6724           (minus:SI (match_operand:SI 1 "register_operand" "0")
6725                     (match_operand:SI 2 "general_operand" "rim"))))
6726    (clobber (reg:CC FLAGS_REG))]
6727   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6728   "sub{l}\t{%2, %k0|%k0, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "SI")])
6731
6732 (define_insn "*subsi_2"
6733   [(set (reg FLAGS_REG)
6734         (compare
6735           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6736                     (match_operand:SI 2 "general_operand" "ri,rm"))
6737           (const_int 0)))
6738    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6739         (minus:SI (match_dup 1) (match_dup 2)))]
6740   "ix86_match_ccmode (insn, CCGOCmode)
6741    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6742   "sub{l}\t{%2, %0|%0, %2}"
6743   [(set_attr "type" "alu")
6744    (set_attr "mode" "SI")])
6745
6746 (define_insn "*subsi_2_zext"
6747   [(set (reg FLAGS_REG)
6748         (compare
6749           (minus:SI (match_operand:SI 1 "register_operand" "0")
6750                     (match_operand:SI 2 "general_operand" "rim"))
6751           (const_int 0)))
6752    (set (match_operand:DI 0 "register_operand" "=r")
6753         (zero_extend:DI
6754           (minus:SI (match_dup 1)
6755                     (match_dup 2))))]
6756   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6757    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6758   "sub{l}\t{%2, %k0|%k0, %2}"
6759   [(set_attr "type" "alu")
6760    (set_attr "mode" "SI")])
6761
6762 (define_insn "*subsi_3"
6763   [(set (reg FLAGS_REG)
6764         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6765                  (match_operand:SI 2 "general_operand" "ri,rm")))
6766    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6767         (minus:SI (match_dup 1) (match_dup 2)))]
6768   "ix86_match_ccmode (insn, CCmode)
6769    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6770   "sub{l}\t{%2, %0|%0, %2}"
6771   [(set_attr "type" "alu")
6772    (set_attr "mode" "SI")])
6773
6774 (define_insn "*subsi_3_zext"
6775   [(set (reg FLAGS_REG)
6776         (compare (match_operand:SI 1 "register_operand" "0")
6777                  (match_operand:SI 2 "general_operand" "rim")))
6778    (set (match_operand:DI 0 "register_operand" "=r")
6779         (zero_extend:DI
6780           (minus:SI (match_dup 1)
6781                     (match_dup 2))))]
6782   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6783    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784   "sub{q}\t{%2, %0|%0, %2}"
6785   [(set_attr "type" "alu")
6786    (set_attr "mode" "DI")])
6787
6788 (define_expand "subhi3"
6789   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6790                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6791                              (match_operand:HI 2 "general_operand" "")))
6792               (clobber (reg:CC FLAGS_REG))])]
6793   "TARGET_HIMODE_MATH"
6794   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6795
6796 (define_insn "*subhi_1"
6797   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6798         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6799                   (match_operand:HI 2 "general_operand" "ri,rm")))
6800    (clobber (reg:CC FLAGS_REG))]
6801   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6802   "sub{w}\t{%2, %0|%0, %2}"
6803   [(set_attr "type" "alu")
6804    (set_attr "mode" "HI")])
6805
6806 (define_insn "*subhi_2"
6807   [(set (reg FLAGS_REG)
6808         (compare
6809           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6810                     (match_operand:HI 2 "general_operand" "ri,rm"))
6811           (const_int 0)))
6812    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6813         (minus:HI (match_dup 1) (match_dup 2)))]
6814   "ix86_match_ccmode (insn, CCGOCmode)
6815    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6816   "sub{w}\t{%2, %0|%0, %2}"
6817   [(set_attr "type" "alu")
6818    (set_attr "mode" "HI")])
6819
6820 (define_insn "*subhi_3"
6821   [(set (reg FLAGS_REG)
6822         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6823                  (match_operand:HI 2 "general_operand" "ri,rm")))
6824    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6825         (minus:HI (match_dup 1) (match_dup 2)))]
6826   "ix86_match_ccmode (insn, CCmode)
6827    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6828   "sub{w}\t{%2, %0|%0, %2}"
6829   [(set_attr "type" "alu")
6830    (set_attr "mode" "HI")])
6831
6832 (define_expand "subqi3"
6833   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6834                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6835                              (match_operand:QI 2 "general_operand" "")))
6836               (clobber (reg:CC FLAGS_REG))])]
6837   "TARGET_QIMODE_MATH"
6838   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6839
6840 (define_insn "*subqi_1"
6841   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6842         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6843                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6844    (clobber (reg:CC FLAGS_REG))]
6845   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6846   "sub{b}\t{%2, %0|%0, %2}"
6847   [(set_attr "type" "alu")
6848    (set_attr "mode" "QI")])
6849
6850 (define_insn "*subqi_1_slp"
6851   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6852         (minus:QI (match_dup 0)
6853                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6854    (clobber (reg:CC FLAGS_REG))]
6855   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6856    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6857   "sub{b}\t{%1, %0|%0, %1}"
6858   [(set_attr "type" "alu1")
6859    (set_attr "mode" "QI")])
6860
6861 (define_insn "*subqi_2"
6862   [(set (reg FLAGS_REG)
6863         (compare
6864           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6865                     (match_operand:QI 2 "general_operand" "qi,qm"))
6866           (const_int 0)))
6867    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6868         (minus:HI (match_dup 1) (match_dup 2)))]
6869   "ix86_match_ccmode (insn, CCGOCmode)
6870    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6871   "sub{b}\t{%2, %0|%0, %2}"
6872   [(set_attr "type" "alu")
6873    (set_attr "mode" "QI")])
6874
6875 (define_insn "*subqi_3"
6876   [(set (reg FLAGS_REG)
6877         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878                  (match_operand:QI 2 "general_operand" "qi,qm")))
6879    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6880         (minus:HI (match_dup 1) (match_dup 2)))]
6881   "ix86_match_ccmode (insn, CCmode)
6882    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6883   "sub{b}\t{%2, %0|%0, %2}"
6884   [(set_attr "type" "alu")
6885    (set_attr "mode" "QI")])
6886
6887 ;; The patterns that match these are at the end of this file.
6888
6889 (define_expand "subxf3"
6890   [(set (match_operand:XF 0 "register_operand" "")
6891         (minus:XF (match_operand:XF 1 "register_operand" "")
6892                   (match_operand:XF 2 "register_operand" "")))]
6893   "TARGET_80387"
6894   "")
6895
6896 (define_expand "subdf3"
6897   [(set (match_operand:DF 0 "register_operand" "")
6898         (minus:DF (match_operand:DF 1 "register_operand" "")
6899                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6900   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6901   "")
6902
6903 (define_expand "subsf3"
6904   [(set (match_operand:SF 0 "register_operand" "")
6905         (minus:SF (match_operand:SF 1 "register_operand" "")
6906                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6907   "TARGET_80387 || TARGET_SSE_MATH"
6908   "")
6909 \f
6910 ;; Multiply instructions
6911
6912 (define_expand "muldi3"
6913   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6914                    (mult:DI (match_operand:DI 1 "register_operand" "")
6915                             (match_operand:DI 2 "x86_64_general_operand" "")))
6916               (clobber (reg:CC FLAGS_REG))])]
6917   "TARGET_64BIT"
6918   "")
6919
6920 (define_insn "*muldi3_1_rex64"
6921   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6922         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6923                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "TARGET_64BIT
6926    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6927   "@
6928    imul{q}\t{%2, %1, %0|%0, %1, %2}
6929    imul{q}\t{%2, %1, %0|%0, %1, %2}
6930    imul{q}\t{%2, %0|%0, %2}"
6931   [(set_attr "type" "imul")
6932    (set_attr "prefix_0f" "0,0,1")
6933    (set (attr "athlon_decode")
6934         (cond [(eq_attr "cpu" "athlon")
6935                   (const_string "vector")
6936                (eq_attr "alternative" "1")
6937                   (const_string "vector")
6938                (and (eq_attr "alternative" "2")
6939                     (match_operand 1 "memory_operand" ""))
6940                   (const_string "vector")]
6941               (const_string "direct")))
6942    (set_attr "mode" "DI")])
6943
6944 (define_expand "mulsi3"
6945   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6946                    (mult:SI (match_operand:SI 1 "register_operand" "")
6947                             (match_operand:SI 2 "general_operand" "")))
6948               (clobber (reg:CC FLAGS_REG))])]
6949   ""
6950   "")
6951
6952 (define_insn "*mulsi3_1"
6953   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6954         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6955                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6956    (clobber (reg:CC FLAGS_REG))]
6957   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6958   "@
6959    imul{l}\t{%2, %1, %0|%0, %1, %2}
6960    imul{l}\t{%2, %1, %0|%0, %1, %2}
6961    imul{l}\t{%2, %0|%0, %2}"
6962   [(set_attr "type" "imul")
6963    (set_attr "prefix_0f" "0,0,1")
6964    (set (attr "athlon_decode")
6965         (cond [(eq_attr "cpu" "athlon")
6966                   (const_string "vector")
6967                (eq_attr "alternative" "1")
6968                   (const_string "vector")
6969                (and (eq_attr "alternative" "2")
6970                     (match_operand 1 "memory_operand" ""))
6971                   (const_string "vector")]
6972               (const_string "direct")))
6973    (set_attr "mode" "SI")])
6974
6975 (define_insn "*mulsi3_1_zext"
6976   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6977         (zero_extend:DI
6978           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6979                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6980    (clobber (reg:CC FLAGS_REG))]
6981   "TARGET_64BIT
6982    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6983   "@
6984    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6985    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6986    imul{l}\t{%2, %k0|%k0, %2}"
6987   [(set_attr "type" "imul")
6988    (set_attr "prefix_0f" "0,0,1")
6989    (set (attr "athlon_decode")
6990         (cond [(eq_attr "cpu" "athlon")
6991                   (const_string "vector")
6992                (eq_attr "alternative" "1")
6993                   (const_string "vector")
6994                (and (eq_attr "alternative" "2")
6995                     (match_operand 1 "memory_operand" ""))
6996                   (const_string "vector")]
6997               (const_string "direct")))
6998    (set_attr "mode" "SI")])
6999
7000 (define_expand "mulhi3"
7001   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7002                    (mult:HI (match_operand:HI 1 "register_operand" "")
7003                             (match_operand:HI 2 "general_operand" "")))
7004               (clobber (reg:CC FLAGS_REG))])]
7005   "TARGET_HIMODE_MATH"
7006   "")
7007
7008 (define_insn "*mulhi3_1"
7009   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7010         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7011                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7012    (clobber (reg:CC FLAGS_REG))]
7013   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7014   "@
7015    imul{w}\t{%2, %1, %0|%0, %1, %2}
7016    imul{w}\t{%2, %1, %0|%0, %1, %2}
7017    imul{w}\t{%2, %0|%0, %2}"
7018   [(set_attr "type" "imul")
7019    (set_attr "prefix_0f" "0,0,1")
7020    (set (attr "athlon_decode")
7021         (cond [(eq_attr "cpu" "athlon")
7022                   (const_string "vector")
7023                (eq_attr "alternative" "1,2")
7024                   (const_string "vector")]
7025               (const_string "direct")))
7026    (set_attr "mode" "HI")])
7027
7028 (define_expand "mulqi3"
7029   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7030                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7031                             (match_operand:QI 2 "register_operand" "")))
7032               (clobber (reg:CC FLAGS_REG))])]
7033   "TARGET_QIMODE_MATH"
7034   "")
7035
7036 (define_insn "*mulqi3_1"
7037   [(set (match_operand:QI 0 "register_operand" "=a")
7038         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7039                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7040    (clobber (reg:CC FLAGS_REG))]
7041   "TARGET_QIMODE_MATH
7042    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7043   "mul{b}\t%2"
7044   [(set_attr "type" "imul")
7045    (set_attr "length_immediate" "0")
7046    (set (attr "athlon_decode")
7047      (if_then_else (eq_attr "cpu" "athlon")
7048         (const_string "vector")
7049         (const_string "direct")))
7050    (set_attr "mode" "QI")])
7051
7052 (define_expand "umulqihi3"
7053   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7054                    (mult:HI (zero_extend:HI
7055                               (match_operand:QI 1 "nonimmediate_operand" ""))
7056                             (zero_extend:HI
7057                               (match_operand:QI 2 "register_operand" ""))))
7058               (clobber (reg:CC FLAGS_REG))])]
7059   "TARGET_QIMODE_MATH"
7060   "")
7061
7062 (define_insn "*umulqihi3_1"
7063   [(set (match_operand:HI 0 "register_operand" "=a")
7064         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7065                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7066    (clobber (reg:CC FLAGS_REG))]
7067   "TARGET_QIMODE_MATH
7068    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7069   "mul{b}\t%2"
7070   [(set_attr "type" "imul")
7071    (set_attr "length_immediate" "0")
7072    (set (attr "athlon_decode")
7073      (if_then_else (eq_attr "cpu" "athlon")
7074         (const_string "vector")
7075         (const_string "direct")))
7076    (set_attr "mode" "QI")])
7077
7078 (define_expand "mulqihi3"
7079   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7080                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7081                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   "TARGET_QIMODE_MATH"
7084   "")
7085
7086 (define_insn "*mulqihi3_insn"
7087   [(set (match_operand:HI 0 "register_operand" "=a")
7088         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "TARGET_QIMODE_MATH
7092    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093   "imul{b}\t%2"
7094   [(set_attr "type" "imul")
7095    (set_attr "length_immediate" "0")
7096    (set (attr "athlon_decode")
7097      (if_then_else (eq_attr "cpu" "athlon")
7098         (const_string "vector")
7099         (const_string "direct")))
7100    (set_attr "mode" "QI")])
7101
7102 (define_expand "umulditi3"
7103   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7104                    (mult:TI (zero_extend:TI
7105                               (match_operand:DI 1 "nonimmediate_operand" ""))
7106                             (zero_extend:TI
7107                               (match_operand:DI 2 "register_operand" ""))))
7108               (clobber (reg:CC FLAGS_REG))])]
7109   "TARGET_64BIT"
7110   "")
7111
7112 (define_insn "*umulditi3_insn"
7113   [(set (match_operand:TI 0 "register_operand" "=A")
7114         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7115                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7116    (clobber (reg:CC FLAGS_REG))]
7117   "TARGET_64BIT
7118    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7119   "mul{q}\t%2"
7120   [(set_attr "type" "imul")
7121    (set_attr "length_immediate" "0")
7122    (set (attr "athlon_decode")
7123      (if_then_else (eq_attr "cpu" "athlon")
7124         (const_string "vector")
7125         (const_string "double")))
7126    (set_attr "mode" "DI")])
7127
7128 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7129 (define_expand "umulsidi3"
7130   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7131                    (mult:DI (zero_extend:DI
7132                               (match_operand:SI 1 "nonimmediate_operand" ""))
7133                             (zero_extend:DI
7134                               (match_operand:SI 2 "register_operand" ""))))
7135               (clobber (reg:CC FLAGS_REG))])]
7136   "!TARGET_64BIT"
7137   "")
7138
7139 (define_insn "*umulsidi3_insn"
7140   [(set (match_operand:DI 0 "register_operand" "=A")
7141         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7142                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7143    (clobber (reg:CC FLAGS_REG))]
7144   "!TARGET_64BIT
7145    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7146   "mul{l}\t%2"
7147   [(set_attr "type" "imul")
7148    (set_attr "length_immediate" "0")
7149    (set (attr "athlon_decode")
7150      (if_then_else (eq_attr "cpu" "athlon")
7151         (const_string "vector")
7152         (const_string "double")))
7153    (set_attr "mode" "SI")])
7154
7155 (define_expand "mulditi3"
7156   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7157                    (mult:TI (sign_extend:TI
7158                               (match_operand:DI 1 "nonimmediate_operand" ""))
7159                             (sign_extend:TI
7160                               (match_operand:DI 2 "register_operand" ""))))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   "TARGET_64BIT"
7163   "")
7164
7165 (define_insn "*mulditi3_insn"
7166   [(set (match_operand:TI 0 "register_operand" "=A")
7167         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7168                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7169    (clobber (reg:CC FLAGS_REG))]
7170   "TARGET_64BIT
7171    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172   "imul{q}\t%2"
7173   [(set_attr "type" "imul")
7174    (set_attr "length_immediate" "0")
7175    (set (attr "athlon_decode")
7176      (if_then_else (eq_attr "cpu" "athlon")
7177         (const_string "vector")
7178         (const_string "double")))
7179    (set_attr "mode" "DI")])
7180
7181 (define_expand "mulsidi3"
7182   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7183                    (mult:DI (sign_extend:DI
7184                               (match_operand:SI 1 "nonimmediate_operand" ""))
7185                             (sign_extend:DI
7186                               (match_operand:SI 2 "register_operand" ""))))
7187               (clobber (reg:CC FLAGS_REG))])]
7188   "!TARGET_64BIT"
7189   "")
7190
7191 (define_insn "*mulsidi3_insn"
7192   [(set (match_operand:DI 0 "register_operand" "=A")
7193         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7194                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7195    (clobber (reg:CC FLAGS_REG))]
7196   "!TARGET_64BIT
7197    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7198   "imul{l}\t%2"
7199   [(set_attr "type" "imul")
7200    (set_attr "length_immediate" "0")
7201    (set (attr "athlon_decode")
7202      (if_then_else (eq_attr "cpu" "athlon")
7203         (const_string "vector")
7204         (const_string "double")))
7205    (set_attr "mode" "SI")])
7206
7207 (define_expand "umuldi3_highpart"
7208   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7209                    (truncate:DI
7210                      (lshiftrt:TI
7211                        (mult:TI (zero_extend:TI
7212                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7213                                 (zero_extend:TI
7214                                   (match_operand:DI 2 "register_operand" "")))
7215                        (const_int 64))))
7216               (clobber (match_scratch:DI 3 ""))
7217               (clobber (reg:CC FLAGS_REG))])]
7218   "TARGET_64BIT"
7219   "")
7220
7221 (define_insn "*umuldi3_highpart_rex64"
7222   [(set (match_operand:DI 0 "register_operand" "=d")
7223         (truncate:DI
7224           (lshiftrt:TI
7225             (mult:TI (zero_extend:TI
7226                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7227                      (zero_extend:TI
7228                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7229             (const_int 64))))
7230    (clobber (match_scratch:DI 3 "=1"))
7231    (clobber (reg:CC FLAGS_REG))]
7232   "TARGET_64BIT
7233    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234   "mul{q}\t%2"
7235   [(set_attr "type" "imul")
7236    (set_attr "length_immediate" "0")
7237    (set (attr "athlon_decode")
7238      (if_then_else (eq_attr "cpu" "athlon")
7239         (const_string "vector")
7240         (const_string "double")))
7241    (set_attr "mode" "DI")])
7242
7243 (define_expand "umulsi3_highpart"
7244   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7245                    (truncate:SI
7246                      (lshiftrt:DI
7247                        (mult:DI (zero_extend:DI
7248                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7249                                 (zero_extend:DI
7250                                   (match_operand:SI 2 "register_operand" "")))
7251                        (const_int 32))))
7252               (clobber (match_scratch:SI 3 ""))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   ""
7255   "")
7256
7257 (define_insn "*umulsi3_highpart_insn"
7258   [(set (match_operand:SI 0 "register_operand" "=d")
7259         (truncate:SI
7260           (lshiftrt:DI
7261             (mult:DI (zero_extend:DI
7262                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7263                      (zero_extend:DI
7264                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7265             (const_int 32))))
7266    (clobber (match_scratch:SI 3 "=1"))
7267    (clobber (reg:CC FLAGS_REG))]
7268   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7269   "mul{l}\t%2"
7270   [(set_attr "type" "imul")
7271    (set_attr "length_immediate" "0")
7272    (set (attr "athlon_decode")
7273      (if_then_else (eq_attr "cpu" "athlon")
7274         (const_string "vector")
7275         (const_string "double")))
7276    (set_attr "mode" "SI")])
7277
7278 (define_insn "*umulsi3_highpart_zext"
7279   [(set (match_operand:DI 0 "register_operand" "=d")
7280         (zero_extend:DI (truncate:SI
7281           (lshiftrt:DI
7282             (mult:DI (zero_extend:DI
7283                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7284                      (zero_extend:DI
7285                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7286             (const_int 32)))))
7287    (clobber (match_scratch:SI 3 "=1"))
7288    (clobber (reg:CC FLAGS_REG))]
7289   "TARGET_64BIT
7290    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7291   "mul{l}\t%2"
7292   [(set_attr "type" "imul")
7293    (set_attr "length_immediate" "0")
7294    (set (attr "athlon_decode")
7295      (if_then_else (eq_attr "cpu" "athlon")
7296         (const_string "vector")
7297         (const_string "double")))
7298    (set_attr "mode" "SI")])
7299
7300 (define_expand "smuldi3_highpart"
7301   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7302                    (truncate:DI
7303                      (lshiftrt:TI
7304                        (mult:TI (sign_extend:TI
7305                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7306                                 (sign_extend:TI
7307                                   (match_operand:DI 2 "register_operand" "")))
7308                        (const_int 64))))
7309               (clobber (match_scratch:DI 3 ""))
7310               (clobber (reg:CC FLAGS_REG))])]
7311   "TARGET_64BIT"
7312   "")
7313
7314 (define_insn "*smuldi3_highpart_rex64"
7315   [(set (match_operand:DI 0 "register_operand" "=d")
7316         (truncate:DI
7317           (lshiftrt:TI
7318             (mult:TI (sign_extend:TI
7319                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7320                      (sign_extend:TI
7321                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7322             (const_int 64))))
7323    (clobber (match_scratch:DI 3 "=1"))
7324    (clobber (reg:CC FLAGS_REG))]
7325   "TARGET_64BIT
7326    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7327   "imul{q}\t%2"
7328   [(set_attr "type" "imul")
7329    (set (attr "athlon_decode")
7330      (if_then_else (eq_attr "cpu" "athlon")
7331         (const_string "vector")
7332         (const_string "double")))
7333    (set_attr "mode" "DI")])
7334
7335 (define_expand "smulsi3_highpart"
7336   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7337                    (truncate:SI
7338                      (lshiftrt:DI
7339                        (mult:DI (sign_extend:DI
7340                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7341                                 (sign_extend:DI
7342                                   (match_operand:SI 2 "register_operand" "")))
7343                        (const_int 32))))
7344               (clobber (match_scratch:SI 3 ""))
7345               (clobber (reg:CC FLAGS_REG))])]
7346   ""
7347   "")
7348
7349 (define_insn "*smulsi3_highpart_insn"
7350   [(set (match_operand:SI 0 "register_operand" "=d")
7351         (truncate:SI
7352           (lshiftrt:DI
7353             (mult:DI (sign_extend:DI
7354                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7355                      (sign_extend:DI
7356                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7357             (const_int 32))))
7358    (clobber (match_scratch:SI 3 "=1"))
7359    (clobber (reg:CC FLAGS_REG))]
7360   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7361   "imul{l}\t%2"
7362   [(set_attr "type" "imul")
7363    (set (attr "athlon_decode")
7364      (if_then_else (eq_attr "cpu" "athlon")
7365         (const_string "vector")
7366         (const_string "double")))
7367    (set_attr "mode" "SI")])
7368
7369 (define_insn "*smulsi3_highpart_zext"
7370   [(set (match_operand:DI 0 "register_operand" "=d")
7371         (zero_extend:DI (truncate:SI
7372           (lshiftrt:DI
7373             (mult:DI (sign_extend:DI
7374                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7375                      (sign_extend:DI
7376                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7377             (const_int 32)))))
7378    (clobber (match_scratch:SI 3 "=1"))
7379    (clobber (reg:CC FLAGS_REG))]
7380   "TARGET_64BIT
7381    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7382   "imul{l}\t%2"
7383   [(set_attr "type" "imul")
7384    (set (attr "athlon_decode")
7385      (if_then_else (eq_attr "cpu" "athlon")
7386         (const_string "vector")
7387         (const_string "double")))
7388    (set_attr "mode" "SI")])
7389
7390 ;; The patterns that match these are at the end of this file.
7391
7392 (define_expand "mulxf3"
7393   [(set (match_operand:XF 0 "register_operand" "")
7394         (mult:XF (match_operand:XF 1 "register_operand" "")
7395                  (match_operand:XF 2 "register_operand" "")))]
7396   "TARGET_80387"
7397   "")
7398
7399 (define_expand "muldf3"
7400   [(set (match_operand:DF 0 "register_operand" "")
7401         (mult:DF (match_operand:DF 1 "register_operand" "")
7402                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7403   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7404   "")
7405
7406 (define_expand "mulsf3"
7407   [(set (match_operand:SF 0 "register_operand" "")
7408         (mult:SF (match_operand:SF 1 "register_operand" "")
7409                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7410   "TARGET_80387 || TARGET_SSE_MATH"
7411   "")
7412 \f
7413 ;; Divide instructions
7414
7415 (define_insn "divqi3"
7416   [(set (match_operand:QI 0 "register_operand" "=a")
7417         (div:QI (match_operand:HI 1 "register_operand" "0")
7418                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "TARGET_QIMODE_MATH"
7421   "idiv{b}\t%2"
7422   [(set_attr "type" "idiv")
7423    (set_attr "mode" "QI")])
7424
7425 (define_insn "udivqi3"
7426   [(set (match_operand:QI 0 "register_operand" "=a")
7427         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7428                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7429    (clobber (reg:CC FLAGS_REG))]
7430   "TARGET_QIMODE_MATH"
7431   "div{b}\t%2"
7432   [(set_attr "type" "idiv")
7433    (set_attr "mode" "QI")])
7434
7435 ;; The patterns that match these are at the end of this file.
7436
7437 (define_expand "divxf3"
7438   [(set (match_operand:XF 0 "register_operand" "")
7439         (div:XF (match_operand:XF 1 "register_operand" "")
7440                 (match_operand:XF 2 "register_operand" "")))]
7441   "TARGET_80387"
7442   "")
7443
7444 (define_expand "divdf3"
7445   [(set (match_operand:DF 0 "register_operand" "")
7446         (div:DF (match_operand:DF 1 "register_operand" "")
7447                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7448    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7449    "")
7450  
7451 (define_expand "divsf3"
7452   [(set (match_operand:SF 0 "register_operand" "")
7453         (div:SF (match_operand:SF 1 "register_operand" "")
7454                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7455   "TARGET_80387 || TARGET_SSE_MATH"
7456   "")
7457 \f
7458 ;; Remainder instructions.
7459
7460 (define_expand "divmoddi4"
7461   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7462                    (div:DI (match_operand:DI 1 "register_operand" "")
7463                            (match_operand:DI 2 "nonimmediate_operand" "")))
7464               (set (match_operand:DI 3 "register_operand" "")
7465                    (mod:DI (match_dup 1) (match_dup 2)))
7466               (clobber (reg:CC FLAGS_REG))])]
7467   "TARGET_64BIT"
7468   "")
7469
7470 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7471 ;; Penalize eax case slightly because it results in worse scheduling
7472 ;; of code.
7473 (define_insn "*divmoddi4_nocltd_rex64"
7474   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7475         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7476                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7477    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7478         (mod:DI (match_dup 2) (match_dup 3)))
7479    (clobber (reg:CC FLAGS_REG))]
7480   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7481   "#"
7482   [(set_attr "type" "multi")])
7483
7484 (define_insn "*divmoddi4_cltd_rex64"
7485   [(set (match_operand:DI 0 "register_operand" "=a")
7486         (div:DI (match_operand:DI 2 "register_operand" "a")
7487                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7488    (set (match_operand:DI 1 "register_operand" "=&d")
7489         (mod:DI (match_dup 2) (match_dup 3)))
7490    (clobber (reg:CC FLAGS_REG))]
7491   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7492   "#"
7493   [(set_attr "type" "multi")])
7494
7495 (define_insn "*divmoddi_noext_rex64"
7496   [(set (match_operand:DI 0 "register_operand" "=a")
7497         (div:DI (match_operand:DI 1 "register_operand" "0")
7498                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7499    (set (match_operand:DI 3 "register_operand" "=d")
7500         (mod:DI (match_dup 1) (match_dup 2)))
7501    (use (match_operand:DI 4 "register_operand" "3"))
7502    (clobber (reg:CC FLAGS_REG))]
7503   "TARGET_64BIT"
7504   "idiv{q}\t%2"
7505   [(set_attr "type" "idiv")
7506    (set_attr "mode" "DI")])
7507
7508 (define_split
7509   [(set (match_operand:DI 0 "register_operand" "")
7510         (div:DI (match_operand:DI 1 "register_operand" "")
7511                 (match_operand:DI 2 "nonimmediate_operand" "")))
7512    (set (match_operand:DI 3 "register_operand" "")
7513         (mod:DI (match_dup 1) (match_dup 2)))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "TARGET_64BIT && reload_completed"
7516   [(parallel [(set (match_dup 3)
7517                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7518               (clobber (reg:CC FLAGS_REG))])
7519    (parallel [(set (match_dup 0)
7520                    (div:DI (reg:DI 0) (match_dup 2)))
7521               (set (match_dup 3)
7522                    (mod:DI (reg:DI 0) (match_dup 2)))
7523               (use (match_dup 3))
7524               (clobber (reg:CC FLAGS_REG))])]
7525 {
7526   /* Avoid use of cltd in favor of a mov+shift.  */
7527   if (!TARGET_USE_CLTD && !optimize_size)
7528     {
7529       if (true_regnum (operands[1]))
7530         emit_move_insn (operands[0], operands[1]);
7531       else
7532         emit_move_insn (operands[3], operands[1]);
7533       operands[4] = operands[3];
7534     }
7535   else
7536     {
7537       if (true_regnum (operands[1]))
7538         abort();
7539       operands[4] = operands[1];
7540     }
7541 })
7542
7543
7544 (define_expand "divmodsi4"
7545   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7546                    (div:SI (match_operand:SI 1 "register_operand" "")
7547                            (match_operand:SI 2 "nonimmediate_operand" "")))
7548               (set (match_operand:SI 3 "register_operand" "")
7549                    (mod:SI (match_dup 1) (match_dup 2)))
7550               (clobber (reg:CC FLAGS_REG))])]
7551   ""
7552   "")
7553
7554 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7555 ;; Penalize eax case slightly because it results in worse scheduling
7556 ;; of code.
7557 (define_insn "*divmodsi4_nocltd"
7558   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7559         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7560                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7561    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7562         (mod:SI (match_dup 2) (match_dup 3)))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "!optimize_size && !TARGET_USE_CLTD"
7565   "#"
7566   [(set_attr "type" "multi")])
7567
7568 (define_insn "*divmodsi4_cltd"
7569   [(set (match_operand:SI 0 "register_operand" "=a")
7570         (div:SI (match_operand:SI 2 "register_operand" "a")
7571                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7572    (set (match_operand:SI 1 "register_operand" "=&d")
7573         (mod:SI (match_dup 2) (match_dup 3)))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "optimize_size || TARGET_USE_CLTD"
7576   "#"
7577   [(set_attr "type" "multi")])
7578
7579 (define_insn "*divmodsi_noext"
7580   [(set (match_operand:SI 0 "register_operand" "=a")
7581         (div:SI (match_operand:SI 1 "register_operand" "0")
7582                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7583    (set (match_operand:SI 3 "register_operand" "=d")
7584         (mod:SI (match_dup 1) (match_dup 2)))
7585    (use (match_operand:SI 4 "register_operand" "3"))
7586    (clobber (reg:CC FLAGS_REG))]
7587   ""
7588   "idiv{l}\t%2"
7589   [(set_attr "type" "idiv")
7590    (set_attr "mode" "SI")])
7591
7592 (define_split
7593   [(set (match_operand:SI 0 "register_operand" "")
7594         (div:SI (match_operand:SI 1 "register_operand" "")
7595                 (match_operand:SI 2 "nonimmediate_operand" "")))
7596    (set (match_operand:SI 3 "register_operand" "")
7597         (mod:SI (match_dup 1) (match_dup 2)))
7598    (clobber (reg:CC FLAGS_REG))]
7599   "reload_completed"
7600   [(parallel [(set (match_dup 3)
7601                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7602               (clobber (reg:CC FLAGS_REG))])
7603    (parallel [(set (match_dup 0)
7604                    (div:SI (reg:SI 0) (match_dup 2)))
7605               (set (match_dup 3)
7606                    (mod:SI (reg:SI 0) (match_dup 2)))
7607               (use (match_dup 3))
7608               (clobber (reg:CC FLAGS_REG))])]
7609 {
7610   /* Avoid use of cltd in favor of a mov+shift.  */
7611   if (!TARGET_USE_CLTD && !optimize_size)
7612     {
7613       if (true_regnum (operands[1]))
7614         emit_move_insn (operands[0], operands[1]);
7615       else
7616         emit_move_insn (operands[3], operands[1]);
7617       operands[4] = operands[3];
7618     }
7619   else
7620     {
7621       if (true_regnum (operands[1]))
7622         abort();
7623       operands[4] = operands[1];
7624     }
7625 })
7626 ;; %%% Split me.
7627 (define_insn "divmodhi4"
7628   [(set (match_operand:HI 0 "register_operand" "=a")
7629         (div:HI (match_operand:HI 1 "register_operand" "0")
7630                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7631    (set (match_operand:HI 3 "register_operand" "=&d")
7632         (mod:HI (match_dup 1) (match_dup 2)))
7633    (clobber (reg:CC FLAGS_REG))]
7634   "TARGET_HIMODE_MATH"
7635   "cwtd\;idiv{w}\t%2"
7636   [(set_attr "type" "multi")
7637    (set_attr "length_immediate" "0")
7638    (set_attr "mode" "SI")])
7639
7640 (define_insn "udivmoddi4"
7641   [(set (match_operand:DI 0 "register_operand" "=a")
7642         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7643                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7644    (set (match_operand:DI 3 "register_operand" "=&d")
7645         (umod:DI (match_dup 1) (match_dup 2)))
7646    (clobber (reg:CC FLAGS_REG))]
7647   "TARGET_64BIT"
7648   "xor{q}\t%3, %3\;div{q}\t%2"
7649   [(set_attr "type" "multi")
7650    (set_attr "length_immediate" "0")
7651    (set_attr "mode" "DI")])
7652
7653 (define_insn "*udivmoddi4_noext"
7654   [(set (match_operand:DI 0 "register_operand" "=a")
7655         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7656                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7657    (set (match_operand:DI 3 "register_operand" "=d")
7658         (umod:DI (match_dup 1) (match_dup 2)))
7659    (use (match_dup 3))
7660    (clobber (reg:CC FLAGS_REG))]
7661   "TARGET_64BIT"
7662   "div{q}\t%2"
7663   [(set_attr "type" "idiv")
7664    (set_attr "mode" "DI")])
7665
7666 (define_split
7667   [(set (match_operand:DI 0 "register_operand" "")
7668         (udiv:DI (match_operand:DI 1 "register_operand" "")
7669                  (match_operand:DI 2 "nonimmediate_operand" "")))
7670    (set (match_operand:DI 3 "register_operand" "")
7671         (umod:DI (match_dup 1) (match_dup 2)))
7672    (clobber (reg:CC FLAGS_REG))]
7673   "TARGET_64BIT && reload_completed"
7674   [(set (match_dup 3) (const_int 0))
7675    (parallel [(set (match_dup 0)
7676                    (udiv:DI (match_dup 1) (match_dup 2)))
7677               (set (match_dup 3)
7678                    (umod:DI (match_dup 1) (match_dup 2)))
7679               (use (match_dup 3))
7680               (clobber (reg:CC FLAGS_REG))])]
7681   "")
7682
7683 (define_insn "udivmodsi4"
7684   [(set (match_operand:SI 0 "register_operand" "=a")
7685         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7686                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7687    (set (match_operand:SI 3 "register_operand" "=&d")
7688         (umod:SI (match_dup 1) (match_dup 2)))
7689    (clobber (reg:CC FLAGS_REG))]
7690   ""
7691   "xor{l}\t%3, %3\;div{l}\t%2"
7692   [(set_attr "type" "multi")
7693    (set_attr "length_immediate" "0")
7694    (set_attr "mode" "SI")])
7695
7696 (define_insn "*udivmodsi4_noext"
7697   [(set (match_operand:SI 0 "register_operand" "=a")
7698         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7699                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7700    (set (match_operand:SI 3 "register_operand" "=d")
7701         (umod:SI (match_dup 1) (match_dup 2)))
7702    (use (match_dup 3))
7703    (clobber (reg:CC FLAGS_REG))]
7704   ""
7705   "div{l}\t%2"
7706   [(set_attr "type" "idiv")
7707    (set_attr "mode" "SI")])
7708
7709 (define_split
7710   [(set (match_operand:SI 0 "register_operand" "")
7711         (udiv:SI (match_operand:SI 1 "register_operand" "")
7712                  (match_operand:SI 2 "nonimmediate_operand" "")))
7713    (set (match_operand:SI 3 "register_operand" "")
7714         (umod:SI (match_dup 1) (match_dup 2)))
7715    (clobber (reg:CC FLAGS_REG))]
7716   "reload_completed"
7717   [(set (match_dup 3) (const_int 0))
7718    (parallel [(set (match_dup 0)
7719                    (udiv:SI (match_dup 1) (match_dup 2)))
7720               (set (match_dup 3)
7721                    (umod:SI (match_dup 1) (match_dup 2)))
7722               (use (match_dup 3))
7723               (clobber (reg:CC FLAGS_REG))])]
7724   "")
7725
7726 (define_expand "udivmodhi4"
7727   [(set (match_dup 4) (const_int 0))
7728    (parallel [(set (match_operand:HI 0 "register_operand" "")
7729                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7730                             (match_operand:HI 2 "nonimmediate_operand" "")))
7731               (set (match_operand:HI 3 "register_operand" "")
7732                    (umod:HI (match_dup 1) (match_dup 2)))
7733               (use (match_dup 4))
7734               (clobber (reg:CC FLAGS_REG))])]
7735   "TARGET_HIMODE_MATH"
7736   "operands[4] = gen_reg_rtx (HImode);")
7737
7738 (define_insn "*udivmodhi_noext"
7739   [(set (match_operand:HI 0 "register_operand" "=a")
7740         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7741                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7742    (set (match_operand:HI 3 "register_operand" "=d")
7743         (umod:HI (match_dup 1) (match_dup 2)))
7744    (use (match_operand:HI 4 "register_operand" "3"))
7745    (clobber (reg:CC FLAGS_REG))]
7746   ""
7747   "div{w}\t%2"
7748   [(set_attr "type" "idiv")
7749    (set_attr "mode" "HI")])
7750
7751 ;; We cannot use div/idiv for double division, because it causes
7752 ;; "division by zero" on the overflow and that's not what we expect
7753 ;; from truncate.  Because true (non truncating) double division is
7754 ;; never generated, we can't create this insn anyway.
7755 ;
7756 ;(define_insn ""
7757 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7758 ;       (truncate:SI
7759 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7760 ;                  (zero_extend:DI
7761 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7762 ;   (set (match_operand:SI 3 "register_operand" "=d")
7763 ;       (truncate:SI
7764 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7765 ;   (clobber (reg:CC FLAGS_REG))]
7766 ;  ""
7767 ;  "div{l}\t{%2, %0|%0, %2}"
7768 ;  [(set_attr "type" "idiv")])
7769 \f
7770 ;;- Logical AND instructions
7771
7772 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7773 ;; Note that this excludes ah.
7774
7775 (define_insn "*testdi_1_rex64"
7776   [(set (reg FLAGS_REG)
7777         (compare
7778           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7779                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7780           (const_int 0)))]
7781   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7782    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7783   "@
7784    test{l}\t{%k1, %k0|%k0, %k1}
7785    test{l}\t{%k1, %k0|%k0, %k1}
7786    test{q}\t{%1, %0|%0, %1}
7787    test{q}\t{%1, %0|%0, %1}
7788    test{q}\t{%1, %0|%0, %1}"
7789   [(set_attr "type" "test")
7790    (set_attr "modrm" "0,1,0,1,1")
7791    (set_attr "mode" "SI,SI,DI,DI,DI")
7792    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7793
7794 (define_insn "testsi_1"
7795   [(set (reg FLAGS_REG)
7796         (compare
7797           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7798                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7799           (const_int 0)))]
7800   "ix86_match_ccmode (insn, CCNOmode)
7801    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7802   "test{l}\t{%1, %0|%0, %1}"
7803   [(set_attr "type" "test")
7804    (set_attr "modrm" "0,1,1")
7805    (set_attr "mode" "SI")
7806    (set_attr "pent_pair" "uv,np,uv")])
7807
7808 (define_expand "testsi_ccno_1"
7809   [(set (reg:CCNO FLAGS_REG)
7810         (compare:CCNO
7811           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7812                   (match_operand:SI 1 "nonmemory_operand" ""))
7813           (const_int 0)))]
7814   ""
7815   "")
7816
7817 (define_insn "*testhi_1"
7818   [(set (reg FLAGS_REG)
7819         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7820                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7821                  (const_int 0)))]
7822   "ix86_match_ccmode (insn, CCNOmode)
7823    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7824   "test{w}\t{%1, %0|%0, %1}"
7825   [(set_attr "type" "test")
7826    (set_attr "modrm" "0,1,1")
7827    (set_attr "mode" "HI")
7828    (set_attr "pent_pair" "uv,np,uv")])
7829
7830 (define_expand "testqi_ccz_1"
7831   [(set (reg:CCZ FLAGS_REG)
7832         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7833                              (match_operand:QI 1 "nonmemory_operand" ""))
7834                  (const_int 0)))]
7835   ""
7836   "")
7837
7838 (define_insn "*testqi_1_maybe_si"
7839   [(set (reg FLAGS_REG)
7840         (compare
7841           (and:QI
7842             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7843             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7844           (const_int 0)))]
7845    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7846     && ix86_match_ccmode (insn,
7847                          GET_CODE (operands[1]) == CONST_INT
7848                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7849 {
7850   if (which_alternative == 3)
7851     {
7852       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7853         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7854       return "test{l}\t{%1, %k0|%k0, %1}";
7855     }
7856   return "test{b}\t{%1, %0|%0, %1}";
7857 }
7858   [(set_attr "type" "test")
7859    (set_attr "modrm" "0,1,1,1")
7860    (set_attr "mode" "QI,QI,QI,SI")
7861    (set_attr "pent_pair" "uv,np,uv,np")])
7862
7863 (define_insn "*testqi_1"
7864   [(set (reg FLAGS_REG)
7865         (compare
7866           (and:QI
7867             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7868             (match_operand:QI 1 "general_operand" "n,n,qn"))
7869           (const_int 0)))]
7870   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7871    && ix86_match_ccmode (insn, CCNOmode)"
7872   "test{b}\t{%1, %0|%0, %1}"
7873   [(set_attr "type" "test")
7874    (set_attr "modrm" "0,1,1")
7875    (set_attr "mode" "QI")
7876    (set_attr "pent_pair" "uv,np,uv")])
7877
7878 (define_expand "testqi_ext_ccno_0"
7879   [(set (reg:CCNO FLAGS_REG)
7880         (compare:CCNO
7881           (and:SI
7882             (zero_extract:SI
7883               (match_operand 0 "ext_register_operand" "")
7884               (const_int 8)
7885               (const_int 8))
7886             (match_operand 1 "const_int_operand" ""))
7887           (const_int 0)))]
7888   ""
7889   "")
7890
7891 (define_insn "*testqi_ext_0"
7892   [(set (reg FLAGS_REG)
7893         (compare
7894           (and:SI
7895             (zero_extract:SI
7896               (match_operand 0 "ext_register_operand" "Q")
7897               (const_int 8)
7898               (const_int 8))
7899             (match_operand 1 "const_int_operand" "n"))
7900           (const_int 0)))]
7901   "ix86_match_ccmode (insn, CCNOmode)"
7902   "test{b}\t{%1, %h0|%h0, %1}"
7903   [(set_attr "type" "test")
7904    (set_attr "mode" "QI")
7905    (set_attr "length_immediate" "1")
7906    (set_attr "pent_pair" "np")])
7907
7908 (define_insn "*testqi_ext_1"
7909   [(set (reg FLAGS_REG)
7910         (compare
7911           (and:SI
7912             (zero_extract:SI
7913               (match_operand 0 "ext_register_operand" "Q")
7914               (const_int 8)
7915               (const_int 8))
7916             (zero_extend:SI
7917               (match_operand:QI 1 "general_operand" "Qm")))
7918           (const_int 0)))]
7919   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7921   "test{b}\t{%1, %h0|%h0, %1}"
7922   [(set_attr "type" "test")
7923    (set_attr "mode" "QI")])
7924
7925 (define_insn "*testqi_ext_1_rex64"
7926   [(set (reg FLAGS_REG)
7927         (compare
7928           (and:SI
7929             (zero_extract:SI
7930               (match_operand 0 "ext_register_operand" "Q")
7931               (const_int 8)
7932               (const_int 8))
7933             (zero_extend:SI
7934               (match_operand:QI 1 "register_operand" "Q")))
7935           (const_int 0)))]
7936   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7937   "test{b}\t{%1, %h0|%h0, %1}"
7938   [(set_attr "type" "test")
7939    (set_attr "mode" "QI")])
7940
7941 (define_insn "*testqi_ext_2"
7942   [(set (reg FLAGS_REG)
7943         (compare
7944           (and:SI
7945             (zero_extract:SI
7946               (match_operand 0 "ext_register_operand" "Q")
7947               (const_int 8)
7948               (const_int 8))
7949             (zero_extract:SI
7950               (match_operand 1 "ext_register_operand" "Q")
7951               (const_int 8)
7952               (const_int 8)))
7953           (const_int 0)))]
7954   "ix86_match_ccmode (insn, CCNOmode)"
7955   "test{b}\t{%h1, %h0|%h0, %h1}"
7956   [(set_attr "type" "test")
7957    (set_attr "mode" "QI")])
7958
7959 ;; Combine likes to form bit extractions for some tests.  Humor it.
7960 (define_insn "*testqi_ext_3"
7961   [(set (reg FLAGS_REG)
7962         (compare (zero_extract:SI
7963                    (match_operand 0 "nonimmediate_operand" "rm")
7964                    (match_operand:SI 1 "const_int_operand" "")
7965                    (match_operand:SI 2 "const_int_operand" ""))
7966                  (const_int 0)))]
7967   "ix86_match_ccmode (insn, CCNOmode)
7968    && (GET_MODE (operands[0]) == SImode
7969        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7970        || GET_MODE (operands[0]) == HImode
7971        || GET_MODE (operands[0]) == QImode)"
7972   "#")
7973
7974 (define_insn "*testqi_ext_3_rex64"
7975   [(set (reg FLAGS_REG)
7976         (compare (zero_extract:DI
7977                    (match_operand 0 "nonimmediate_operand" "rm")
7978                    (match_operand:DI 1 "const_int_operand" "")
7979                    (match_operand:DI 2 "const_int_operand" ""))
7980                  (const_int 0)))]
7981   "TARGET_64BIT
7982    && ix86_match_ccmode (insn, CCNOmode)
7983    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7984    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7985    /* Ensure that resulting mask is zero or sign extended operand.  */
7986    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7987        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7988            && INTVAL (operands[1]) > 32))
7989    && (GET_MODE (operands[0]) == SImode
7990        || GET_MODE (operands[0]) == DImode
7991        || GET_MODE (operands[0]) == HImode
7992        || GET_MODE (operands[0]) == QImode)"
7993   "#")
7994
7995 (define_split
7996   [(set (match_operand 0 "flags_reg_operand" "")
7997         (match_operator 1 "compare_operator"
7998           [(zero_extract
7999              (match_operand 2 "nonimmediate_operand" "")
8000              (match_operand 3 "const_int_operand" "")
8001              (match_operand 4 "const_int_operand" ""))
8002            (const_int 0)]))]
8003   "ix86_match_ccmode (insn, CCNOmode)"
8004   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8005 {
8006   rtx val = operands[2];
8007   HOST_WIDE_INT len = INTVAL (operands[3]);
8008   HOST_WIDE_INT pos = INTVAL (operands[4]);
8009   HOST_WIDE_INT mask;
8010   enum machine_mode mode, submode;
8011
8012   mode = GET_MODE (val);
8013   if (GET_CODE (val) == MEM)
8014     {
8015       /* ??? Combine likes to put non-volatile mem extractions in QImode
8016          no matter the size of the test.  So find a mode that works.  */
8017       if (! MEM_VOLATILE_P (val))
8018         {
8019           mode = smallest_mode_for_size (pos + len, MODE_INT);
8020           val = adjust_address (val, mode, 0);
8021         }
8022     }
8023   else if (GET_CODE (val) == SUBREG
8024            && (submode = GET_MODE (SUBREG_REG (val)),
8025                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8026            && pos + len <= GET_MODE_BITSIZE (submode))
8027     {
8028       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8029       mode = submode;
8030       val = SUBREG_REG (val);
8031     }
8032   else if (mode == HImode && pos + len <= 8)
8033     {
8034       /* Small HImode tests can be converted to QImode.  */
8035       mode = QImode;
8036       val = gen_lowpart (QImode, val);
8037     }
8038
8039   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8040   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8041
8042   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8043 })
8044
8045 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8046 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8047 ;; this is relatively important trick.
8048 ;; Do the conversion only post-reload to avoid limiting of the register class
8049 ;; to QI regs.
8050 (define_split
8051   [(set (match_operand 0 "flags_reg_operand" "")
8052         (match_operator 1 "compare_operator"
8053           [(and (match_operand 2 "register_operand" "")
8054                 (match_operand 3 "const_int_operand" ""))
8055            (const_int 0)]))]
8056    "reload_completed
8057     && QI_REG_P (operands[2])
8058     && GET_MODE (operands[2]) != QImode
8059     && ((ix86_match_ccmode (insn, CCZmode)
8060          && !(INTVAL (operands[3]) & ~(255 << 8)))
8061         || (ix86_match_ccmode (insn, CCNOmode)
8062             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8063   [(set (match_dup 0)
8064         (match_op_dup 1
8065           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8066                    (match_dup 3))
8067            (const_int 0)]))]
8068   "operands[2] = gen_lowpart (SImode, operands[2]);
8069    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8070
8071 (define_split
8072   [(set (match_operand 0 "flags_reg_operand" "")
8073         (match_operator 1 "compare_operator"
8074           [(and (match_operand 2 "nonimmediate_operand" "")
8075                 (match_operand 3 "const_int_operand" ""))
8076            (const_int 0)]))]
8077    "reload_completed
8078     && GET_MODE (operands[2]) != QImode
8079     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8080     && ((ix86_match_ccmode (insn, CCZmode)
8081          && !(INTVAL (operands[3]) & ~255))
8082         || (ix86_match_ccmode (insn, CCNOmode)
8083             && !(INTVAL (operands[3]) & ~127)))"
8084   [(set (match_dup 0)
8085         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8086                          (const_int 0)]))]
8087   "operands[2] = gen_lowpart (QImode, operands[2]);
8088    operands[3] = gen_lowpart (QImode, operands[3]);")
8089
8090
8091 ;; %%% This used to optimize known byte-wide and operations to memory,
8092 ;; and sometimes to QImode registers.  If this is considered useful,
8093 ;; it should be done with splitters.
8094
8095 (define_expand "anddi3"
8096   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8097         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8098                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "TARGET_64BIT"
8101   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8102
8103 (define_insn "*anddi_1_rex64"
8104   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8105         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8106                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8107    (clobber (reg:CC FLAGS_REG))]
8108   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8109 {
8110   switch (get_attr_type (insn))
8111     {
8112     case TYPE_IMOVX:
8113       {
8114         enum machine_mode mode;
8115
8116         if (GET_CODE (operands[2]) != CONST_INT)
8117           abort ();
8118         if (INTVAL (operands[2]) == 0xff)
8119           mode = QImode;
8120         else if (INTVAL (operands[2]) == 0xffff)
8121           mode = HImode;
8122         else
8123           abort ();
8124         
8125         operands[1] = gen_lowpart (mode, operands[1]);
8126         if (mode == QImode)
8127           return "movz{bq|x}\t{%1,%0|%0, %1}";
8128         else
8129           return "movz{wq|x}\t{%1,%0|%0, %1}";
8130       }
8131
8132     default:
8133       if (! rtx_equal_p (operands[0], operands[1]))
8134         abort ();
8135       if (get_attr_mode (insn) == MODE_SI)
8136         return "and{l}\t{%k2, %k0|%k0, %k2}";
8137       else
8138         return "and{q}\t{%2, %0|%0, %2}";
8139     }
8140 }
8141   [(set_attr "type" "alu,alu,alu,imovx")
8142    (set_attr "length_immediate" "*,*,*,0")
8143    (set_attr "mode" "SI,DI,DI,DI")])
8144
8145 (define_insn "*anddi_2"
8146   [(set (reg FLAGS_REG)
8147         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8148                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8149                  (const_int 0)))
8150    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8151         (and:DI (match_dup 1) (match_dup 2)))]
8152   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8153    && ix86_binary_operator_ok (AND, DImode, operands)"
8154   "@
8155    and{l}\t{%k2, %k0|%k0, %k2}
8156    and{q}\t{%2, %0|%0, %2}
8157    and{q}\t{%2, %0|%0, %2}"
8158   [(set_attr "type" "alu")
8159    (set_attr "mode" "SI,DI,DI")])
8160
8161 (define_expand "andsi3"
8162   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8163         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8164                 (match_operand:SI 2 "general_operand" "")))
8165    (clobber (reg:CC FLAGS_REG))]
8166   ""
8167   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8168
8169 (define_insn "*andsi_1"
8170   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8171         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8172                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8173    (clobber (reg:CC FLAGS_REG))]
8174   "ix86_binary_operator_ok (AND, SImode, operands)"
8175 {
8176   switch (get_attr_type (insn))
8177     {
8178     case TYPE_IMOVX:
8179       {
8180         enum machine_mode mode;
8181
8182         if (GET_CODE (operands[2]) != CONST_INT)
8183           abort ();
8184         if (INTVAL (operands[2]) == 0xff)
8185           mode = QImode;
8186         else if (INTVAL (operands[2]) == 0xffff)
8187           mode = HImode;
8188         else
8189           abort ();
8190         
8191         operands[1] = gen_lowpart (mode, operands[1]);
8192         if (mode == QImode)
8193           return "movz{bl|x}\t{%1,%0|%0, %1}";
8194         else
8195           return "movz{wl|x}\t{%1,%0|%0, %1}";
8196       }
8197
8198     default:
8199       if (! rtx_equal_p (operands[0], operands[1]))
8200         abort ();
8201       return "and{l}\t{%2, %0|%0, %2}";
8202     }
8203 }
8204   [(set_attr "type" "alu,alu,imovx")
8205    (set_attr "length_immediate" "*,*,0")
8206    (set_attr "mode" "SI")])
8207
8208 (define_split
8209   [(set (match_operand 0 "register_operand" "")
8210         (and (match_dup 0)
8211              (const_int -65536)))
8212    (clobber (reg:CC FLAGS_REG))]
8213   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8214   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8215   "operands[1] = gen_lowpart (HImode, operands[0]);")
8216
8217 (define_split
8218   [(set (match_operand 0 "ext_register_operand" "")
8219         (and (match_dup 0)
8220              (const_int -256)))
8221    (clobber (reg:CC FLAGS_REG))]
8222   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8223   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8224   "operands[1] = gen_lowpart (QImode, operands[0]);")
8225
8226 (define_split
8227   [(set (match_operand 0 "ext_register_operand" "")
8228         (and (match_dup 0)
8229              (const_int -65281)))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8232   [(parallel [(set (zero_extract:SI (match_dup 0)
8233                                     (const_int 8)
8234                                     (const_int 8))
8235                    (xor:SI 
8236                      (zero_extract:SI (match_dup 0)
8237                                       (const_int 8)
8238                                       (const_int 8))
8239                      (zero_extract:SI (match_dup 0)
8240                                       (const_int 8)
8241                                       (const_int 8))))
8242               (clobber (reg:CC FLAGS_REG))])]
8243   "operands[0] = gen_lowpart (SImode, operands[0]);")
8244
8245 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8246 (define_insn "*andsi_1_zext"
8247   [(set (match_operand:DI 0 "register_operand" "=r")
8248         (zero_extend:DI
8249           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250                   (match_operand:SI 2 "general_operand" "rim"))))
8251    (clobber (reg:CC FLAGS_REG))]
8252   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8253   "and{l}\t{%2, %k0|%k0, %2}"
8254   [(set_attr "type" "alu")
8255    (set_attr "mode" "SI")])
8256
8257 (define_insn "*andsi_2"
8258   [(set (reg FLAGS_REG)
8259         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8260                          (match_operand:SI 2 "general_operand" "rim,ri"))
8261                  (const_int 0)))
8262    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8263         (and:SI (match_dup 1) (match_dup 2)))]
8264   "ix86_match_ccmode (insn, CCNOmode)
8265    && ix86_binary_operator_ok (AND, SImode, operands)"
8266   "and{l}\t{%2, %0|%0, %2}"
8267   [(set_attr "type" "alu")
8268    (set_attr "mode" "SI")])
8269
8270 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8271 (define_insn "*andsi_2_zext"
8272   [(set (reg FLAGS_REG)
8273         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8274                          (match_operand:SI 2 "general_operand" "rim"))
8275                  (const_int 0)))
8276    (set (match_operand:DI 0 "register_operand" "=r")
8277         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8278   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8279    && ix86_binary_operator_ok (AND, SImode, operands)"
8280   "and{l}\t{%2, %k0|%k0, %2}"
8281   [(set_attr "type" "alu")
8282    (set_attr "mode" "SI")])
8283
8284 (define_expand "andhi3"
8285   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8286         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8287                 (match_operand:HI 2 "general_operand" "")))
8288    (clobber (reg:CC FLAGS_REG))]
8289   "TARGET_HIMODE_MATH"
8290   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8291
8292 (define_insn "*andhi_1"
8293   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8294         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8295                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "ix86_binary_operator_ok (AND, HImode, operands)"
8298 {
8299   switch (get_attr_type (insn))
8300     {
8301     case TYPE_IMOVX:
8302       if (GET_CODE (operands[2]) != CONST_INT)
8303         abort ();
8304       if (INTVAL (operands[2]) == 0xff)
8305         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8306       abort ();
8307
8308     default:
8309       if (! rtx_equal_p (operands[0], operands[1]))
8310         abort ();
8311
8312       return "and{w}\t{%2, %0|%0, %2}";
8313     }
8314 }
8315   [(set_attr "type" "alu,alu,imovx")
8316    (set_attr "length_immediate" "*,*,0")
8317    (set_attr "mode" "HI,HI,SI")])
8318
8319 (define_insn "*andhi_2"
8320   [(set (reg FLAGS_REG)
8321         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8322                          (match_operand:HI 2 "general_operand" "rim,ri"))
8323                  (const_int 0)))
8324    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8325         (and:HI (match_dup 1) (match_dup 2)))]
8326   "ix86_match_ccmode (insn, CCNOmode)
8327    && ix86_binary_operator_ok (AND, HImode, operands)"
8328   "and{w}\t{%2, %0|%0, %2}"
8329   [(set_attr "type" "alu")
8330    (set_attr "mode" "HI")])
8331
8332 (define_expand "andqi3"
8333   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8334         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8335                 (match_operand:QI 2 "general_operand" "")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "TARGET_QIMODE_MATH"
8338   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8339
8340 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8341 (define_insn "*andqi_1"
8342   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8343         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8344                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "ix86_binary_operator_ok (AND, QImode, operands)"
8347   "@
8348    and{b}\t{%2, %0|%0, %2}
8349    and{b}\t{%2, %0|%0, %2}
8350    and{l}\t{%k2, %k0|%k0, %k2}"
8351   [(set_attr "type" "alu")
8352    (set_attr "mode" "QI,QI,SI")])
8353
8354 (define_insn "*andqi_1_slp"
8355   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8356         (and:QI (match_dup 0)
8357                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8358    (clobber (reg:CC FLAGS_REG))]
8359   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8360    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8361   "and{b}\t{%1, %0|%0, %1}"
8362   [(set_attr "type" "alu1")
8363    (set_attr "mode" "QI")])
8364
8365 (define_insn "*andqi_2_maybe_si"
8366   [(set (reg FLAGS_REG)
8367         (compare (and:QI
8368                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8369                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8370                  (const_int 0)))
8371    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8372         (and:QI (match_dup 1) (match_dup 2)))]
8373   "ix86_binary_operator_ok (AND, QImode, operands)
8374    && ix86_match_ccmode (insn,
8375                          GET_CODE (operands[2]) == CONST_INT
8376                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8377 {
8378   if (which_alternative == 2)
8379     {
8380       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8381         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8382       return "and{l}\t{%2, %k0|%k0, %2}";
8383     }
8384   return "and{b}\t{%2, %0|%0, %2}";
8385 }
8386   [(set_attr "type" "alu")
8387    (set_attr "mode" "QI,QI,SI")])
8388
8389 (define_insn "*andqi_2"
8390   [(set (reg FLAGS_REG)
8391         (compare (and:QI
8392                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8393                    (match_operand:QI 2 "general_operand" "qim,qi"))
8394                  (const_int 0)))
8395    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8396         (and:QI (match_dup 1) (match_dup 2)))]
8397   "ix86_match_ccmode (insn, CCNOmode)
8398    && ix86_binary_operator_ok (AND, QImode, operands)"
8399   "and{b}\t{%2, %0|%0, %2}"
8400   [(set_attr "type" "alu")
8401    (set_attr "mode" "QI")])
8402
8403 (define_insn "*andqi_2_slp"
8404   [(set (reg FLAGS_REG)
8405         (compare (and:QI
8406                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8407                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8408                  (const_int 0)))
8409    (set (strict_low_part (match_dup 0))
8410         (and:QI (match_dup 0) (match_dup 1)))]
8411   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8412    && ix86_match_ccmode (insn, CCNOmode)
8413    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8414   "and{b}\t{%1, %0|%0, %1}"
8415   [(set_attr "type" "alu1")
8416    (set_attr "mode" "QI")])
8417
8418 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8419 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8420 ;; for a QImode operand, which of course failed.
8421
8422 (define_insn "andqi_ext_0"
8423   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8424                          (const_int 8)
8425                          (const_int 8))
8426         (and:SI 
8427           (zero_extract:SI
8428             (match_operand 1 "ext_register_operand" "0")
8429             (const_int 8)
8430             (const_int 8))
8431           (match_operand 2 "const_int_operand" "n")))
8432    (clobber (reg:CC FLAGS_REG))]
8433   ""
8434   "and{b}\t{%2, %h0|%h0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "length_immediate" "1")
8437    (set_attr "mode" "QI")])
8438
8439 ;; Generated by peephole translating test to and.  This shows up
8440 ;; often in fp comparisons.
8441
8442 (define_insn "*andqi_ext_0_cc"
8443   [(set (reg FLAGS_REG)
8444         (compare
8445           (and:SI
8446             (zero_extract:SI
8447               (match_operand 1 "ext_register_operand" "0")
8448               (const_int 8)
8449               (const_int 8))
8450             (match_operand 2 "const_int_operand" "n"))
8451           (const_int 0)))
8452    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8453                          (const_int 8)
8454                          (const_int 8))
8455         (and:SI 
8456           (zero_extract:SI
8457             (match_dup 1)
8458             (const_int 8)
8459             (const_int 8))
8460           (match_dup 2)))]
8461   "ix86_match_ccmode (insn, CCNOmode)"
8462   "and{b}\t{%2, %h0|%h0, %2}"
8463   [(set_attr "type" "alu")
8464    (set_attr "length_immediate" "1")
8465    (set_attr "mode" "QI")])
8466
8467 (define_insn "*andqi_ext_1"
8468   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8469                          (const_int 8)
8470                          (const_int 8))
8471         (and:SI 
8472           (zero_extract:SI
8473             (match_operand 1 "ext_register_operand" "0")
8474             (const_int 8)
8475             (const_int 8))
8476           (zero_extend:SI
8477             (match_operand:QI 2 "general_operand" "Qm"))))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "!TARGET_64BIT"
8480   "and{b}\t{%2, %h0|%h0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "length_immediate" "0")
8483    (set_attr "mode" "QI")])
8484
8485 (define_insn "*andqi_ext_1_rex64"
8486   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8487                          (const_int 8)
8488                          (const_int 8))
8489         (and:SI 
8490           (zero_extract:SI
8491             (match_operand 1 "ext_register_operand" "0")
8492             (const_int 8)
8493             (const_int 8))
8494           (zero_extend:SI
8495             (match_operand 2 "ext_register_operand" "Q"))))
8496    (clobber (reg:CC FLAGS_REG))]
8497   "TARGET_64BIT"
8498   "and{b}\t{%2, %h0|%h0, %2}"
8499   [(set_attr "type" "alu")
8500    (set_attr "length_immediate" "0")
8501    (set_attr "mode" "QI")])
8502
8503 (define_insn "*andqi_ext_2"
8504   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8505                          (const_int 8)
8506                          (const_int 8))
8507         (and:SI
8508           (zero_extract:SI
8509             (match_operand 1 "ext_register_operand" "%0")
8510             (const_int 8)
8511             (const_int 8))
8512           (zero_extract:SI
8513             (match_operand 2 "ext_register_operand" "Q")
8514             (const_int 8)
8515             (const_int 8))))
8516    (clobber (reg:CC FLAGS_REG))]
8517   ""
8518   "and{b}\t{%h2, %h0|%h0, %h2}"
8519   [(set_attr "type" "alu")
8520    (set_attr "length_immediate" "0")
8521    (set_attr "mode" "QI")])
8522
8523 ;; Convert wide AND instructions with immediate operand to shorter QImode
8524 ;; equivalents when possible.
8525 ;; Don't do the splitting with memory operands, since it introduces risk
8526 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8527 ;; for size, but that can (should?) be handled by generic code instead.
8528 (define_split
8529   [(set (match_operand 0 "register_operand" "")
8530         (and (match_operand 1 "register_operand" "")
8531              (match_operand 2 "const_int_operand" "")))
8532    (clobber (reg:CC FLAGS_REG))]
8533    "reload_completed
8534     && QI_REG_P (operands[0])
8535     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8536     && !(~INTVAL (operands[2]) & ~(255 << 8))
8537     && GET_MODE (operands[0]) != QImode"
8538   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8539                    (and:SI (zero_extract:SI (match_dup 1)
8540                                             (const_int 8) (const_int 8))
8541                            (match_dup 2)))
8542               (clobber (reg:CC FLAGS_REG))])]
8543   "operands[0] = gen_lowpart (SImode, operands[0]);
8544    operands[1] = gen_lowpart (SImode, operands[1]);
8545    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8546
8547 ;; Since AND can be encoded with sign extended immediate, this is only
8548 ;; profitable when 7th bit is not set.
8549 (define_split
8550   [(set (match_operand 0 "register_operand" "")
8551         (and (match_operand 1 "general_operand" "")
8552              (match_operand 2 "const_int_operand" "")))
8553    (clobber (reg:CC FLAGS_REG))]
8554    "reload_completed
8555     && ANY_QI_REG_P (operands[0])
8556     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8557     && !(~INTVAL (operands[2]) & ~255)
8558     && !(INTVAL (operands[2]) & 128)
8559     && GET_MODE (operands[0]) != QImode"
8560   [(parallel [(set (strict_low_part (match_dup 0))
8561                    (and:QI (match_dup 1)
8562                            (match_dup 2)))
8563               (clobber (reg:CC FLAGS_REG))])]
8564   "operands[0] = gen_lowpart (QImode, operands[0]);
8565    operands[1] = gen_lowpart (QImode, operands[1]);
8566    operands[2] = gen_lowpart (QImode, operands[2]);")
8567 \f
8568 ;; Logical inclusive OR instructions
8569
8570 ;; %%% This used to optimize known byte-wide and operations to memory.
8571 ;; If this is considered useful, it should be done with splitters.
8572
8573 (define_expand "iordi3"
8574   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8575         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8576                 (match_operand:DI 2 "x86_64_general_operand" "")))
8577    (clobber (reg:CC FLAGS_REG))]
8578   "TARGET_64BIT"
8579   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8580
8581 (define_insn "*iordi_1_rex64"
8582   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8583         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8584                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "TARGET_64BIT
8587    && ix86_binary_operator_ok (IOR, DImode, operands)"
8588   "or{q}\t{%2, %0|%0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "DI")])
8591
8592 (define_insn "*iordi_2_rex64"
8593   [(set (reg FLAGS_REG)
8594         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8595                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8596                  (const_int 0)))
8597    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8598         (ior:DI (match_dup 1) (match_dup 2)))]
8599   "TARGET_64BIT
8600    && ix86_match_ccmode (insn, CCNOmode)
8601    && ix86_binary_operator_ok (IOR, DImode, operands)"
8602   "or{q}\t{%2, %0|%0, %2}"
8603   [(set_attr "type" "alu")
8604    (set_attr "mode" "DI")])
8605
8606 (define_insn "*iordi_3_rex64"
8607   [(set (reg FLAGS_REG)
8608         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8609                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8610                  (const_int 0)))
8611    (clobber (match_scratch:DI 0 "=r"))]
8612   "TARGET_64BIT
8613    && ix86_match_ccmode (insn, CCNOmode)
8614    && ix86_binary_operator_ok (IOR, DImode, operands)"
8615   "or{q}\t{%2, %0|%0, %2}"
8616   [(set_attr "type" "alu")
8617    (set_attr "mode" "DI")])
8618
8619
8620 (define_expand "iorsi3"
8621   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8622         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8623                 (match_operand:SI 2 "general_operand" "")))
8624    (clobber (reg:CC FLAGS_REG))]
8625   ""
8626   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8627
8628 (define_insn "*iorsi_1"
8629   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8630         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8631                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   "ix86_binary_operator_ok (IOR, SImode, operands)"
8634   "or{l}\t{%2, %0|%0, %2}"
8635   [(set_attr "type" "alu")
8636    (set_attr "mode" "SI")])
8637
8638 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8639 (define_insn "*iorsi_1_zext"
8640   [(set (match_operand:DI 0 "register_operand" "=rm")
8641         (zero_extend:DI
8642           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8643                   (match_operand:SI 2 "general_operand" "rim"))))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8646   "or{l}\t{%2, %k0|%k0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "SI")])
8649
8650 (define_insn "*iorsi_1_zext_imm"
8651   [(set (match_operand:DI 0 "register_operand" "=rm")
8652         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8653                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8654    (clobber (reg:CC FLAGS_REG))]
8655   "TARGET_64BIT"
8656   "or{l}\t{%2, %k0|%k0, %2}"
8657   [(set_attr "type" "alu")
8658    (set_attr "mode" "SI")])
8659
8660 (define_insn "*iorsi_2"
8661   [(set (reg FLAGS_REG)
8662         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8663                          (match_operand:SI 2 "general_operand" "rim,ri"))
8664                  (const_int 0)))
8665    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8666         (ior:SI (match_dup 1) (match_dup 2)))]
8667   "ix86_match_ccmode (insn, CCNOmode)
8668    && ix86_binary_operator_ok (IOR, SImode, operands)"
8669   "or{l}\t{%2, %0|%0, %2}"
8670   [(set_attr "type" "alu")
8671    (set_attr "mode" "SI")])
8672
8673 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8674 ;; ??? Special case for immediate operand is missing - it is tricky.
8675 (define_insn "*iorsi_2_zext"
8676   [(set (reg FLAGS_REG)
8677         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678                          (match_operand:SI 2 "general_operand" "rim"))
8679                  (const_int 0)))
8680    (set (match_operand:DI 0 "register_operand" "=r")
8681         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8682   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8683    && ix86_binary_operator_ok (IOR, SImode, operands)"
8684   "or{l}\t{%2, %k0|%k0, %2}"
8685   [(set_attr "type" "alu")
8686    (set_attr "mode" "SI")])
8687
8688 (define_insn "*iorsi_2_zext_imm"
8689   [(set (reg FLAGS_REG)
8690         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8691                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8692                  (const_int 0)))
8693    (set (match_operand:DI 0 "register_operand" "=r")
8694         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8695   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8696    && ix86_binary_operator_ok (IOR, SImode, operands)"
8697   "or{l}\t{%2, %k0|%k0, %2}"
8698   [(set_attr "type" "alu")
8699    (set_attr "mode" "SI")])
8700
8701 (define_insn "*iorsi_3"
8702   [(set (reg FLAGS_REG)
8703         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8704                          (match_operand:SI 2 "general_operand" "rim"))
8705                  (const_int 0)))
8706    (clobber (match_scratch:SI 0 "=r"))]
8707   "ix86_match_ccmode (insn, CCNOmode)
8708    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8709   "or{l}\t{%2, %0|%0, %2}"
8710   [(set_attr "type" "alu")
8711    (set_attr "mode" "SI")])
8712
8713 (define_expand "iorhi3"
8714   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8715         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8716                 (match_operand:HI 2 "general_operand" "")))
8717    (clobber (reg:CC FLAGS_REG))]
8718   "TARGET_HIMODE_MATH"
8719   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8720
8721 (define_insn "*iorhi_1"
8722   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8723         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8724                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8725    (clobber (reg:CC FLAGS_REG))]
8726   "ix86_binary_operator_ok (IOR, HImode, operands)"
8727   "or{w}\t{%2, %0|%0, %2}"
8728   [(set_attr "type" "alu")
8729    (set_attr "mode" "HI")])
8730
8731 (define_insn "*iorhi_2"
8732   [(set (reg FLAGS_REG)
8733         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8734                          (match_operand:HI 2 "general_operand" "rim,ri"))
8735                  (const_int 0)))
8736    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8737         (ior:HI (match_dup 1) (match_dup 2)))]
8738   "ix86_match_ccmode (insn, CCNOmode)
8739    && ix86_binary_operator_ok (IOR, HImode, operands)"
8740   "or{w}\t{%2, %0|%0, %2}"
8741   [(set_attr "type" "alu")
8742    (set_attr "mode" "HI")])
8743
8744 (define_insn "*iorhi_3"
8745   [(set (reg FLAGS_REG)
8746         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8747                          (match_operand:HI 2 "general_operand" "rim"))
8748                  (const_int 0)))
8749    (clobber (match_scratch:HI 0 "=r"))]
8750   "ix86_match_ccmode (insn, CCNOmode)
8751    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8752   "or{w}\t{%2, %0|%0, %2}"
8753   [(set_attr "type" "alu")
8754    (set_attr "mode" "HI")])
8755
8756 (define_expand "iorqi3"
8757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8758         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8759                 (match_operand:QI 2 "general_operand" "")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "TARGET_QIMODE_MATH"
8762   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8763
8764 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8765 (define_insn "*iorqi_1"
8766   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8767         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8768                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "ix86_binary_operator_ok (IOR, QImode, operands)"
8771   "@
8772    or{b}\t{%2, %0|%0, %2}
8773    or{b}\t{%2, %0|%0, %2}
8774    or{l}\t{%k2, %k0|%k0, %k2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "mode" "QI,QI,SI")])
8777
8778 (define_insn "*iorqi_1_slp"
8779   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8780         (ior:QI (match_dup 0)
8781                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8782    (clobber (reg:CC FLAGS_REG))]
8783   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8784    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8785   "or{b}\t{%1, %0|%0, %1}"
8786   [(set_attr "type" "alu1")
8787    (set_attr "mode" "QI")])
8788
8789 (define_insn "*iorqi_2"
8790   [(set (reg FLAGS_REG)
8791         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8792                          (match_operand:QI 2 "general_operand" "qim,qi"))
8793                  (const_int 0)))
8794    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8795         (ior:QI (match_dup 1) (match_dup 2)))]
8796   "ix86_match_ccmode (insn, CCNOmode)
8797    && ix86_binary_operator_ok (IOR, QImode, operands)"
8798   "or{b}\t{%2, %0|%0, %2}"
8799   [(set_attr "type" "alu")
8800    (set_attr "mode" "QI")])
8801
8802 (define_insn "*iorqi_2_slp"
8803   [(set (reg FLAGS_REG)
8804         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8805                          (match_operand:QI 1 "general_operand" "qim,qi"))
8806                  (const_int 0)))
8807    (set (strict_low_part (match_dup 0))
8808         (ior:QI (match_dup 0) (match_dup 1)))]
8809   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8810    && ix86_match_ccmode (insn, CCNOmode)
8811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8812   "or{b}\t{%1, %0|%0, %1}"
8813   [(set_attr "type" "alu1")
8814    (set_attr "mode" "QI")])
8815
8816 (define_insn "*iorqi_3"
8817   [(set (reg FLAGS_REG)
8818         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8819                          (match_operand:QI 2 "general_operand" "qim"))
8820                  (const_int 0)))
8821    (clobber (match_scratch:QI 0 "=q"))]
8822   "ix86_match_ccmode (insn, CCNOmode)
8823    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8824   "or{b}\t{%2, %0|%0, %2}"
8825   [(set_attr "type" "alu")
8826    (set_attr "mode" "QI")])
8827
8828 (define_insn "iorqi_ext_0"
8829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8830                          (const_int 8)
8831                          (const_int 8))
8832         (ior:SI 
8833           (zero_extract:SI
8834             (match_operand 1 "ext_register_operand" "0")
8835             (const_int 8)
8836             (const_int 8))
8837           (match_operand 2 "const_int_operand" "n")))
8838    (clobber (reg:CC FLAGS_REG))]
8839   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8840   "or{b}\t{%2, %h0|%h0, %2}"
8841   [(set_attr "type" "alu")
8842    (set_attr "length_immediate" "1")
8843    (set_attr "mode" "QI")])
8844
8845 (define_insn "*iorqi_ext_1"
8846   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8847                          (const_int 8)
8848                          (const_int 8))
8849         (ior:SI 
8850           (zero_extract:SI
8851             (match_operand 1 "ext_register_operand" "0")
8852             (const_int 8)
8853             (const_int 8))
8854           (zero_extend:SI
8855             (match_operand:QI 2 "general_operand" "Qm"))))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "!TARGET_64BIT
8858    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8859   "or{b}\t{%2, %h0|%h0, %2}"
8860   [(set_attr "type" "alu")
8861    (set_attr "length_immediate" "0")
8862    (set_attr "mode" "QI")])
8863
8864 (define_insn "*iorqi_ext_1_rex64"
8865   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8866                          (const_int 8)
8867                          (const_int 8))
8868         (ior:SI 
8869           (zero_extract:SI
8870             (match_operand 1 "ext_register_operand" "0")
8871             (const_int 8)
8872             (const_int 8))
8873           (zero_extend:SI
8874             (match_operand 2 "ext_register_operand" "Q"))))
8875    (clobber (reg:CC FLAGS_REG))]
8876   "TARGET_64BIT
8877    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8878   "or{b}\t{%2, %h0|%h0, %2}"
8879   [(set_attr "type" "alu")
8880    (set_attr "length_immediate" "0")
8881    (set_attr "mode" "QI")])
8882
8883 (define_insn "*iorqi_ext_2"
8884   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8885                          (const_int 8)
8886                          (const_int 8))
8887         (ior:SI 
8888           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8889                            (const_int 8)
8890                            (const_int 8))
8891           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8892                            (const_int 8)
8893                            (const_int 8))))
8894    (clobber (reg:CC FLAGS_REG))]
8895   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8896   "ior{b}\t{%h2, %h0|%h0, %h2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "length_immediate" "0")
8899    (set_attr "mode" "QI")])
8900
8901 (define_split
8902   [(set (match_operand 0 "register_operand" "")
8903         (ior (match_operand 1 "register_operand" "")
8904              (match_operand 2 "const_int_operand" "")))
8905    (clobber (reg:CC FLAGS_REG))]
8906    "reload_completed
8907     && QI_REG_P (operands[0])
8908     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8909     && !(INTVAL (operands[2]) & ~(255 << 8))
8910     && GET_MODE (operands[0]) != QImode"
8911   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8912                    (ior:SI (zero_extract:SI (match_dup 1)
8913                                             (const_int 8) (const_int 8))
8914                            (match_dup 2)))
8915               (clobber (reg:CC FLAGS_REG))])]
8916   "operands[0] = gen_lowpart (SImode, operands[0]);
8917    operands[1] = gen_lowpart (SImode, operands[1]);
8918    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8919
8920 ;; Since OR can be encoded with sign extended immediate, this is only
8921 ;; profitable when 7th bit is set.
8922 (define_split
8923   [(set (match_operand 0 "register_operand" "")
8924         (ior (match_operand 1 "general_operand" "")
8925              (match_operand 2 "const_int_operand" "")))
8926    (clobber (reg:CC FLAGS_REG))]
8927    "reload_completed
8928     && ANY_QI_REG_P (operands[0])
8929     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8930     && !(INTVAL (operands[2]) & ~255)
8931     && (INTVAL (operands[2]) & 128)
8932     && GET_MODE (operands[0]) != QImode"
8933   [(parallel [(set (strict_low_part (match_dup 0))
8934                    (ior:QI (match_dup 1)
8935                            (match_dup 2)))
8936               (clobber (reg:CC FLAGS_REG))])]
8937   "operands[0] = gen_lowpart (QImode, operands[0]);
8938    operands[1] = gen_lowpart (QImode, operands[1]);
8939    operands[2] = gen_lowpart (QImode, operands[2]);")
8940 \f
8941 ;; Logical XOR instructions
8942
8943 ;; %%% This used to optimize known byte-wide and operations to memory.
8944 ;; If this is considered useful, it should be done with splitters.
8945
8946 (define_expand "xordi3"
8947   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8948         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8949                 (match_operand:DI 2 "x86_64_general_operand" "")))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "TARGET_64BIT"
8952   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8953
8954 (define_insn "*xordi_1_rex64"
8955   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8956         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8957                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8958    (clobber (reg:CC FLAGS_REG))]
8959   "TARGET_64BIT
8960    && ix86_binary_operator_ok (XOR, DImode, operands)"
8961   "@
8962    xor{q}\t{%2, %0|%0, %2}
8963    xor{q}\t{%2, %0|%0, %2}"
8964   [(set_attr "type" "alu")
8965    (set_attr "mode" "DI,DI")])
8966
8967 (define_insn "*xordi_2_rex64"
8968   [(set (reg FLAGS_REG)
8969         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8970                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8971                  (const_int 0)))
8972    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8973         (xor:DI (match_dup 1) (match_dup 2)))]
8974   "TARGET_64BIT
8975    && ix86_match_ccmode (insn, CCNOmode)
8976    && ix86_binary_operator_ok (XOR, DImode, operands)"
8977   "@
8978    xor{q}\t{%2, %0|%0, %2}
8979    xor{q}\t{%2, %0|%0, %2}"
8980   [(set_attr "type" "alu")
8981    (set_attr "mode" "DI,DI")])
8982
8983 (define_insn "*xordi_3_rex64"
8984   [(set (reg FLAGS_REG)
8985         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8986                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8987                  (const_int 0)))
8988    (clobber (match_scratch:DI 0 "=r"))]
8989   "TARGET_64BIT
8990    && ix86_match_ccmode (insn, CCNOmode)
8991    && ix86_binary_operator_ok (XOR, DImode, operands)"
8992   "xor{q}\t{%2, %0|%0, %2}"
8993   [(set_attr "type" "alu")
8994    (set_attr "mode" "DI")])
8995
8996 (define_expand "xorsi3"
8997   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8998         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8999                 (match_operand:SI 2 "general_operand" "")))
9000    (clobber (reg:CC FLAGS_REG))]
9001   ""
9002   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9003
9004 (define_insn "*xorsi_1"
9005   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9006         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9007                 (match_operand:SI 2 "general_operand" "ri,rm")))
9008    (clobber (reg:CC FLAGS_REG))]
9009   "ix86_binary_operator_ok (XOR, SImode, operands)"
9010   "xor{l}\t{%2, %0|%0, %2}"
9011   [(set_attr "type" "alu")
9012    (set_attr "mode" "SI")])
9013
9014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9015 ;; Add speccase for immediates
9016 (define_insn "*xorsi_1_zext"
9017   [(set (match_operand:DI 0 "register_operand" "=r")
9018         (zero_extend:DI
9019           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9020                   (match_operand:SI 2 "general_operand" "rim"))))
9021    (clobber (reg:CC FLAGS_REG))]
9022   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9023   "xor{l}\t{%2, %k0|%k0, %2}"
9024   [(set_attr "type" "alu")
9025    (set_attr "mode" "SI")])
9026
9027 (define_insn "*xorsi_1_zext_imm"
9028   [(set (match_operand:DI 0 "register_operand" "=r")
9029         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9030                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9031    (clobber (reg:CC FLAGS_REG))]
9032   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9033   "xor{l}\t{%2, %k0|%k0, %2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "mode" "SI")])
9036
9037 (define_insn "*xorsi_2"
9038   [(set (reg FLAGS_REG)
9039         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9040                          (match_operand:SI 2 "general_operand" "rim,ri"))
9041                  (const_int 0)))
9042    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9043         (xor:SI (match_dup 1) (match_dup 2)))]
9044   "ix86_match_ccmode (insn, CCNOmode)
9045    && ix86_binary_operator_ok (XOR, SImode, operands)"
9046   "xor{l}\t{%2, %0|%0, %2}"
9047   [(set_attr "type" "alu")
9048    (set_attr "mode" "SI")])
9049
9050 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9051 ;; ??? Special case for immediate operand is missing - it is tricky.
9052 (define_insn "*xorsi_2_zext"
9053   [(set (reg FLAGS_REG)
9054         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055                          (match_operand:SI 2 "general_operand" "rim"))
9056                  (const_int 0)))
9057    (set (match_operand:DI 0 "register_operand" "=r")
9058         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9059   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9060    && ix86_binary_operator_ok (XOR, SImode, operands)"
9061   "xor{l}\t{%2, %k0|%k0, %2}"
9062   [(set_attr "type" "alu")
9063    (set_attr "mode" "SI")])
9064
9065 (define_insn "*xorsi_2_zext_imm"
9066   [(set (reg FLAGS_REG)
9067         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9068                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9069                  (const_int 0)))
9070    (set (match_operand:DI 0 "register_operand" "=r")
9071         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9072   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9073    && ix86_binary_operator_ok (XOR, SImode, operands)"
9074   "xor{l}\t{%2, %k0|%k0, %2}"
9075   [(set_attr "type" "alu")
9076    (set_attr "mode" "SI")])
9077
9078 (define_insn "*xorsi_3"
9079   [(set (reg FLAGS_REG)
9080         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9081                          (match_operand:SI 2 "general_operand" "rim"))
9082                  (const_int 0)))
9083    (clobber (match_scratch:SI 0 "=r"))]
9084   "ix86_match_ccmode (insn, CCNOmode)
9085    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9086   "xor{l}\t{%2, %0|%0, %2}"
9087   [(set_attr "type" "alu")
9088    (set_attr "mode" "SI")])
9089
9090 (define_expand "xorhi3"
9091   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9092         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9093                 (match_operand:HI 2 "general_operand" "")))
9094    (clobber (reg:CC FLAGS_REG))]
9095   "TARGET_HIMODE_MATH"
9096   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9097
9098 (define_insn "*xorhi_1"
9099   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9100         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9101                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9102    (clobber (reg:CC FLAGS_REG))]
9103   "ix86_binary_operator_ok (XOR, HImode, operands)"
9104   "xor{w}\t{%2, %0|%0, %2}"
9105   [(set_attr "type" "alu")
9106    (set_attr "mode" "HI")])
9107
9108 (define_insn "*xorhi_2"
9109   [(set (reg FLAGS_REG)
9110         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9111                          (match_operand:HI 2 "general_operand" "rim,ri"))
9112                  (const_int 0)))
9113    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9114         (xor:HI (match_dup 1) (match_dup 2)))]
9115   "ix86_match_ccmode (insn, CCNOmode)
9116    && ix86_binary_operator_ok (XOR, HImode, operands)"
9117   "xor{w}\t{%2, %0|%0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "mode" "HI")])
9120
9121 (define_insn "*xorhi_3"
9122   [(set (reg FLAGS_REG)
9123         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9124                          (match_operand:HI 2 "general_operand" "rim"))
9125                  (const_int 0)))
9126    (clobber (match_scratch:HI 0 "=r"))]
9127   "ix86_match_ccmode (insn, CCNOmode)
9128    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9129   "xor{w}\t{%2, %0|%0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "HI")])
9132
9133 (define_expand "xorqi3"
9134   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9135         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9136                 (match_operand:QI 2 "general_operand" "")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "TARGET_QIMODE_MATH"
9139   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9140
9141 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9142 (define_insn "*xorqi_1"
9143   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9144         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9145                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "ix86_binary_operator_ok (XOR, QImode, operands)"
9148   "@
9149    xor{b}\t{%2, %0|%0, %2}
9150    xor{b}\t{%2, %0|%0, %2}
9151    xor{l}\t{%k2, %k0|%k0, %k2}"
9152   [(set_attr "type" "alu")
9153    (set_attr "mode" "QI,QI,SI")])
9154
9155 (define_insn "*xorqi_1_slp"
9156   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9157         (xor:QI (match_dup 0)
9158                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9159    (clobber (reg:CC FLAGS_REG))]
9160   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9161    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9162   "xor{b}\t{%1, %0|%0, %1}"
9163   [(set_attr "type" "alu1")
9164    (set_attr "mode" "QI")])
9165
9166 (define_insn "xorqi_ext_0"
9167   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9168                          (const_int 8)
9169                          (const_int 8))
9170         (xor:SI 
9171           (zero_extract:SI
9172             (match_operand 1 "ext_register_operand" "0")
9173             (const_int 8)
9174             (const_int 8))
9175           (match_operand 2 "const_int_operand" "n")))
9176    (clobber (reg:CC FLAGS_REG))]
9177   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9178   "xor{b}\t{%2, %h0|%h0, %2}"
9179   [(set_attr "type" "alu")
9180    (set_attr "length_immediate" "1")
9181    (set_attr "mode" "QI")])
9182
9183 (define_insn "*xorqi_ext_1"
9184   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9185                          (const_int 8)
9186                          (const_int 8))
9187         (xor:SI 
9188           (zero_extract:SI
9189             (match_operand 1 "ext_register_operand" "0")
9190             (const_int 8)
9191             (const_int 8))
9192           (zero_extend:SI
9193             (match_operand:QI 2 "general_operand" "Qm"))))
9194    (clobber (reg:CC FLAGS_REG))]
9195   "!TARGET_64BIT
9196    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9197   "xor{b}\t{%2, %h0|%h0, %2}"
9198   [(set_attr "type" "alu")
9199    (set_attr "length_immediate" "0")
9200    (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_ext_1_rex64"
9203   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9204                          (const_int 8)
9205                          (const_int 8))
9206         (xor:SI 
9207           (zero_extract:SI
9208             (match_operand 1 "ext_register_operand" "0")
9209             (const_int 8)
9210             (const_int 8))
9211           (zero_extend:SI
9212             (match_operand 2 "ext_register_operand" "Q"))))
9213    (clobber (reg:CC FLAGS_REG))]
9214   "TARGET_64BIT
9215    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9216   "xor{b}\t{%2, %h0|%h0, %2}"
9217   [(set_attr "type" "alu")
9218    (set_attr "length_immediate" "0")
9219    (set_attr "mode" "QI")])
9220
9221 (define_insn "*xorqi_ext_2"
9222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9223                          (const_int 8)
9224                          (const_int 8))
9225         (xor:SI 
9226           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9227                            (const_int 8)
9228                            (const_int 8))
9229           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9230                            (const_int 8)
9231                            (const_int 8))))
9232    (clobber (reg:CC FLAGS_REG))]
9233   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9234   "xor{b}\t{%h2, %h0|%h0, %h2}"
9235   [(set_attr "type" "alu")
9236    (set_attr "length_immediate" "0")
9237    (set_attr "mode" "QI")])
9238
9239 (define_insn "*xorqi_cc_1"
9240   [(set (reg FLAGS_REG)
9241         (compare
9242           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9243                   (match_operand:QI 2 "general_operand" "qim,qi"))
9244           (const_int 0)))
9245    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9246         (xor:QI (match_dup 1) (match_dup 2)))]
9247   "ix86_match_ccmode (insn, CCNOmode)
9248    && ix86_binary_operator_ok (XOR, QImode, operands)"
9249   "xor{b}\t{%2, %0|%0, %2}"
9250   [(set_attr "type" "alu")
9251    (set_attr "mode" "QI")])
9252
9253 (define_insn "*xorqi_2_slp"
9254   [(set (reg FLAGS_REG)
9255         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9256                          (match_operand:QI 1 "general_operand" "qim,qi"))
9257                  (const_int 0)))
9258    (set (strict_low_part (match_dup 0))
9259         (xor:QI (match_dup 0) (match_dup 1)))]
9260   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9261    && ix86_match_ccmode (insn, CCNOmode)
9262    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9263   "xor{b}\t{%1, %0|%0, %1}"
9264   [(set_attr "type" "alu1")
9265    (set_attr "mode" "QI")])
9266
9267 (define_insn "*xorqi_cc_2"
9268   [(set (reg FLAGS_REG)
9269         (compare
9270           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9271                   (match_operand:QI 2 "general_operand" "qim"))
9272           (const_int 0)))
9273    (clobber (match_scratch:QI 0 "=q"))]
9274   "ix86_match_ccmode (insn, CCNOmode)
9275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9276   "xor{b}\t{%2, %0|%0, %2}"
9277   [(set_attr "type" "alu")
9278    (set_attr "mode" "QI")])
9279
9280 (define_insn "*xorqi_cc_ext_1"
9281   [(set (reg FLAGS_REG)
9282         (compare
9283           (xor:SI
9284             (zero_extract:SI
9285               (match_operand 1 "ext_register_operand" "0")
9286               (const_int 8)
9287               (const_int 8))
9288             (match_operand:QI 2 "general_operand" "qmn"))
9289           (const_int 0)))
9290    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9291                          (const_int 8)
9292                          (const_int 8))
9293         (xor:SI 
9294           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9295           (match_dup 2)))]
9296   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9297   "xor{b}\t{%2, %h0|%h0, %2}"
9298   [(set_attr "type" "alu")
9299    (set_attr "mode" "QI")])
9300
9301 (define_insn "*xorqi_cc_ext_1_rex64"
9302   [(set (reg FLAGS_REG)
9303         (compare
9304           (xor:SI
9305             (zero_extract:SI
9306               (match_operand 1 "ext_register_operand" "0")
9307               (const_int 8)
9308               (const_int 8))
9309             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9310           (const_int 0)))
9311    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9312                          (const_int 8)
9313                          (const_int 8))
9314         (xor:SI 
9315           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9316           (match_dup 2)))]
9317   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9318   "xor{b}\t{%2, %h0|%h0, %2}"
9319   [(set_attr "type" "alu")
9320    (set_attr "mode" "QI")])
9321
9322 (define_expand "xorqi_cc_ext_1"
9323   [(parallel [
9324      (set (reg:CCNO FLAGS_REG)
9325           (compare:CCNO
9326             (xor:SI
9327               (zero_extract:SI
9328                 (match_operand 1 "ext_register_operand" "")
9329                 (const_int 8)
9330                 (const_int 8))
9331               (match_operand:QI 2 "general_operand" ""))
9332             (const_int 0)))
9333      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9334                            (const_int 8)
9335                            (const_int 8))
9336           (xor:SI 
9337             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9338             (match_dup 2)))])]
9339   ""
9340   "")
9341
9342 (define_split
9343   [(set (match_operand 0 "register_operand" "")
9344         (xor (match_operand 1 "register_operand" "")
9345              (match_operand 2 "const_int_operand" "")))
9346    (clobber (reg:CC FLAGS_REG))]
9347    "reload_completed
9348     && QI_REG_P (operands[0])
9349     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9350     && !(INTVAL (operands[2]) & ~(255 << 8))
9351     && GET_MODE (operands[0]) != QImode"
9352   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9353                    (xor:SI (zero_extract:SI (match_dup 1)
9354                                             (const_int 8) (const_int 8))
9355                            (match_dup 2)))
9356               (clobber (reg:CC FLAGS_REG))])]
9357   "operands[0] = gen_lowpart (SImode, operands[0]);
9358    operands[1] = gen_lowpart (SImode, operands[1]);
9359    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9360
9361 ;; Since XOR can be encoded with sign extended immediate, this is only
9362 ;; profitable when 7th bit is set.
9363 (define_split
9364   [(set (match_operand 0 "register_operand" "")
9365         (xor (match_operand 1 "general_operand" "")
9366              (match_operand 2 "const_int_operand" "")))
9367    (clobber (reg:CC FLAGS_REG))]
9368    "reload_completed
9369     && ANY_QI_REG_P (operands[0])
9370     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9371     && !(INTVAL (operands[2]) & ~255)
9372     && (INTVAL (operands[2]) & 128)
9373     && GET_MODE (operands[0]) != QImode"
9374   [(parallel [(set (strict_low_part (match_dup 0))
9375                    (xor:QI (match_dup 1)
9376                            (match_dup 2)))
9377               (clobber (reg:CC FLAGS_REG))])]
9378   "operands[0] = gen_lowpart (QImode, operands[0]);
9379    operands[1] = gen_lowpart (QImode, operands[1]);
9380    operands[2] = gen_lowpart (QImode, operands[2]);")
9381 \f
9382 ;; Negation instructions
9383
9384 (define_expand "negdi2"
9385   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9386                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9387               (clobber (reg:CC FLAGS_REG))])]
9388   ""
9389   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9390
9391 (define_insn "*negdi2_1"
9392   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9393         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "!TARGET_64BIT
9396    && ix86_unary_operator_ok (NEG, DImode, operands)"
9397   "#")
9398
9399 (define_split
9400   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9401         (neg:DI (match_operand:DI 1 "general_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "!TARGET_64BIT && reload_completed"
9404   [(parallel
9405     [(set (reg:CCZ FLAGS_REG)
9406           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9407      (set (match_dup 0) (neg:SI (match_dup 2)))])
9408    (parallel
9409     [(set (match_dup 1)
9410           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9411                             (match_dup 3))
9412                    (const_int 0)))
9413      (clobber (reg:CC FLAGS_REG))])
9414    (parallel
9415     [(set (match_dup 1)
9416           (neg:SI (match_dup 1)))
9417      (clobber (reg:CC FLAGS_REG))])]
9418   "split_di (operands+1, 1, operands+2, operands+3);
9419    split_di (operands+0, 1, operands+0, operands+1);")
9420
9421 (define_insn "*negdi2_1_rex64"
9422   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9423         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9424    (clobber (reg:CC FLAGS_REG))]
9425   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9426   "neg{q}\t%0"
9427   [(set_attr "type" "negnot")
9428    (set_attr "mode" "DI")])
9429
9430 ;; The problem with neg is that it does not perform (compare x 0),
9431 ;; it really performs (compare 0 x), which leaves us with the zero
9432 ;; flag being the only useful item.
9433
9434 (define_insn "*negdi2_cmpz_rex64"
9435   [(set (reg:CCZ FLAGS_REG)
9436         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9437                      (const_int 0)))
9438    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9439         (neg:DI (match_dup 1)))]
9440   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9441   "neg{q}\t%0"
9442   [(set_attr "type" "negnot")
9443    (set_attr "mode" "DI")])
9444
9445
9446 (define_expand "negsi2"
9447   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9448                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9449               (clobber (reg:CC FLAGS_REG))])]
9450   ""
9451   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9452
9453 (define_insn "*negsi2_1"
9454   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9455         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9456    (clobber (reg:CC FLAGS_REG))]
9457   "ix86_unary_operator_ok (NEG, SImode, operands)"
9458   "neg{l}\t%0"
9459   [(set_attr "type" "negnot")
9460    (set_attr "mode" "SI")])
9461
9462 ;; Combine is quite creative about this pattern.
9463 (define_insn "*negsi2_1_zext"
9464   [(set (match_operand:DI 0 "register_operand" "=r")
9465         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9466                                         (const_int 32)))
9467                      (const_int 32)))
9468    (clobber (reg:CC FLAGS_REG))]
9469   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9470   "neg{l}\t%k0"
9471   [(set_attr "type" "negnot")
9472    (set_attr "mode" "SI")])
9473
9474 ;; The problem with neg is that it does not perform (compare x 0),
9475 ;; it really performs (compare 0 x), which leaves us with the zero
9476 ;; flag being the only useful item.
9477
9478 (define_insn "*negsi2_cmpz"
9479   [(set (reg:CCZ FLAGS_REG)
9480         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9481                      (const_int 0)))
9482    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9483         (neg:SI (match_dup 1)))]
9484   "ix86_unary_operator_ok (NEG, SImode, operands)"
9485   "neg{l}\t%0"
9486   [(set_attr "type" "negnot")
9487    (set_attr "mode" "SI")])
9488
9489 (define_insn "*negsi2_cmpz_zext"
9490   [(set (reg:CCZ FLAGS_REG)
9491         (compare:CCZ (lshiftrt:DI
9492                        (neg:DI (ashift:DI
9493                                  (match_operand:DI 1 "register_operand" "0")
9494                                  (const_int 32)))
9495                        (const_int 32))
9496                      (const_int 0)))
9497    (set (match_operand:DI 0 "register_operand" "=r")
9498         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9499                                         (const_int 32)))
9500                      (const_int 32)))]
9501   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9502   "neg{l}\t%k0"
9503   [(set_attr "type" "negnot")
9504    (set_attr "mode" "SI")])
9505
9506 (define_expand "neghi2"
9507   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9508                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9509               (clobber (reg:CC FLAGS_REG))])]
9510   "TARGET_HIMODE_MATH"
9511   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9512
9513 (define_insn "*neghi2_1"
9514   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9515         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9516    (clobber (reg:CC FLAGS_REG))]
9517   "ix86_unary_operator_ok (NEG, HImode, operands)"
9518   "neg{w}\t%0"
9519   [(set_attr "type" "negnot")
9520    (set_attr "mode" "HI")])
9521
9522 (define_insn "*neghi2_cmpz"
9523   [(set (reg:CCZ FLAGS_REG)
9524         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9525                      (const_int 0)))
9526    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9527         (neg:HI (match_dup 1)))]
9528   "ix86_unary_operator_ok (NEG, HImode, operands)"
9529   "neg{w}\t%0"
9530   [(set_attr "type" "negnot")
9531    (set_attr "mode" "HI")])
9532
9533 (define_expand "negqi2"
9534   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9535                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9536               (clobber (reg:CC FLAGS_REG))])]
9537   "TARGET_QIMODE_MATH"
9538   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9539
9540 (define_insn "*negqi2_1"
9541   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9542         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "ix86_unary_operator_ok (NEG, QImode, operands)"
9545   "neg{b}\t%0"
9546   [(set_attr "type" "negnot")
9547    (set_attr "mode" "QI")])
9548
9549 (define_insn "*negqi2_cmpz"
9550   [(set (reg:CCZ FLAGS_REG)
9551         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9552                      (const_int 0)))
9553    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9554         (neg:QI (match_dup 1)))]
9555   "ix86_unary_operator_ok (NEG, QImode, operands)"
9556   "neg{b}\t%0"
9557   [(set_attr "type" "negnot")
9558    (set_attr "mode" "QI")])
9559
9560 ;; Changing of sign for FP values is doable using integer unit too.
9561
9562 (define_expand "negsf2"
9563   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9564         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9565   "TARGET_80387 || TARGET_SSE_MATH"
9566   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9567
9568 (define_expand "abssf2"
9569   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9570         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9571   "TARGET_80387 || TARGET_SSE_MATH"
9572   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9573
9574 (define_insn "*absnegsf2_mixed"
9575   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9576         (match_operator:SF 3 "absneg_operator"
9577           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9578    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9579    (clobber (reg:CC FLAGS_REG))]
9580   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9581    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9582   "#")
9583
9584 (define_insn "*absnegsf2_sse"
9585   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9586         (match_operator:SF 3 "absneg_operator"
9587           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9588    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9589    (clobber (reg:CC FLAGS_REG))]
9590   "TARGET_SSE_MATH
9591    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9592   "#")
9593
9594 (define_insn "*absnegsf2_i387"
9595   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9596         (match_operator:SF 3 "absneg_operator"
9597           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9598    (use (match_operand 2 "" ""))
9599    (clobber (reg:CC FLAGS_REG))]
9600   "TARGET_80387 && !TARGET_SSE_MATH
9601    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9602   "#")
9603
9604 (define_expand "negdf2"
9605   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9606         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9607   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9608   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9609
9610 (define_expand "absdf2"
9611   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9612         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9613   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9614   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9615
9616 (define_insn "*absnegdf2_mixed"
9617   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9618         (match_operator:DF 3 "absneg_operator"
9619           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9620    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9621    (clobber (reg:CC FLAGS_REG))]
9622   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9623    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9624   "#")
9625
9626 (define_insn "*absnegdf2_sse"
9627   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9628         (match_operator:DF 3 "absneg_operator"
9629           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9630    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9631    (clobber (reg:CC FLAGS_REG))]
9632   "TARGET_SSE2 && TARGET_SSE_MATH
9633    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9634   "#")
9635
9636 (define_insn "*absnegdf2_i387"
9637   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9638         (match_operator:DF 3 "absneg_operator"
9639           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9640    (use (match_operand 2 "" ""))
9641    (clobber (reg:CC FLAGS_REG))]
9642   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9643    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9644   "#")
9645
9646 (define_expand "negxf2"
9647   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9648         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9649   "TARGET_80387"
9650   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9651
9652 (define_expand "absxf2"
9653   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9654         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9655   "TARGET_80387"
9656   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9657
9658 (define_insn "*absnegxf2_i387"
9659   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9660         (match_operator:XF 3 "absneg_operator"
9661           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9662    (use (match_operand 2 "" ""))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "TARGET_80387
9665    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9666   "#")
9667
9668 ;; Splitters for fp abs and neg.
9669
9670 (define_split
9671   [(set (match_operand 0 "fp_register_operand" "")
9672         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9673    (use (match_operand 2 "" ""))
9674    (clobber (reg:CC FLAGS_REG))]
9675   "reload_completed"
9676   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9677
9678 (define_split
9679   [(set (match_operand 0 "register_operand" "")
9680         (match_operator 3 "absneg_operator"
9681           [(match_operand 1 "register_operand" "")]))
9682    (use (match_operand 2 "nonimmediate_operand" ""))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "reload_completed && SSE_REG_P (operands[0])"
9685   [(set (match_dup 0) (match_dup 3))]
9686 {
9687   enum machine_mode mode = GET_MODE (operands[0]);
9688   enum machine_mode vmode = GET_MODE (operands[2]);
9689   rtx tmp;
9690   
9691   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9692   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9693   if (operands_match_p (operands[0], operands[2]))
9694     {
9695       tmp = operands[1];
9696       operands[1] = operands[2];
9697       operands[2] = tmp;
9698     }
9699   if (GET_CODE (operands[3]) == ABS)
9700     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9701   else
9702     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9703   operands[3] = tmp;
9704 })
9705
9706 (define_split
9707   [(set (match_operand:SF 0 "register_operand" "")
9708         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9709    (use (match_operand:V4SF 2 "" ""))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "reload_completed"
9712   [(parallel [(set (match_dup 0) (match_dup 1))
9713               (clobber (reg:CC FLAGS_REG))])]
9714
9715   rtx tmp;
9716   operands[0] = gen_lowpart (SImode, operands[0]);
9717   if (GET_CODE (operands[1]) == ABS)
9718     {
9719       tmp = gen_int_mode (0x7fffffff, SImode);
9720       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9721     }
9722   else
9723     {
9724       tmp = gen_int_mode (0x80000000, SImode);
9725       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9726     }
9727   operands[1] = tmp;
9728 })
9729
9730 (define_split
9731   [(set (match_operand:DF 0 "register_operand" "")
9732         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9733    (use (match_operand 2 "" ""))
9734    (clobber (reg:CC FLAGS_REG))]
9735   "reload_completed"
9736   [(parallel [(set (match_dup 0) (match_dup 1))
9737               (clobber (reg:CC FLAGS_REG))])]
9738 {
9739   rtx tmp;
9740   if (TARGET_64BIT)
9741     {
9742       tmp = gen_lowpart (DImode, operands[0]);
9743       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9744       operands[0] = tmp;
9745
9746       if (GET_CODE (operands[1]) == ABS)
9747         tmp = const0_rtx;
9748       else
9749         tmp = gen_rtx_NOT (DImode, tmp);
9750     }
9751   else
9752     {
9753       operands[0] = gen_highpart (SImode, operands[0]);
9754       if (GET_CODE (operands[1]) == ABS)
9755         {
9756           tmp = gen_int_mode (0x7fffffff, SImode);
9757           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9758         }
9759       else
9760         {
9761           tmp = gen_int_mode (0x80000000, SImode);
9762           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9763         }
9764     }
9765   operands[1] = tmp;
9766 })
9767
9768 (define_split
9769   [(set (match_operand:XF 0 "register_operand" "")
9770         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9771    (use (match_operand 2 "" ""))
9772    (clobber (reg:CC FLAGS_REG))]
9773   "reload_completed"
9774   [(parallel [(set (match_dup 0) (match_dup 1))
9775               (clobber (reg:CC FLAGS_REG))])]
9776 {
9777   rtx tmp;
9778   operands[0] = gen_rtx_REG (SImode,
9779                              true_regnum (operands[0])
9780                              + (TARGET_64BIT ? 1 : 2));
9781   if (GET_CODE (operands[1]) == ABS)
9782     {
9783       tmp = GEN_INT (0x7fff);
9784       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9785     }
9786   else
9787     {
9788       tmp = GEN_INT (0x8000);
9789       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9790     }
9791   operands[1] = tmp;
9792 })
9793
9794 (define_split
9795   [(set (match_operand 0 "memory_operand" "")
9796         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9797    (use (match_operand 2 "" ""))
9798    (clobber (reg:CC FLAGS_REG))]
9799   "reload_completed"
9800   [(parallel [(set (match_dup 0) (match_dup 1))
9801               (clobber (reg:CC FLAGS_REG))])]
9802 {
9803   enum machine_mode mode = GET_MODE (operands[0]);
9804   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9805   rtx tmp;
9806
9807   operands[0] = adjust_address (operands[0], QImode, size - 1);
9808   if (GET_CODE (operands[1]) == ABS)
9809     {
9810       tmp = gen_int_mode (0x7f, QImode);
9811       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9812     }
9813   else
9814     {
9815       tmp = gen_int_mode (0x80, QImode);
9816       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9817     }
9818   operands[1] = tmp;
9819 })
9820
9821 ;; Conditionalize these after reload. If they match before reload, we 
9822 ;; lose the clobber and ability to use integer instructions.
9823
9824 (define_insn "*negsf2_1"
9825   [(set (match_operand:SF 0 "register_operand" "=f")
9826         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9827   "TARGET_80387 && reload_completed"
9828   "fchs"
9829   [(set_attr "type" "fsgn")
9830    (set_attr "mode" "SF")])
9831
9832 (define_insn "*negdf2_1"
9833   [(set (match_operand:DF 0 "register_operand" "=f")
9834         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9835   "TARGET_80387 && reload_completed"
9836   "fchs"
9837   [(set_attr "type" "fsgn")
9838    (set_attr "mode" "DF")])
9839
9840 (define_insn "*negxf2_1"
9841   [(set (match_operand:XF 0 "register_operand" "=f")
9842         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9843   "TARGET_80387 && reload_completed"
9844   "fchs"
9845   [(set_attr "type" "fsgn")
9846    (set_attr "mode" "XF")])
9847
9848 (define_insn "*abssf2_1"
9849   [(set (match_operand:SF 0 "register_operand" "=f")
9850         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9851   "TARGET_80387 && reload_completed"
9852   "fabs"
9853   [(set_attr "type" "fsgn")
9854    (set_attr "mode" "SF")])
9855
9856 (define_insn "*absdf2_1"
9857   [(set (match_operand:DF 0 "register_operand" "=f")
9858         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9859   "TARGET_80387 && reload_completed"
9860   "fabs"
9861   [(set_attr "type" "fsgn")
9862    (set_attr "mode" "DF")])
9863
9864 (define_insn "*absxf2_1"
9865   [(set (match_operand:XF 0 "register_operand" "=f")
9866         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9867   "TARGET_80387 && reload_completed"
9868   "fabs"
9869   [(set_attr "type" "fsgn")
9870    (set_attr "mode" "DF")])
9871
9872 (define_insn "*negextendsfdf2"
9873   [(set (match_operand:DF 0 "register_operand" "=f")
9874         (neg:DF (float_extend:DF
9875                   (match_operand:SF 1 "register_operand" "0"))))]
9876   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9877   "fchs"
9878   [(set_attr "type" "fsgn")
9879    (set_attr "mode" "DF")])
9880
9881 (define_insn "*negextenddfxf2"
9882   [(set (match_operand:XF 0 "register_operand" "=f")
9883         (neg:XF (float_extend:XF
9884                   (match_operand:DF 1 "register_operand" "0"))))]
9885   "TARGET_80387"
9886   "fchs"
9887   [(set_attr "type" "fsgn")
9888    (set_attr "mode" "XF")])
9889
9890 (define_insn "*negextendsfxf2"
9891   [(set (match_operand:XF 0 "register_operand" "=f")
9892         (neg:XF (float_extend:XF
9893                   (match_operand:SF 1 "register_operand" "0"))))]
9894   "TARGET_80387"
9895   "fchs"
9896   [(set_attr "type" "fsgn")
9897    (set_attr "mode" "XF")])
9898
9899 (define_insn "*absextendsfdf2"
9900   [(set (match_operand:DF 0 "register_operand" "=f")
9901         (abs:DF (float_extend:DF
9902                   (match_operand:SF 1 "register_operand" "0"))))]
9903   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9904   "fabs"
9905   [(set_attr "type" "fsgn")
9906    (set_attr "mode" "DF")])
9907
9908 (define_insn "*absextenddfxf2"
9909   [(set (match_operand:XF 0 "register_operand" "=f")
9910         (abs:XF (float_extend:XF
9911           (match_operand:DF 1 "register_operand" "0"))))]
9912   "TARGET_80387"
9913   "fabs"
9914   [(set_attr "type" "fsgn")
9915    (set_attr "mode" "XF")])
9916
9917 (define_insn "*absextendsfxf2"
9918   [(set (match_operand:XF 0 "register_operand" "=f")
9919         (abs:XF (float_extend:XF
9920           (match_operand:SF 1 "register_operand" "0"))))]
9921   "TARGET_80387"
9922   "fabs"
9923   [(set_attr "type" "fsgn")
9924    (set_attr "mode" "XF")])
9925 \f
9926 ;; One complement instructions
9927
9928 (define_expand "one_cmpldi2"
9929   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9930         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9931   "TARGET_64BIT"
9932   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9933
9934 (define_insn "*one_cmpldi2_1_rex64"
9935   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9936         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9937   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9938   "not{q}\t%0"
9939   [(set_attr "type" "negnot")
9940    (set_attr "mode" "DI")])
9941
9942 (define_insn "*one_cmpldi2_2_rex64"
9943   [(set (reg FLAGS_REG)
9944         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9945                  (const_int 0)))
9946    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9947         (not:DI (match_dup 1)))]
9948   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9949    && ix86_unary_operator_ok (NOT, DImode, operands)"
9950   "#"
9951   [(set_attr "type" "alu1")
9952    (set_attr "mode" "DI")])
9953
9954 (define_split
9955   [(set (match_operand 0 "flags_reg_operand" "")
9956         (match_operator 2 "compare_operator"
9957           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9958            (const_int 0)]))
9959    (set (match_operand:DI 1 "nonimmediate_operand" "")
9960         (not:DI (match_dup 3)))]
9961   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9962   [(parallel [(set (match_dup 0)
9963                    (match_op_dup 2
9964                      [(xor:DI (match_dup 3) (const_int -1))
9965                       (const_int 0)]))
9966               (set (match_dup 1)
9967                    (xor:DI (match_dup 3) (const_int -1)))])]
9968   "")
9969
9970 (define_expand "one_cmplsi2"
9971   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9972         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9973   ""
9974   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9975
9976 (define_insn "*one_cmplsi2_1"
9977   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9978         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9979   "ix86_unary_operator_ok (NOT, SImode, operands)"
9980   "not{l}\t%0"
9981   [(set_attr "type" "negnot")
9982    (set_attr "mode" "SI")])
9983
9984 ;; ??? Currently never generated - xor is used instead.
9985 (define_insn "*one_cmplsi2_1_zext"
9986   [(set (match_operand:DI 0 "register_operand" "=r")
9987         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9988   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9989   "not{l}\t%k0"
9990   [(set_attr "type" "negnot")
9991    (set_attr "mode" "SI")])
9992
9993 (define_insn "*one_cmplsi2_2"
9994   [(set (reg FLAGS_REG)
9995         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9996                  (const_int 0)))
9997    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9998         (not:SI (match_dup 1)))]
9999   "ix86_match_ccmode (insn, CCNOmode)
10000    && ix86_unary_operator_ok (NOT, SImode, operands)"
10001   "#"
10002   [(set_attr "type" "alu1")
10003    (set_attr "mode" "SI")])
10004
10005 (define_split
10006   [(set (match_operand 0 "flags_reg_operand" "")
10007         (match_operator 2 "compare_operator"
10008           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10009            (const_int 0)]))
10010    (set (match_operand:SI 1 "nonimmediate_operand" "")
10011         (not:SI (match_dup 3)))]
10012   "ix86_match_ccmode (insn, CCNOmode)"
10013   [(parallel [(set (match_dup 0)
10014                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10015                                     (const_int 0)]))
10016               (set (match_dup 1)
10017                    (xor:SI (match_dup 3) (const_int -1)))])]
10018   "")
10019
10020 ;; ??? Currently never generated - xor is used instead.
10021 (define_insn "*one_cmplsi2_2_zext"
10022   [(set (reg FLAGS_REG)
10023         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10024                  (const_int 0)))
10025    (set (match_operand:DI 0 "register_operand" "=r")
10026         (zero_extend:DI (not:SI (match_dup 1))))]
10027   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10028    && ix86_unary_operator_ok (NOT, SImode, operands)"
10029   "#"
10030   [(set_attr "type" "alu1")
10031    (set_attr "mode" "SI")])
10032
10033 (define_split
10034   [(set (match_operand 0 "flags_reg_operand" "")
10035         (match_operator 2 "compare_operator"
10036           [(not:SI (match_operand:SI 3 "register_operand" ""))
10037            (const_int 0)]))
10038    (set (match_operand:DI 1 "register_operand" "")
10039         (zero_extend:DI (not:SI (match_dup 3))))]
10040   "ix86_match_ccmode (insn, CCNOmode)"
10041   [(parallel [(set (match_dup 0)
10042                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10043                                     (const_int 0)]))
10044               (set (match_dup 1)
10045                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10046   "")
10047
10048 (define_expand "one_cmplhi2"
10049   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10050         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10051   "TARGET_HIMODE_MATH"
10052   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10053
10054 (define_insn "*one_cmplhi2_1"
10055   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10056         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10057   "ix86_unary_operator_ok (NOT, HImode, operands)"
10058   "not{w}\t%0"
10059   [(set_attr "type" "negnot")
10060    (set_attr "mode" "HI")])
10061
10062 (define_insn "*one_cmplhi2_2"
10063   [(set (reg FLAGS_REG)
10064         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10065                  (const_int 0)))
10066    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10067         (not:HI (match_dup 1)))]
10068   "ix86_match_ccmode (insn, CCNOmode)
10069    && ix86_unary_operator_ok (NEG, HImode, operands)"
10070   "#"
10071   [(set_attr "type" "alu1")
10072    (set_attr "mode" "HI")])
10073
10074 (define_split
10075   [(set (match_operand 0 "flags_reg_operand" "")
10076         (match_operator 2 "compare_operator"
10077           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10078            (const_int 0)]))
10079    (set (match_operand:HI 1 "nonimmediate_operand" "")
10080         (not:HI (match_dup 3)))]
10081   "ix86_match_ccmode (insn, CCNOmode)"
10082   [(parallel [(set (match_dup 0)
10083                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10084                                     (const_int 0)]))
10085               (set (match_dup 1)
10086                    (xor:HI (match_dup 3) (const_int -1)))])]
10087   "")
10088
10089 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10090 (define_expand "one_cmplqi2"
10091   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10092         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10093   "TARGET_QIMODE_MATH"
10094   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10095
10096 (define_insn "*one_cmplqi2_1"
10097   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10098         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10099   "ix86_unary_operator_ok (NOT, QImode, operands)"
10100   "@
10101    not{b}\t%0
10102    not{l}\t%k0"
10103   [(set_attr "type" "negnot")
10104    (set_attr "mode" "QI,SI")])
10105
10106 (define_insn "*one_cmplqi2_2"
10107   [(set (reg FLAGS_REG)
10108         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10109                  (const_int 0)))
10110    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10111         (not:QI (match_dup 1)))]
10112   "ix86_match_ccmode (insn, CCNOmode)
10113    && ix86_unary_operator_ok (NOT, QImode, operands)"
10114   "#"
10115   [(set_attr "type" "alu1")
10116    (set_attr "mode" "QI")])
10117
10118 (define_split
10119   [(set (match_operand 0 "flags_reg_operand" "")
10120         (match_operator 2 "compare_operator"
10121           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10122            (const_int 0)]))
10123    (set (match_operand:QI 1 "nonimmediate_operand" "")
10124         (not:QI (match_dup 3)))]
10125   "ix86_match_ccmode (insn, CCNOmode)"
10126   [(parallel [(set (match_dup 0)
10127                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10128                                     (const_int 0)]))
10129               (set (match_dup 1)
10130                    (xor:QI (match_dup 3) (const_int -1)))])]
10131   "")
10132 \f
10133 ;; Arithmetic shift instructions
10134
10135 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10136 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10137 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10138 ;; from the assembler input.
10139 ;;
10140 ;; This instruction shifts the target reg/mem as usual, but instead of
10141 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10142 ;; is a left shift double, bits are taken from the high order bits of
10143 ;; reg, else if the insn is a shift right double, bits are taken from the
10144 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10145 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10146 ;;
10147 ;; Since sh[lr]d does not change the `reg' operand, that is done
10148 ;; separately, making all shifts emit pairs of shift double and normal
10149 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10150 ;; support a 63 bit shift, each shift where the count is in a reg expands
10151 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10152 ;;
10153 ;; If the shift count is a constant, we need never emit more than one
10154 ;; shift pair, instead using moves and sign extension for counts greater
10155 ;; than 31.
10156
10157 (define_expand "ashldi3"
10158   [(set (match_operand:DI 0 "shiftdi_operand" "")
10159         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10160                    (match_operand:QI 2 "nonmemory_operand" "")))]
10161   ""
10162   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10163
10164 (define_insn "*ashldi3_1_rex64"
10165   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10166         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10167                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10168    (clobber (reg:CC FLAGS_REG))]
10169   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10170 {
10171   switch (get_attr_type (insn))
10172     {
10173     case TYPE_ALU:
10174       if (operands[2] != const1_rtx)
10175         abort ();
10176       if (!rtx_equal_p (operands[0], operands[1]))
10177         abort ();
10178       return "add{q}\t{%0, %0|%0, %0}";
10179
10180     case TYPE_LEA:
10181       if (GET_CODE (operands[2]) != CONST_INT
10182           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10183         abort ();
10184       operands[1] = gen_rtx_MULT (DImode, operands[1],
10185                                   GEN_INT (1 << INTVAL (operands[2])));
10186       return "lea{q}\t{%a1, %0|%0, %a1}";
10187
10188     default:
10189       if (REG_P (operands[2]))
10190         return "sal{q}\t{%b2, %0|%0, %b2}";
10191       else if (operands[2] == const1_rtx
10192                && (TARGET_SHIFT1 || optimize_size))
10193         return "sal{q}\t%0";
10194       else
10195         return "sal{q}\t{%2, %0|%0, %2}";
10196     }
10197 }
10198   [(set (attr "type")
10199      (cond [(eq_attr "alternative" "1")
10200               (const_string "lea")
10201             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10202                           (const_int 0))
10203                       (match_operand 0 "register_operand" ""))
10204                  (match_operand 2 "const1_operand" ""))
10205               (const_string "alu")
10206            ]
10207            (const_string "ishift")))
10208    (set_attr "mode" "DI")])
10209
10210 ;; Convert lea to the lea pattern to avoid flags dependency.
10211 (define_split
10212   [(set (match_operand:DI 0 "register_operand" "")
10213         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10214                    (match_operand:QI 2 "immediate_operand" "")))
10215    (clobber (reg:CC FLAGS_REG))]
10216   "TARGET_64BIT && reload_completed
10217    && true_regnum (operands[0]) != true_regnum (operands[1])"
10218   [(set (match_dup 0)
10219         (mult:DI (match_dup 1)
10220                  (match_dup 2)))]
10221   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10222
10223 ;; This pattern can't accept a variable shift count, since shifts by
10224 ;; zero don't affect the flags.  We assume that shifts by constant
10225 ;; zero are optimized away.
10226 (define_insn "*ashldi3_cmp_rex64"
10227   [(set (reg FLAGS_REG)
10228         (compare
10229           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10230                      (match_operand:QI 2 "immediate_operand" "e"))
10231           (const_int 0)))
10232    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10233         (ashift:DI (match_dup 1) (match_dup 2)))]
10234   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10235    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10236 {
10237   switch (get_attr_type (insn))
10238     {
10239     case TYPE_ALU:
10240       if (operands[2] != const1_rtx)
10241         abort ();
10242       return "add{q}\t{%0, %0|%0, %0}";
10243
10244     default:
10245       if (REG_P (operands[2]))
10246         return "sal{q}\t{%b2, %0|%0, %b2}";
10247       else if (operands[2] == const1_rtx
10248                && (TARGET_SHIFT1 || optimize_size))
10249         return "sal{q}\t%0";
10250       else
10251         return "sal{q}\t{%2, %0|%0, %2}";
10252     }
10253 }
10254   [(set (attr "type")
10255      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10256                           (const_int 0))
10257                       (match_operand 0 "register_operand" ""))
10258                  (match_operand 2 "const1_operand" ""))
10259               (const_string "alu")
10260            ]
10261            (const_string "ishift")))
10262    (set_attr "mode" "DI")])
10263
10264 (define_insn "*ashldi3_1"
10265   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10266         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10267                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "!TARGET_64BIT"
10270   "#"
10271   [(set_attr "type" "multi")])
10272
10273 ;; By default we don't ask for a scratch register, because when DImode
10274 ;; values are manipulated, registers are already at a premium.  But if
10275 ;; we have one handy, we won't turn it away.
10276 (define_peephole2
10277   [(match_scratch:SI 3 "r")
10278    (parallel [(set (match_operand:DI 0 "register_operand" "")
10279                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10280                               (match_operand:QI 2 "nonmemory_operand" "")))
10281               (clobber (reg:CC FLAGS_REG))])
10282    (match_dup 3)]
10283   "!TARGET_64BIT && TARGET_CMOVE"
10284   [(const_int 0)]
10285   "ix86_split_ashldi (operands, operands[3]); DONE;")
10286
10287 (define_split
10288   [(set (match_operand:DI 0 "register_operand" "")
10289         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10290                    (match_operand:QI 2 "nonmemory_operand" "")))
10291    (clobber (reg:CC FLAGS_REG))]
10292   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10293   [(const_int 0)]
10294   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10295
10296 (define_insn "x86_shld_1"
10297   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10298         (ior:SI (ashift:SI (match_dup 0)
10299                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10300                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10301                   (minus:QI (const_int 32) (match_dup 2)))))
10302    (clobber (reg:CC FLAGS_REG))]
10303   ""
10304   "@
10305    shld{l}\t{%2, %1, %0|%0, %1, %2}
10306    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10307   [(set_attr "type" "ishift")
10308    (set_attr "prefix_0f" "1")
10309    (set_attr "mode" "SI")
10310    (set_attr "pent_pair" "np")
10311    (set_attr "athlon_decode" "vector")])
10312
10313 (define_expand "x86_shift_adj_1"
10314   [(set (reg:CCZ FLAGS_REG)
10315         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10316                              (const_int 32))
10317                      (const_int 0)))
10318    (set (match_operand:SI 0 "register_operand" "")
10319         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10320                          (match_operand:SI 1 "register_operand" "")
10321                          (match_dup 0)))
10322    (set (match_dup 1)
10323         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10324                          (match_operand:SI 3 "register_operand" "r")
10325                          (match_dup 1)))]
10326   "TARGET_CMOVE"
10327   "")
10328
10329 (define_expand "x86_shift_adj_2"
10330   [(use (match_operand:SI 0 "register_operand" ""))
10331    (use (match_operand:SI 1 "register_operand" ""))
10332    (use (match_operand:QI 2 "register_operand" ""))]
10333   ""
10334 {
10335   rtx label = gen_label_rtx ();
10336   rtx tmp;
10337
10338   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10339
10340   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10341   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10342   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10343                               gen_rtx_LABEL_REF (VOIDmode, label),
10344                               pc_rtx);
10345   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10346   JUMP_LABEL (tmp) = label;
10347
10348   emit_move_insn (operands[0], operands[1]);
10349   ix86_expand_clear (operands[1]);
10350
10351   emit_label (label);
10352   LABEL_NUSES (label) = 1;
10353
10354   DONE;
10355 })
10356
10357 (define_expand "ashlsi3"
10358   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10359         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10360                    (match_operand:QI 2 "nonmemory_operand" "")))
10361    (clobber (reg:CC FLAGS_REG))]
10362   ""
10363   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10364
10365 (define_insn "*ashlsi3_1"
10366   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10367         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10368                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10369    (clobber (reg:CC FLAGS_REG))]
10370   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10371 {
10372   switch (get_attr_type (insn))
10373     {
10374     case TYPE_ALU:
10375       if (operands[2] != const1_rtx)
10376         abort ();
10377       if (!rtx_equal_p (operands[0], operands[1]))
10378         abort ();
10379       return "add{l}\t{%0, %0|%0, %0}";
10380
10381     case TYPE_LEA:
10382       return "#";
10383
10384     default:
10385       if (REG_P (operands[2]))
10386         return "sal{l}\t{%b2, %0|%0, %b2}";
10387       else if (operands[2] == const1_rtx
10388                && (TARGET_SHIFT1 || optimize_size))
10389         return "sal{l}\t%0";
10390       else
10391         return "sal{l}\t{%2, %0|%0, %2}";
10392     }
10393 }
10394   [(set (attr "type")
10395      (cond [(eq_attr "alternative" "1")
10396               (const_string "lea")
10397             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10398                           (const_int 0))
10399                       (match_operand 0 "register_operand" ""))
10400                  (match_operand 2 "const1_operand" ""))
10401               (const_string "alu")
10402            ]
10403            (const_string "ishift")))
10404    (set_attr "mode" "SI")])
10405
10406 ;; Convert lea to the lea pattern to avoid flags dependency.
10407 (define_split
10408   [(set (match_operand 0 "register_operand" "")
10409         (ashift (match_operand 1 "index_register_operand" "")
10410                 (match_operand:QI 2 "const_int_operand" "")))
10411    (clobber (reg:CC FLAGS_REG))]
10412   "reload_completed
10413    && true_regnum (operands[0]) != true_regnum (operands[1])
10414    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10415   [(const_int 0)]
10416 {
10417   rtx pat;
10418   enum machine_mode mode = GET_MODE (operands[0]);
10419
10420   if (GET_MODE_SIZE (mode) < 4)
10421     operands[0] = gen_lowpart (SImode, operands[0]);
10422   if (mode != Pmode)
10423     operands[1] = gen_lowpart (Pmode, operands[1]);
10424   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10425
10426   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10427   if (Pmode != SImode)
10428     pat = gen_rtx_SUBREG (SImode, pat, 0);
10429   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10430   DONE;
10431 })
10432
10433 ;; Rare case of shifting RSP is handled by generating move and shift
10434 (define_split
10435   [(set (match_operand 0 "register_operand" "")
10436         (ashift (match_operand 1 "register_operand" "")
10437                 (match_operand:QI 2 "const_int_operand" "")))
10438    (clobber (reg:CC FLAGS_REG))]
10439   "reload_completed
10440    && true_regnum (operands[0]) != true_regnum (operands[1])"
10441   [(const_int 0)]
10442 {
10443   rtx pat, clob;
10444   emit_move_insn (operands[1], operands[0]);
10445   pat = gen_rtx_SET (VOIDmode, operands[0],
10446                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10447                                      operands[0], operands[2]));
10448   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10449   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10450   DONE;
10451 })
10452
10453 (define_insn "*ashlsi3_1_zext"
10454   [(set (match_operand:DI 0 "register_operand" "=r,r")
10455         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10456                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10457    (clobber (reg:CC FLAGS_REG))]
10458   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10459 {
10460   switch (get_attr_type (insn))
10461     {
10462     case TYPE_ALU:
10463       if (operands[2] != const1_rtx)
10464         abort ();
10465       return "add{l}\t{%k0, %k0|%k0, %k0}";
10466
10467     case TYPE_LEA:
10468       return "#";
10469
10470     default:
10471       if (REG_P (operands[2]))
10472         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10473       else if (operands[2] == const1_rtx
10474                && (TARGET_SHIFT1 || optimize_size))
10475         return "sal{l}\t%k0";
10476       else
10477         return "sal{l}\t{%2, %k0|%k0, %2}";
10478     }
10479 }
10480   [(set (attr "type")
10481      (cond [(eq_attr "alternative" "1")
10482               (const_string "lea")
10483             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10484                      (const_int 0))
10485                  (match_operand 2 "const1_operand" ""))
10486               (const_string "alu")
10487            ]
10488            (const_string "ishift")))
10489    (set_attr "mode" "SI")])
10490
10491 ;; Convert lea to the lea pattern to avoid flags dependency.
10492 (define_split
10493   [(set (match_operand:DI 0 "register_operand" "")
10494         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10495                                 (match_operand:QI 2 "const_int_operand" ""))))
10496    (clobber (reg:CC FLAGS_REG))]
10497   "TARGET_64BIT && reload_completed
10498    && true_regnum (operands[0]) != true_regnum (operands[1])"
10499   [(set (match_dup 0) (zero_extend:DI
10500                         (subreg:SI (mult:SI (match_dup 1)
10501                                             (match_dup 2)) 0)))]
10502 {
10503   operands[1] = gen_lowpart (Pmode, operands[1]);
10504   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10505 })
10506
10507 ;; This pattern can't accept a variable shift count, since shifts by
10508 ;; zero don't affect the flags.  We assume that shifts by constant
10509 ;; zero are optimized away.
10510 (define_insn "*ashlsi3_cmp"
10511   [(set (reg FLAGS_REG)
10512         (compare
10513           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10514                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10515           (const_int 0)))
10516    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10517         (ashift:SI (match_dup 1) (match_dup 2)))]
10518   "ix86_match_ccmode (insn, CCGOCmode)
10519    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10520 {
10521   switch (get_attr_type (insn))
10522     {
10523     case TYPE_ALU:
10524       if (operands[2] != const1_rtx)
10525         abort ();
10526       return "add{l}\t{%0, %0|%0, %0}";
10527
10528     default:
10529       if (REG_P (operands[2]))
10530         return "sal{l}\t{%b2, %0|%0, %b2}";
10531       else if (operands[2] == const1_rtx
10532                && (TARGET_SHIFT1 || optimize_size))
10533         return "sal{l}\t%0";
10534       else
10535         return "sal{l}\t{%2, %0|%0, %2}";
10536     }
10537 }
10538   [(set (attr "type")
10539      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10540                           (const_int 0))
10541                       (match_operand 0 "register_operand" ""))
10542                  (match_operand 2 "const1_operand" ""))
10543               (const_string "alu")
10544            ]
10545            (const_string "ishift")))
10546    (set_attr "mode" "SI")])
10547
10548 (define_insn "*ashlsi3_cmp_zext"
10549   [(set (reg FLAGS_REG)
10550         (compare
10551           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10552                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10553           (const_int 0)))
10554    (set (match_operand:DI 0 "register_operand" "=r")
10555         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10556   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10557    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10558 {
10559   switch (get_attr_type (insn))
10560     {
10561     case TYPE_ALU:
10562       if (operands[2] != const1_rtx)
10563         abort ();
10564       return "add{l}\t{%k0, %k0|%k0, %k0}";
10565
10566     default:
10567       if (REG_P (operands[2]))
10568         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10569       else if (operands[2] == const1_rtx
10570                && (TARGET_SHIFT1 || optimize_size))
10571         return "sal{l}\t%k0";
10572       else
10573         return "sal{l}\t{%2, %k0|%k0, %2}";
10574     }
10575 }
10576   [(set (attr "type")
10577      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10578                      (const_int 0))
10579                  (match_operand 2 "const1_operand" ""))
10580               (const_string "alu")
10581            ]
10582            (const_string "ishift")))
10583    (set_attr "mode" "SI")])
10584
10585 (define_expand "ashlhi3"
10586   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10587         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10588                    (match_operand:QI 2 "nonmemory_operand" "")))
10589    (clobber (reg:CC FLAGS_REG))]
10590   "TARGET_HIMODE_MATH"
10591   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10592
10593 (define_insn "*ashlhi3_1_lea"
10594   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10595         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10596                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10597    (clobber (reg:CC FLAGS_REG))]
10598   "!TARGET_PARTIAL_REG_STALL
10599    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10600 {
10601   switch (get_attr_type (insn))
10602     {
10603     case TYPE_LEA:
10604       return "#";
10605     case TYPE_ALU:
10606       if (operands[2] != const1_rtx)
10607         abort ();
10608       return "add{w}\t{%0, %0|%0, %0}";
10609
10610     default:
10611       if (REG_P (operands[2]))
10612         return "sal{w}\t{%b2, %0|%0, %b2}";
10613       else if (operands[2] == const1_rtx
10614                && (TARGET_SHIFT1 || optimize_size))
10615         return "sal{w}\t%0";
10616       else
10617         return "sal{w}\t{%2, %0|%0, %2}";
10618     }
10619 }
10620   [(set (attr "type")
10621      (cond [(eq_attr "alternative" "1")
10622               (const_string "lea")
10623             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10624                           (const_int 0))
10625                       (match_operand 0 "register_operand" ""))
10626                  (match_operand 2 "const1_operand" ""))
10627               (const_string "alu")
10628            ]
10629            (const_string "ishift")))
10630    (set_attr "mode" "HI,SI")])
10631
10632 (define_insn "*ashlhi3_1"
10633   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10634         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10635                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10636    (clobber (reg:CC FLAGS_REG))]
10637   "TARGET_PARTIAL_REG_STALL
10638    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10639 {
10640   switch (get_attr_type (insn))
10641     {
10642     case TYPE_ALU:
10643       if (operands[2] != const1_rtx)
10644         abort ();
10645       return "add{w}\t{%0, %0|%0, %0}";
10646
10647     default:
10648       if (REG_P (operands[2]))
10649         return "sal{w}\t{%b2, %0|%0, %b2}";
10650       else if (operands[2] == const1_rtx
10651                && (TARGET_SHIFT1 || optimize_size))
10652         return "sal{w}\t%0";
10653       else
10654         return "sal{w}\t{%2, %0|%0, %2}";
10655     }
10656 }
10657   [(set (attr "type")
10658      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10659                           (const_int 0))
10660                       (match_operand 0 "register_operand" ""))
10661                  (match_operand 2 "const1_operand" ""))
10662               (const_string "alu")
10663            ]
10664            (const_string "ishift")))
10665    (set_attr "mode" "HI")])
10666
10667 ;; This pattern can't accept a variable shift count, since shifts by
10668 ;; zero don't affect the flags.  We assume that shifts by constant
10669 ;; zero are optimized away.
10670 (define_insn "*ashlhi3_cmp"
10671   [(set (reg FLAGS_REG)
10672         (compare
10673           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10674                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10675           (const_int 0)))
10676    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10677         (ashift:HI (match_dup 1) (match_dup 2)))]
10678   "ix86_match_ccmode (insn, CCGOCmode)
10679    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10680 {
10681   switch (get_attr_type (insn))
10682     {
10683     case TYPE_ALU:
10684       if (operands[2] != const1_rtx)
10685         abort ();
10686       return "add{w}\t{%0, %0|%0, %0}";
10687
10688     default:
10689       if (REG_P (operands[2]))
10690         return "sal{w}\t{%b2, %0|%0, %b2}";
10691       else if (operands[2] == const1_rtx
10692                && (TARGET_SHIFT1 || optimize_size))
10693         return "sal{w}\t%0";
10694       else
10695         return "sal{w}\t{%2, %0|%0, %2}";
10696     }
10697 }
10698   [(set (attr "type")
10699      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10700                           (const_int 0))
10701                       (match_operand 0 "register_operand" ""))
10702                  (match_operand 2 "const1_operand" ""))
10703               (const_string "alu")
10704            ]
10705            (const_string "ishift")))
10706    (set_attr "mode" "HI")])
10707
10708 (define_expand "ashlqi3"
10709   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10710         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10711                    (match_operand:QI 2 "nonmemory_operand" "")))
10712    (clobber (reg:CC FLAGS_REG))]
10713   "TARGET_QIMODE_MATH"
10714   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10715
10716 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10717
10718 (define_insn "*ashlqi3_1_lea"
10719   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10720         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10721                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10722    (clobber (reg:CC FLAGS_REG))]
10723   "!TARGET_PARTIAL_REG_STALL
10724    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10725 {
10726   switch (get_attr_type (insn))
10727     {
10728     case TYPE_LEA:
10729       return "#";
10730     case TYPE_ALU:
10731       if (operands[2] != const1_rtx)
10732         abort ();
10733       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10734         return "add{l}\t{%k0, %k0|%k0, %k0}";
10735       else
10736         return "add{b}\t{%0, %0|%0, %0}";
10737
10738     default:
10739       if (REG_P (operands[2]))
10740         {
10741           if (get_attr_mode (insn) == MODE_SI)
10742             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10743           else
10744             return "sal{b}\t{%b2, %0|%0, %b2}";
10745         }
10746       else if (operands[2] == const1_rtx
10747                && (TARGET_SHIFT1 || optimize_size))
10748         {
10749           if (get_attr_mode (insn) == MODE_SI)
10750             return "sal{l}\t%0";
10751           else
10752             return "sal{b}\t%0";
10753         }
10754       else
10755         {
10756           if (get_attr_mode (insn) == MODE_SI)
10757             return "sal{l}\t{%2, %k0|%k0, %2}";
10758           else
10759             return "sal{b}\t{%2, %0|%0, %2}";
10760         }
10761     }
10762 }
10763   [(set (attr "type")
10764      (cond [(eq_attr "alternative" "2")
10765               (const_string "lea")
10766             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10767                           (const_int 0))
10768                       (match_operand 0 "register_operand" ""))
10769                  (match_operand 2 "const1_operand" ""))
10770               (const_string "alu")
10771            ]
10772            (const_string "ishift")))
10773    (set_attr "mode" "QI,SI,SI")])
10774
10775 (define_insn "*ashlqi3_1"
10776   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10777         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10778                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10779    (clobber (reg:CC FLAGS_REG))]
10780   "TARGET_PARTIAL_REG_STALL
10781    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10782 {
10783   switch (get_attr_type (insn))
10784     {
10785     case TYPE_ALU:
10786       if (operands[2] != const1_rtx)
10787         abort ();
10788       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10789         return "add{l}\t{%k0, %k0|%k0, %k0}";
10790       else
10791         return "add{b}\t{%0, %0|%0, %0}";
10792
10793     default:
10794       if (REG_P (operands[2]))
10795         {
10796           if (get_attr_mode (insn) == MODE_SI)
10797             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10798           else
10799             return "sal{b}\t{%b2, %0|%0, %b2}";
10800         }
10801       else if (operands[2] == const1_rtx
10802                && (TARGET_SHIFT1 || optimize_size))
10803         {
10804           if (get_attr_mode (insn) == MODE_SI)
10805             return "sal{l}\t%0";
10806           else
10807             return "sal{b}\t%0";
10808         }
10809       else
10810         {
10811           if (get_attr_mode (insn) == MODE_SI)
10812             return "sal{l}\t{%2, %k0|%k0, %2}";
10813           else
10814             return "sal{b}\t{%2, %0|%0, %2}";
10815         }
10816     }
10817 }
10818   [(set (attr "type")
10819      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10820                           (const_int 0))
10821                       (match_operand 0 "register_operand" ""))
10822                  (match_operand 2 "const1_operand" ""))
10823               (const_string "alu")
10824            ]
10825            (const_string "ishift")))
10826    (set_attr "mode" "QI,SI")])
10827
10828 ;; This pattern can't accept a variable shift count, since shifts by
10829 ;; zero don't affect the flags.  We assume that shifts by constant
10830 ;; zero are optimized away.
10831 (define_insn "*ashlqi3_cmp"
10832   [(set (reg FLAGS_REG)
10833         (compare
10834           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10835                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10836           (const_int 0)))
10837    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10838         (ashift:QI (match_dup 1) (match_dup 2)))]
10839   "ix86_match_ccmode (insn, CCGOCmode)
10840    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10841 {
10842   switch (get_attr_type (insn))
10843     {
10844     case TYPE_ALU:
10845       if (operands[2] != const1_rtx)
10846         abort ();
10847       return "add{b}\t{%0, %0|%0, %0}";
10848
10849     default:
10850       if (REG_P (operands[2]))
10851         return "sal{b}\t{%b2, %0|%0, %b2}";
10852       else if (operands[2] == const1_rtx
10853                && (TARGET_SHIFT1 || optimize_size))
10854         return "sal{b}\t%0";
10855       else
10856         return "sal{b}\t{%2, %0|%0, %2}";
10857     }
10858 }
10859   [(set (attr "type")
10860      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10861                           (const_int 0))
10862                       (match_operand 0 "register_operand" ""))
10863                  (match_operand 2 "const1_operand" ""))
10864               (const_string "alu")
10865            ]
10866            (const_string "ishift")))
10867    (set_attr "mode" "QI")])
10868
10869 ;; See comment above `ashldi3' about how this works.
10870
10871 (define_expand "ashrdi3"
10872   [(set (match_operand:DI 0 "shiftdi_operand" "")
10873         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10874                      (match_operand:QI 2 "nonmemory_operand" "")))]
10875   ""
10876   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10877
10878 (define_insn "*ashrdi3_63_rex64"
10879   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10880         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10881                      (match_operand:DI 2 "const_int_operand" "i,i")))
10882    (clobber (reg:CC FLAGS_REG))]
10883   "TARGET_64BIT && INTVAL (operands[2]) == 63
10884    && (TARGET_USE_CLTD || optimize_size)
10885    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10886   "@
10887    {cqto|cqo}
10888    sar{q}\t{%2, %0|%0, %2}"
10889   [(set_attr "type" "imovx,ishift")
10890    (set_attr "prefix_0f" "0,*")
10891    (set_attr "length_immediate" "0,*")
10892    (set_attr "modrm" "0,1")
10893    (set_attr "mode" "DI")])
10894
10895 (define_insn "*ashrdi3_1_one_bit_rex64"
10896   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10897         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10898                      (match_operand:QI 2 "const1_operand" "")))
10899    (clobber (reg:CC FLAGS_REG))]
10900   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10901    && (TARGET_SHIFT1 || optimize_size)"
10902   "sar{q}\t%0"
10903   [(set_attr "type" "ishift")
10904    (set (attr "length") 
10905      (if_then_else (match_operand:DI 0 "register_operand" "") 
10906         (const_string "2")
10907         (const_string "*")))])
10908
10909 (define_insn "*ashrdi3_1_rex64"
10910   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10911         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10912                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10913    (clobber (reg:CC FLAGS_REG))]
10914   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10915   "@
10916    sar{q}\t{%2, %0|%0, %2}
10917    sar{q}\t{%b2, %0|%0, %b2}"
10918   [(set_attr "type" "ishift")
10919    (set_attr "mode" "DI")])
10920
10921 ;; This pattern can't accept a variable shift count, since shifts by
10922 ;; zero don't affect the flags.  We assume that shifts by constant
10923 ;; zero are optimized away.
10924 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10925   [(set (reg FLAGS_REG)
10926         (compare
10927           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10928                        (match_operand:QI 2 "const1_operand" ""))
10929           (const_int 0)))
10930    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10931         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10932   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10933    && (TARGET_SHIFT1 || optimize_size)
10934    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10935   "sar{q}\t%0"
10936   [(set_attr "type" "ishift")
10937    (set (attr "length") 
10938      (if_then_else (match_operand:DI 0 "register_operand" "") 
10939         (const_string "2")
10940         (const_string "*")))])
10941
10942 ;; This pattern can't accept a variable shift count, since shifts by
10943 ;; zero don't affect the flags.  We assume that shifts by constant
10944 ;; zero are optimized away.
10945 (define_insn "*ashrdi3_cmp_rex64"
10946   [(set (reg FLAGS_REG)
10947         (compare
10948           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10949                        (match_operand:QI 2 "const_int_operand" "n"))
10950           (const_int 0)))
10951    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10952         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10953   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10954    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10955   "sar{q}\t{%2, %0|%0, %2}"
10956   [(set_attr "type" "ishift")
10957    (set_attr "mode" "DI")])
10958
10959 (define_insn "*ashrdi3_1"
10960   [(set (match_operand:DI 0 "register_operand" "=r")
10961         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10962                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10963    (clobber (reg:CC FLAGS_REG))]
10964   "!TARGET_64BIT"
10965   "#"
10966   [(set_attr "type" "multi")])
10967
10968 ;; By default we don't ask for a scratch register, because when DImode
10969 ;; values are manipulated, registers are already at a premium.  But if
10970 ;; we have one handy, we won't turn it away.
10971 (define_peephole2
10972   [(match_scratch:SI 3 "r")
10973    (parallel [(set (match_operand:DI 0 "register_operand" "")
10974                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10975                                 (match_operand:QI 2 "nonmemory_operand" "")))
10976               (clobber (reg:CC FLAGS_REG))])
10977    (match_dup 3)]
10978   "!TARGET_64BIT && TARGET_CMOVE"
10979   [(const_int 0)]
10980   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10981
10982 (define_split
10983   [(set (match_operand:DI 0 "register_operand" "")
10984         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10985                      (match_operand:QI 2 "nonmemory_operand" "")))
10986    (clobber (reg:CC FLAGS_REG))]
10987   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10988   [(const_int 0)]
10989   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10990
10991 (define_insn "x86_shrd_1"
10992   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10993         (ior:SI (ashiftrt:SI (match_dup 0)
10994                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10995                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10996                   (minus:QI (const_int 32) (match_dup 2)))))
10997    (clobber (reg:CC FLAGS_REG))]
10998   ""
10999   "@
11000    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11001    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11002   [(set_attr "type" "ishift")
11003    (set_attr "prefix_0f" "1")
11004    (set_attr "pent_pair" "np")
11005    (set_attr "mode" "SI")])
11006
11007 (define_expand "x86_shift_adj_3"
11008   [(use (match_operand:SI 0 "register_operand" ""))
11009    (use (match_operand:SI 1 "register_operand" ""))
11010    (use (match_operand:QI 2 "register_operand" ""))]
11011   ""
11012 {
11013   rtx label = gen_label_rtx ();
11014   rtx tmp;
11015
11016   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11017
11018   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11019   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11020   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11021                               gen_rtx_LABEL_REF (VOIDmode, label),
11022                               pc_rtx);
11023   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11024   JUMP_LABEL (tmp) = label;
11025
11026   emit_move_insn (operands[0], operands[1]);
11027   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11028
11029   emit_label (label);
11030   LABEL_NUSES (label) = 1;
11031
11032   DONE;
11033 })
11034
11035 (define_insn "ashrsi3_31"
11036   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11037         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11038                      (match_operand:SI 2 "const_int_operand" "i,i")))
11039    (clobber (reg:CC FLAGS_REG))]
11040   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11041    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11042   "@
11043    {cltd|cdq}
11044    sar{l}\t{%2, %0|%0, %2}"
11045   [(set_attr "type" "imovx,ishift")
11046    (set_attr "prefix_0f" "0,*")
11047    (set_attr "length_immediate" "0,*")
11048    (set_attr "modrm" "0,1")
11049    (set_attr "mode" "SI")])
11050
11051 (define_insn "*ashrsi3_31_zext"
11052   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11053         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11054                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11055    (clobber (reg:CC FLAGS_REG))]
11056   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11057    && INTVAL (operands[2]) == 31
11058    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11059   "@
11060    {cltd|cdq}
11061    sar{l}\t{%2, %k0|%k0, %2}"
11062   [(set_attr "type" "imovx,ishift")
11063    (set_attr "prefix_0f" "0,*")
11064    (set_attr "length_immediate" "0,*")
11065    (set_attr "modrm" "0,1")
11066    (set_attr "mode" "SI")])
11067
11068 (define_expand "ashrsi3"
11069   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11070         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11071                      (match_operand:QI 2 "nonmemory_operand" "")))
11072    (clobber (reg:CC FLAGS_REG))]
11073   ""
11074   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11075
11076 (define_insn "*ashrsi3_1_one_bit"
11077   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11078         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11079                      (match_operand:QI 2 "const1_operand" "")))
11080    (clobber (reg:CC FLAGS_REG))]
11081   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11082    && (TARGET_SHIFT1 || optimize_size)"
11083   "sar{l}\t%0"
11084   [(set_attr "type" "ishift")
11085    (set (attr "length") 
11086      (if_then_else (match_operand:SI 0 "register_operand" "") 
11087         (const_string "2")
11088         (const_string "*")))])
11089
11090 (define_insn "*ashrsi3_1_one_bit_zext"
11091   [(set (match_operand:DI 0 "register_operand" "=r")
11092         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11093                                      (match_operand:QI 2 "const1_operand" ""))))
11094    (clobber (reg:CC FLAGS_REG))]
11095   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11096    && (TARGET_SHIFT1 || optimize_size)"
11097   "sar{l}\t%k0"
11098   [(set_attr "type" "ishift")
11099    (set_attr "length" "2")])
11100
11101 (define_insn "*ashrsi3_1"
11102   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11103         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11104                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11107   "@
11108    sar{l}\t{%2, %0|%0, %2}
11109    sar{l}\t{%b2, %0|%0, %b2}"
11110   [(set_attr "type" "ishift")
11111    (set_attr "mode" "SI")])
11112
11113 (define_insn "*ashrsi3_1_zext"
11114   [(set (match_operand:DI 0 "register_operand" "=r,r")
11115         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11116                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11117    (clobber (reg:CC FLAGS_REG))]
11118   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11119   "@
11120    sar{l}\t{%2, %k0|%k0, %2}
11121    sar{l}\t{%b2, %k0|%k0, %b2}"
11122   [(set_attr "type" "ishift")
11123    (set_attr "mode" "SI")])
11124
11125 ;; This pattern can't accept a variable shift count, since shifts by
11126 ;; zero don't affect the flags.  We assume that shifts by constant
11127 ;; zero are optimized away.
11128 (define_insn "*ashrsi3_one_bit_cmp"
11129   [(set (reg FLAGS_REG)
11130         (compare
11131           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11132                        (match_operand:QI 2 "const1_operand" ""))
11133           (const_int 0)))
11134    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11135         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11136   "ix86_match_ccmode (insn, CCGOCmode)
11137    && (TARGET_SHIFT1 || optimize_size)
11138    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11139   "sar{l}\t%0"
11140   [(set_attr "type" "ishift")
11141    (set (attr "length") 
11142      (if_then_else (match_operand:SI 0 "register_operand" "") 
11143         (const_string "2")
11144         (const_string "*")))])
11145
11146 (define_insn "*ashrsi3_one_bit_cmp_zext"
11147   [(set (reg FLAGS_REG)
11148         (compare
11149           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11150                        (match_operand:QI 2 "const1_operand" ""))
11151           (const_int 0)))
11152    (set (match_operand:DI 0 "register_operand" "=r")
11153         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11154   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11155    && (TARGET_SHIFT1 || optimize_size)
11156    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11157   "sar{l}\t%k0"
11158   [(set_attr "type" "ishift")
11159    (set_attr "length" "2")])
11160
11161 ;; This pattern can't accept a variable shift count, since shifts by
11162 ;; zero don't affect the flags.  We assume that shifts by constant
11163 ;; zero are optimized away.
11164 (define_insn "*ashrsi3_cmp"
11165   [(set (reg FLAGS_REG)
11166         (compare
11167           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11168                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11169           (const_int 0)))
11170    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11171         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11172   "ix86_match_ccmode (insn, CCGOCmode)
11173    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11174   "sar{l}\t{%2, %0|%0, %2}"
11175   [(set_attr "type" "ishift")
11176    (set_attr "mode" "SI")])
11177
11178 (define_insn "*ashrsi3_cmp_zext"
11179   [(set (reg FLAGS_REG)
11180         (compare
11181           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11182                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11183           (const_int 0)))
11184    (set (match_operand:DI 0 "register_operand" "=r")
11185         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11186   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11187    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11188   "sar{l}\t{%2, %k0|%k0, %2}"
11189   [(set_attr "type" "ishift")
11190    (set_attr "mode" "SI")])
11191
11192 (define_expand "ashrhi3"
11193   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11194         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11195                      (match_operand:QI 2 "nonmemory_operand" "")))
11196    (clobber (reg:CC FLAGS_REG))]
11197   "TARGET_HIMODE_MATH"
11198   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11199
11200 (define_insn "*ashrhi3_1_one_bit"
11201   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11202         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11203                      (match_operand:QI 2 "const1_operand" "")))
11204    (clobber (reg:CC FLAGS_REG))]
11205   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11206    && (TARGET_SHIFT1 || optimize_size)"
11207   "sar{w}\t%0"
11208   [(set_attr "type" "ishift")
11209    (set (attr "length") 
11210      (if_then_else (match_operand 0 "register_operand" "") 
11211         (const_string "2")
11212         (const_string "*")))])
11213
11214 (define_insn "*ashrhi3_1"
11215   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11216         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11217                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11218    (clobber (reg:CC FLAGS_REG))]
11219   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11220   "@
11221    sar{w}\t{%2, %0|%0, %2}
11222    sar{w}\t{%b2, %0|%0, %b2}"
11223   [(set_attr "type" "ishift")
11224    (set_attr "mode" "HI")])
11225
11226 ;; This pattern can't accept a variable shift count, since shifts by
11227 ;; zero don't affect the flags.  We assume that shifts by constant
11228 ;; zero are optimized away.
11229 (define_insn "*ashrhi3_one_bit_cmp"
11230   [(set (reg FLAGS_REG)
11231         (compare
11232           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11233                        (match_operand:QI 2 "const1_operand" ""))
11234           (const_int 0)))
11235    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11236         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11237   "ix86_match_ccmode (insn, CCGOCmode)
11238    && (TARGET_SHIFT1 || optimize_size)
11239    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11240   "sar{w}\t%0"
11241   [(set_attr "type" "ishift")
11242    (set (attr "length") 
11243      (if_then_else (match_operand 0 "register_operand" "") 
11244         (const_string "2")
11245         (const_string "*")))])
11246
11247 ;; This pattern can't accept a variable shift count, since shifts by
11248 ;; zero don't affect the flags.  We assume that shifts by constant
11249 ;; zero are optimized away.
11250 (define_insn "*ashrhi3_cmp"
11251   [(set (reg FLAGS_REG)
11252         (compare
11253           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11254                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11255           (const_int 0)))
11256    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11257         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11258   "ix86_match_ccmode (insn, CCGOCmode)
11259    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11260   "sar{w}\t{%2, %0|%0, %2}"
11261   [(set_attr "type" "ishift")
11262    (set_attr "mode" "HI")])
11263
11264 (define_expand "ashrqi3"
11265   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11266         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11267                      (match_operand:QI 2 "nonmemory_operand" "")))
11268    (clobber (reg:CC FLAGS_REG))]
11269   "TARGET_QIMODE_MATH"
11270   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11271
11272 (define_insn "*ashrqi3_1_one_bit"
11273   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11274         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11275                      (match_operand:QI 2 "const1_operand" "")))
11276    (clobber (reg:CC FLAGS_REG))]
11277   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11278    && (TARGET_SHIFT1 || optimize_size)"
11279   "sar{b}\t%0"
11280   [(set_attr "type" "ishift")
11281    (set (attr "length") 
11282      (if_then_else (match_operand 0 "register_operand" "") 
11283         (const_string "2")
11284         (const_string "*")))])
11285
11286 (define_insn "*ashrqi3_1_one_bit_slp"
11287   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11288         (ashiftrt:QI (match_dup 0)
11289                      (match_operand:QI 1 "const1_operand" "")))
11290    (clobber (reg:CC FLAGS_REG))]
11291   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11292    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11293    && (TARGET_SHIFT1 || optimize_size)"
11294   "sar{b}\t%0"
11295   [(set_attr "type" "ishift1")
11296    (set (attr "length") 
11297      (if_then_else (match_operand 0 "register_operand" "") 
11298         (const_string "2")
11299         (const_string "*")))])
11300
11301 (define_insn "*ashrqi3_1"
11302   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11303         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11304                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11305    (clobber (reg:CC FLAGS_REG))]
11306   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11307   "@
11308    sar{b}\t{%2, %0|%0, %2}
11309    sar{b}\t{%b2, %0|%0, %b2}"
11310   [(set_attr "type" "ishift")
11311    (set_attr "mode" "QI")])
11312
11313 (define_insn "*ashrqi3_1_slp"
11314   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11315         (ashiftrt:QI (match_dup 0)
11316                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11319    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11320   "@
11321    sar{b}\t{%1, %0|%0, %1}
11322    sar{b}\t{%b1, %0|%0, %b1}"
11323   [(set_attr "type" "ishift1")
11324    (set_attr "mode" "QI")])
11325
11326 ;; This pattern can't accept a variable shift count, since shifts by
11327 ;; zero don't affect the flags.  We assume that shifts by constant
11328 ;; zero are optimized away.
11329 (define_insn "*ashrqi3_one_bit_cmp"
11330   [(set (reg FLAGS_REG)
11331         (compare
11332           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11333                        (match_operand:QI 2 "const1_operand" "I"))
11334           (const_int 0)))
11335    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11336         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11337   "ix86_match_ccmode (insn, CCGOCmode)
11338    && (TARGET_SHIFT1 || optimize_size)
11339    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11340   "sar{b}\t%0"
11341   [(set_attr "type" "ishift")
11342    (set (attr "length") 
11343      (if_then_else (match_operand 0 "register_operand" "") 
11344         (const_string "2")
11345         (const_string "*")))])
11346
11347 ;; This pattern can't accept a variable shift count, since shifts by
11348 ;; zero don't affect the flags.  We assume that shifts by constant
11349 ;; zero are optimized away.
11350 (define_insn "*ashrqi3_cmp"
11351   [(set (reg FLAGS_REG)
11352         (compare
11353           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11354                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11355           (const_int 0)))
11356    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11357         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11358   "ix86_match_ccmode (insn, CCGOCmode)
11359    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11360   "sar{b}\t{%2, %0|%0, %2}"
11361   [(set_attr "type" "ishift")
11362    (set_attr "mode" "QI")])
11363 \f
11364 ;; Logical shift instructions
11365
11366 ;; See comment above `ashldi3' about how this works.
11367
11368 (define_expand "lshrdi3"
11369   [(set (match_operand:DI 0 "shiftdi_operand" "")
11370         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11371                      (match_operand:QI 2 "nonmemory_operand" "")))]
11372   ""
11373   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11374
11375 (define_insn "*lshrdi3_1_one_bit_rex64"
11376   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11377         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11378                      (match_operand:QI 2 "const1_operand" "")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11381    && (TARGET_SHIFT1 || optimize_size)"
11382   "shr{q}\t%0"
11383   [(set_attr "type" "ishift")
11384    (set (attr "length") 
11385      (if_then_else (match_operand:DI 0 "register_operand" "") 
11386         (const_string "2")
11387         (const_string "*")))])
11388
11389 (define_insn "*lshrdi3_1_rex64"
11390   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11391         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11392                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11393    (clobber (reg:CC FLAGS_REG))]
11394   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11395   "@
11396    shr{q}\t{%2, %0|%0, %2}
11397    shr{q}\t{%b2, %0|%0, %b2}"
11398   [(set_attr "type" "ishift")
11399    (set_attr "mode" "DI")])
11400
11401 ;; This pattern can't accept a variable shift count, since shifts by
11402 ;; zero don't affect the flags.  We assume that shifts by constant
11403 ;; zero are optimized away.
11404 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11405   [(set (reg FLAGS_REG)
11406         (compare
11407           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11408                        (match_operand:QI 2 "const1_operand" ""))
11409           (const_int 0)))
11410    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11412   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11413    && (TARGET_SHIFT1 || optimize_size)
11414    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11415   "shr{q}\t%0"
11416   [(set_attr "type" "ishift")
11417    (set (attr "length") 
11418      (if_then_else (match_operand:DI 0 "register_operand" "") 
11419         (const_string "2")
11420         (const_string "*")))])
11421
11422 ;; This pattern can't accept a variable shift count, since shifts by
11423 ;; zero don't affect the flags.  We assume that shifts by constant
11424 ;; zero are optimized away.
11425 (define_insn "*lshrdi3_cmp_rex64"
11426   [(set (reg FLAGS_REG)
11427         (compare
11428           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11429                        (match_operand:QI 2 "const_int_operand" "e"))
11430           (const_int 0)))
11431    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11432         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11433   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11434    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11435   "shr{q}\t{%2, %0|%0, %2}"
11436   [(set_attr "type" "ishift")
11437    (set_attr "mode" "DI")])
11438
11439 (define_insn "*lshrdi3_1"
11440   [(set (match_operand:DI 0 "register_operand" "=r")
11441         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11442                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11443    (clobber (reg:CC FLAGS_REG))]
11444   "!TARGET_64BIT"
11445   "#"
11446   [(set_attr "type" "multi")])
11447
11448 ;; By default we don't ask for a scratch register, because when DImode
11449 ;; values are manipulated, registers are already at a premium.  But if
11450 ;; we have one handy, we won't turn it away.
11451 (define_peephole2
11452   [(match_scratch:SI 3 "r")
11453    (parallel [(set (match_operand:DI 0 "register_operand" "")
11454                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11455                                 (match_operand:QI 2 "nonmemory_operand" "")))
11456               (clobber (reg:CC FLAGS_REG))])
11457    (match_dup 3)]
11458   "!TARGET_64BIT && TARGET_CMOVE"
11459   [(const_int 0)]
11460   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11461
11462 (define_split 
11463   [(set (match_operand:DI 0 "register_operand" "")
11464         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11465                      (match_operand:QI 2 "nonmemory_operand" "")))
11466    (clobber (reg:CC FLAGS_REG))]
11467   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11468   [(const_int 0)]
11469   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11470
11471 (define_expand "lshrsi3"
11472   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11473         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11474                      (match_operand:QI 2 "nonmemory_operand" "")))
11475    (clobber (reg:CC FLAGS_REG))]
11476   ""
11477   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11478
11479 (define_insn "*lshrsi3_1_one_bit"
11480   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11481         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11482                      (match_operand:QI 2 "const1_operand" "")))
11483    (clobber (reg:CC FLAGS_REG))]
11484   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11485    && (TARGET_SHIFT1 || optimize_size)"
11486   "shr{l}\t%0"
11487   [(set_attr "type" "ishift")
11488    (set (attr "length") 
11489      (if_then_else (match_operand:SI 0 "register_operand" "") 
11490         (const_string "2")
11491         (const_string "*")))])
11492
11493 (define_insn "*lshrsi3_1_one_bit_zext"
11494   [(set (match_operand:DI 0 "register_operand" "=r")
11495         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11496                      (match_operand:QI 2 "const1_operand" "")))
11497    (clobber (reg:CC FLAGS_REG))]
11498   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11499    && (TARGET_SHIFT1 || optimize_size)"
11500   "shr{l}\t%k0"
11501   [(set_attr "type" "ishift")
11502    (set_attr "length" "2")])
11503
11504 (define_insn "*lshrsi3_1"
11505   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11506         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11507                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11508    (clobber (reg:CC FLAGS_REG))]
11509   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11510   "@
11511    shr{l}\t{%2, %0|%0, %2}
11512    shr{l}\t{%b2, %0|%0, %b2}"
11513   [(set_attr "type" "ishift")
11514    (set_attr "mode" "SI")])
11515
11516 (define_insn "*lshrsi3_1_zext"
11517   [(set (match_operand:DI 0 "register_operand" "=r,r")
11518         (zero_extend:DI
11519           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11520                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11521    (clobber (reg:CC FLAGS_REG))]
11522   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11523   "@
11524    shr{l}\t{%2, %k0|%k0, %2}
11525    shr{l}\t{%b2, %k0|%k0, %b2}"
11526   [(set_attr "type" "ishift")
11527    (set_attr "mode" "SI")])
11528
11529 ;; This pattern can't accept a variable shift count, since shifts by
11530 ;; zero don't affect the flags.  We assume that shifts by constant
11531 ;; zero are optimized away.
11532 (define_insn "*lshrsi3_one_bit_cmp"
11533   [(set (reg FLAGS_REG)
11534         (compare
11535           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11536                        (match_operand:QI 2 "const1_operand" ""))
11537           (const_int 0)))
11538    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11539         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11540   "ix86_match_ccmode (insn, CCGOCmode)
11541    && (TARGET_SHIFT1 || optimize_size)
11542    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11543   "shr{l}\t%0"
11544   [(set_attr "type" "ishift")
11545    (set (attr "length") 
11546      (if_then_else (match_operand:SI 0 "register_operand" "") 
11547         (const_string "2")
11548         (const_string "*")))])
11549
11550 (define_insn "*lshrsi3_cmp_one_bit_zext"
11551   [(set (reg FLAGS_REG)
11552         (compare
11553           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11554                        (match_operand:QI 2 "const1_operand" ""))
11555           (const_int 0)))
11556    (set (match_operand:DI 0 "register_operand" "=r")
11557         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11558   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11559    && (TARGET_SHIFT1 || optimize_size)
11560    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11561   "shr{l}\t%k0"
11562   [(set_attr "type" "ishift")
11563    (set_attr "length" "2")])
11564
11565 ;; This pattern can't accept a variable shift count, since shifts by
11566 ;; zero don't affect the flags.  We assume that shifts by constant
11567 ;; zero are optimized away.
11568 (define_insn "*lshrsi3_cmp"
11569   [(set (reg FLAGS_REG)
11570         (compare
11571           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11572                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11573           (const_int 0)))
11574    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11575         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11576   "ix86_match_ccmode (insn, CCGOCmode)
11577    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11578   "shr{l}\t{%2, %0|%0, %2}"
11579   [(set_attr "type" "ishift")
11580    (set_attr "mode" "SI")])
11581
11582 (define_insn "*lshrsi3_cmp_zext"
11583   [(set (reg FLAGS_REG)
11584         (compare
11585           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11586                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11587           (const_int 0)))
11588    (set (match_operand:DI 0 "register_operand" "=r")
11589         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11590   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11591    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11592   "shr{l}\t{%2, %k0|%k0, %2}"
11593   [(set_attr "type" "ishift")
11594    (set_attr "mode" "SI")])
11595
11596 (define_expand "lshrhi3"
11597   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11598         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11599                      (match_operand:QI 2 "nonmemory_operand" "")))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "TARGET_HIMODE_MATH"
11602   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11603
11604 (define_insn "*lshrhi3_1_one_bit"
11605   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11606         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11607                      (match_operand:QI 2 "const1_operand" "")))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11610    && (TARGET_SHIFT1 || optimize_size)"
11611   "shr{w}\t%0"
11612   [(set_attr "type" "ishift")
11613    (set (attr "length") 
11614      (if_then_else (match_operand 0 "register_operand" "") 
11615         (const_string "2")
11616         (const_string "*")))])
11617
11618 (define_insn "*lshrhi3_1"
11619   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11620         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11621                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11622    (clobber (reg:CC FLAGS_REG))]
11623   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11624   "@
11625    shr{w}\t{%2, %0|%0, %2}
11626    shr{w}\t{%b2, %0|%0, %b2}"
11627   [(set_attr "type" "ishift")
11628    (set_attr "mode" "HI")])
11629
11630 ;; This pattern can't accept a variable shift count, since shifts by
11631 ;; zero don't affect the flags.  We assume that shifts by constant
11632 ;; zero are optimized away.
11633 (define_insn "*lshrhi3_one_bit_cmp"
11634   [(set (reg FLAGS_REG)
11635         (compare
11636           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11637                        (match_operand:QI 2 "const1_operand" ""))
11638           (const_int 0)))
11639    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11640         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11641   "ix86_match_ccmode (insn, CCGOCmode)
11642    && (TARGET_SHIFT1 || optimize_size)
11643    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11644   "shr{w}\t%0"
11645   [(set_attr "type" "ishift")
11646    (set (attr "length") 
11647      (if_then_else (match_operand:SI 0 "register_operand" "") 
11648         (const_string "2")
11649         (const_string "*")))])
11650
11651 ;; This pattern can't accept a variable shift count, since shifts by
11652 ;; zero don't affect the flags.  We assume that shifts by constant
11653 ;; zero are optimized away.
11654 (define_insn "*lshrhi3_cmp"
11655   [(set (reg FLAGS_REG)
11656         (compare
11657           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11658                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11659           (const_int 0)))
11660    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11661         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11662   "ix86_match_ccmode (insn, CCGOCmode)
11663    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11664   "shr{w}\t{%2, %0|%0, %2}"
11665   [(set_attr "type" "ishift")
11666    (set_attr "mode" "HI")])
11667
11668 (define_expand "lshrqi3"
11669   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11670         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11671                      (match_operand:QI 2 "nonmemory_operand" "")))
11672    (clobber (reg:CC FLAGS_REG))]
11673   "TARGET_QIMODE_MATH"
11674   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11675
11676 (define_insn "*lshrqi3_1_one_bit"
11677   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11678         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11679                      (match_operand:QI 2 "const1_operand" "")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11682    && (TARGET_SHIFT1 || optimize_size)"
11683   "shr{b}\t%0"
11684   [(set_attr "type" "ishift")
11685    (set (attr "length") 
11686      (if_then_else (match_operand 0 "register_operand" "") 
11687         (const_string "2")
11688         (const_string "*")))])
11689
11690 (define_insn "*lshrqi3_1_one_bit_slp"
11691   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11692         (lshiftrt:QI (match_dup 0)
11693                      (match_operand:QI 1 "const1_operand" "")))
11694    (clobber (reg:CC FLAGS_REG))]
11695   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11696    && (TARGET_SHIFT1 || optimize_size)"
11697   "shr{b}\t%0"
11698   [(set_attr "type" "ishift1")
11699    (set (attr "length") 
11700      (if_then_else (match_operand 0 "register_operand" "") 
11701         (const_string "2")
11702         (const_string "*")))])
11703
11704 (define_insn "*lshrqi3_1"
11705   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11706         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11707                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11708    (clobber (reg:CC FLAGS_REG))]
11709   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11710   "@
11711    shr{b}\t{%2, %0|%0, %2}
11712    shr{b}\t{%b2, %0|%0, %b2}"
11713   [(set_attr "type" "ishift")
11714    (set_attr "mode" "QI")])
11715
11716 (define_insn "*lshrqi3_1_slp"
11717   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11718         (lshiftrt:QI (match_dup 0)
11719                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11723   "@
11724    shr{b}\t{%1, %0|%0, %1}
11725    shr{b}\t{%b1, %0|%0, %b1}"
11726   [(set_attr "type" "ishift1")
11727    (set_attr "mode" "QI")])
11728
11729 ;; This pattern can't accept a variable shift count, since shifts by
11730 ;; zero don't affect the flags.  We assume that shifts by constant
11731 ;; zero are optimized away.
11732 (define_insn "*lshrqi2_one_bit_cmp"
11733   [(set (reg FLAGS_REG)
11734         (compare
11735           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11736                        (match_operand:QI 2 "const1_operand" ""))
11737           (const_int 0)))
11738    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11739         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11740   "ix86_match_ccmode (insn, CCGOCmode)
11741    && (TARGET_SHIFT1 || optimize_size)
11742    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11743   "shr{b}\t%0"
11744   [(set_attr "type" "ishift")
11745    (set (attr "length") 
11746      (if_then_else (match_operand:SI 0 "register_operand" "") 
11747         (const_string "2")
11748         (const_string "*")))])
11749
11750 ;; This pattern can't accept a variable shift count, since shifts by
11751 ;; zero don't affect the flags.  We assume that shifts by constant
11752 ;; zero are optimized away.
11753 (define_insn "*lshrqi2_cmp"
11754   [(set (reg FLAGS_REG)
11755         (compare
11756           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11757                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11758           (const_int 0)))
11759    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11760         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11761   "ix86_match_ccmode (insn, CCGOCmode)
11762    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11763   "shr{b}\t{%2, %0|%0, %2}"
11764   [(set_attr "type" "ishift")
11765    (set_attr "mode" "QI")])
11766 \f
11767 ;; Rotate instructions
11768
11769 (define_expand "rotldi3"
11770   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11771         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11772                    (match_operand:QI 2 "nonmemory_operand" "")))
11773    (clobber (reg:CC FLAGS_REG))]
11774   "TARGET_64BIT"
11775   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11776
11777 (define_insn "*rotlsi3_1_one_bit_rex64"
11778   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11779         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11780                    (match_operand:QI 2 "const1_operand" "")))
11781    (clobber (reg:CC FLAGS_REG))]
11782   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11783    && (TARGET_SHIFT1 || optimize_size)"
11784   "rol{q}\t%0"
11785   [(set_attr "type" "rotate")
11786    (set (attr "length") 
11787      (if_then_else (match_operand:DI 0 "register_operand" "") 
11788         (const_string "2")
11789         (const_string "*")))])
11790
11791 (define_insn "*rotldi3_1_rex64"
11792   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11793         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11794                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11795    (clobber (reg:CC FLAGS_REG))]
11796   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11797   "@
11798    rol{q}\t{%2, %0|%0, %2}
11799    rol{q}\t{%b2, %0|%0, %b2}"
11800   [(set_attr "type" "rotate")
11801    (set_attr "mode" "DI")])
11802
11803 (define_expand "rotlsi3"
11804   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11805         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11806                    (match_operand:QI 2 "nonmemory_operand" "")))
11807    (clobber (reg:CC FLAGS_REG))]
11808   ""
11809   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11810
11811 (define_insn "*rotlsi3_1_one_bit"
11812   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11813         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11814                    (match_operand:QI 2 "const1_operand" "")))
11815    (clobber (reg:CC FLAGS_REG))]
11816   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11817    && (TARGET_SHIFT1 || optimize_size)"
11818   "rol{l}\t%0"
11819   [(set_attr "type" "rotate")
11820    (set (attr "length") 
11821      (if_then_else (match_operand:SI 0 "register_operand" "") 
11822         (const_string "2")
11823         (const_string "*")))])
11824
11825 (define_insn "*rotlsi3_1_one_bit_zext"
11826   [(set (match_operand:DI 0 "register_operand" "=r")
11827         (zero_extend:DI
11828           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11829                      (match_operand:QI 2 "const1_operand" ""))))
11830    (clobber (reg:CC FLAGS_REG))]
11831   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11832    && (TARGET_SHIFT1 || optimize_size)"
11833   "rol{l}\t%k0"
11834   [(set_attr "type" "rotate")
11835    (set_attr "length" "2")])
11836
11837 (define_insn "*rotlsi3_1"
11838   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11839         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11840                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11841    (clobber (reg:CC FLAGS_REG))]
11842   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11843   "@
11844    rol{l}\t{%2, %0|%0, %2}
11845    rol{l}\t{%b2, %0|%0, %b2}"
11846   [(set_attr "type" "rotate")
11847    (set_attr "mode" "SI")])
11848
11849 (define_insn "*rotlsi3_1_zext"
11850   [(set (match_operand:DI 0 "register_operand" "=r,r")
11851         (zero_extend:DI
11852           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11853                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11854    (clobber (reg:CC FLAGS_REG))]
11855   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11856   "@
11857    rol{l}\t{%2, %k0|%k0, %2}
11858    rol{l}\t{%b2, %k0|%k0, %b2}"
11859   [(set_attr "type" "rotate")
11860    (set_attr "mode" "SI")])
11861
11862 (define_expand "rotlhi3"
11863   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11864         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11865                    (match_operand:QI 2 "nonmemory_operand" "")))
11866    (clobber (reg:CC FLAGS_REG))]
11867   "TARGET_HIMODE_MATH"
11868   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11869
11870 (define_insn "*rotlhi3_1_one_bit"
11871   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11872         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11873                    (match_operand:QI 2 "const1_operand" "")))
11874    (clobber (reg:CC FLAGS_REG))]
11875   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11876    && (TARGET_SHIFT1 || optimize_size)"
11877   "rol{w}\t%0"
11878   [(set_attr "type" "rotate")
11879    (set (attr "length") 
11880      (if_then_else (match_operand 0 "register_operand" "") 
11881         (const_string "2")
11882         (const_string "*")))])
11883
11884 (define_insn "*rotlhi3_1"
11885   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11886         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11887                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11888    (clobber (reg:CC FLAGS_REG))]
11889   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11890   "@
11891    rol{w}\t{%2, %0|%0, %2}
11892    rol{w}\t{%b2, %0|%0, %b2}"
11893   [(set_attr "type" "rotate")
11894    (set_attr "mode" "HI")])
11895
11896 (define_expand "rotlqi3"
11897   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11898         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11899                    (match_operand:QI 2 "nonmemory_operand" "")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "TARGET_QIMODE_MATH"
11902   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11903
11904 (define_insn "*rotlqi3_1_one_bit_slp"
11905   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11906         (rotate:QI (match_dup 0)
11907                    (match_operand:QI 1 "const1_operand" "")))
11908    (clobber (reg:CC FLAGS_REG))]
11909   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11910    && (TARGET_SHIFT1 || optimize_size)"
11911   "rol{b}\t%0"
11912   [(set_attr "type" "rotate1")
11913    (set (attr "length") 
11914      (if_then_else (match_operand 0 "register_operand" "") 
11915         (const_string "2")
11916         (const_string "*")))])
11917
11918 (define_insn "*rotlqi3_1_one_bit"
11919   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11920         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11921                    (match_operand:QI 2 "const1_operand" "")))
11922    (clobber (reg:CC FLAGS_REG))]
11923   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11924    && (TARGET_SHIFT1 || optimize_size)"
11925   "rol{b}\t%0"
11926   [(set_attr "type" "rotate")
11927    (set (attr "length") 
11928      (if_then_else (match_operand 0 "register_operand" "") 
11929         (const_string "2")
11930         (const_string "*")))])
11931
11932 (define_insn "*rotlqi3_1_slp"
11933   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11934         (rotate:QI (match_dup 0)
11935                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11938    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11939   "@
11940    rol{b}\t{%1, %0|%0, %1}
11941    rol{b}\t{%b1, %0|%0, %b1}"
11942   [(set_attr "type" "rotate1")
11943    (set_attr "mode" "QI")])
11944
11945 (define_insn "*rotlqi3_1"
11946   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11947         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11948                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11949    (clobber (reg:CC FLAGS_REG))]
11950   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11951   "@
11952    rol{b}\t{%2, %0|%0, %2}
11953    rol{b}\t{%b2, %0|%0, %b2}"
11954   [(set_attr "type" "rotate")
11955    (set_attr "mode" "QI")])
11956
11957 (define_expand "rotrdi3"
11958   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11959         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11960                      (match_operand:QI 2 "nonmemory_operand" "")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "TARGET_64BIT"
11963   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11964
11965 (define_insn "*rotrdi3_1_one_bit_rex64"
11966   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11967         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11968                      (match_operand:QI 2 "const1_operand" "")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11971    && (TARGET_SHIFT1 || optimize_size)"
11972   "ror{q}\t%0"
11973   [(set_attr "type" "rotate")
11974    (set (attr "length") 
11975      (if_then_else (match_operand:DI 0 "register_operand" "") 
11976         (const_string "2")
11977         (const_string "*")))])
11978
11979 (define_insn "*rotrdi3_1_rex64"
11980   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11981         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11982                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11983    (clobber (reg:CC FLAGS_REG))]
11984   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11985   "@
11986    ror{q}\t{%2, %0|%0, %2}
11987    ror{q}\t{%b2, %0|%0, %b2}"
11988   [(set_attr "type" "rotate")
11989    (set_attr "mode" "DI")])
11990
11991 (define_expand "rotrsi3"
11992   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11993         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11994                      (match_operand:QI 2 "nonmemory_operand" "")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   ""
11997   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11998
11999 (define_insn "*rotrsi3_1_one_bit"
12000   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12001         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12002                      (match_operand:QI 2 "const1_operand" "")))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12005    && (TARGET_SHIFT1 || optimize_size)"
12006   "ror{l}\t%0"
12007   [(set_attr "type" "rotate")
12008    (set (attr "length") 
12009      (if_then_else (match_operand:SI 0 "register_operand" "") 
12010         (const_string "2")
12011         (const_string "*")))])
12012
12013 (define_insn "*rotrsi3_1_one_bit_zext"
12014   [(set (match_operand:DI 0 "register_operand" "=r")
12015         (zero_extend:DI
12016           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12017                        (match_operand:QI 2 "const1_operand" ""))))
12018    (clobber (reg:CC FLAGS_REG))]
12019   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12020    && (TARGET_SHIFT1 || optimize_size)"
12021   "ror{l}\t%k0"
12022   [(set_attr "type" "rotate")
12023    (set (attr "length") 
12024      (if_then_else (match_operand:SI 0 "register_operand" "") 
12025         (const_string "2")
12026         (const_string "*")))])
12027
12028 (define_insn "*rotrsi3_1"
12029   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12030         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12031                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12032    (clobber (reg:CC FLAGS_REG))]
12033   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12034   "@
12035    ror{l}\t{%2, %0|%0, %2}
12036    ror{l}\t{%b2, %0|%0, %b2}"
12037   [(set_attr "type" "rotate")
12038    (set_attr "mode" "SI")])
12039
12040 (define_insn "*rotrsi3_1_zext"
12041   [(set (match_operand:DI 0 "register_operand" "=r,r")
12042         (zero_extend:DI
12043           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12044                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12045    (clobber (reg:CC FLAGS_REG))]
12046   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12047   "@
12048    ror{l}\t{%2, %k0|%k0, %2}
12049    ror{l}\t{%b2, %k0|%k0, %b2}"
12050   [(set_attr "type" "rotate")
12051    (set_attr "mode" "SI")])
12052
12053 (define_expand "rotrhi3"
12054   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12055         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12056                      (match_operand:QI 2 "nonmemory_operand" "")))
12057    (clobber (reg:CC FLAGS_REG))]
12058   "TARGET_HIMODE_MATH"
12059   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12060
12061 (define_insn "*rotrhi3_one_bit"
12062   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12063         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12064                      (match_operand:QI 2 "const1_operand" "")))
12065    (clobber (reg:CC FLAGS_REG))]
12066   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12067    && (TARGET_SHIFT1 || optimize_size)"
12068   "ror{w}\t%0"
12069   [(set_attr "type" "rotate")
12070    (set (attr "length") 
12071      (if_then_else (match_operand 0 "register_operand" "") 
12072         (const_string "2")
12073         (const_string "*")))])
12074
12075 (define_insn "*rotrhi3"
12076   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12077         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12078                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12079    (clobber (reg:CC FLAGS_REG))]
12080   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12081   "@
12082    ror{w}\t{%2, %0|%0, %2}
12083    ror{w}\t{%b2, %0|%0, %b2}"
12084   [(set_attr "type" "rotate")
12085    (set_attr "mode" "HI")])
12086
12087 (define_expand "rotrqi3"
12088   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12089         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12090                      (match_operand:QI 2 "nonmemory_operand" "")))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "TARGET_QIMODE_MATH"
12093   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12094
12095 (define_insn "*rotrqi3_1_one_bit"
12096   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12097         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12098                      (match_operand:QI 2 "const1_operand" "")))
12099    (clobber (reg:CC FLAGS_REG))]
12100   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12101    && (TARGET_SHIFT1 || optimize_size)"
12102   "ror{b}\t%0"
12103   [(set_attr "type" "rotate")
12104    (set (attr "length") 
12105      (if_then_else (match_operand 0 "register_operand" "") 
12106         (const_string "2")
12107         (const_string "*")))])
12108
12109 (define_insn "*rotrqi3_1_one_bit_slp"
12110   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12111         (rotatert:QI (match_dup 0)
12112                      (match_operand:QI 1 "const1_operand" "")))
12113    (clobber (reg:CC FLAGS_REG))]
12114   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12115    && (TARGET_SHIFT1 || optimize_size)"
12116   "ror{b}\t%0"
12117   [(set_attr "type" "rotate1")
12118    (set (attr "length") 
12119      (if_then_else (match_operand 0 "register_operand" "") 
12120         (const_string "2")
12121         (const_string "*")))])
12122
12123 (define_insn "*rotrqi3_1"
12124   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12125         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12126                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12129   "@
12130    ror{b}\t{%2, %0|%0, %2}
12131    ror{b}\t{%b2, %0|%0, %b2}"
12132   [(set_attr "type" "rotate")
12133    (set_attr "mode" "QI")])
12134
12135 (define_insn "*rotrqi3_1_slp"
12136   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12137         (rotatert:QI (match_dup 0)
12138                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12141    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12142   "@
12143    ror{b}\t{%1, %0|%0, %1}
12144    ror{b}\t{%b1, %0|%0, %b1}"
12145   [(set_attr "type" "rotate1")
12146    (set_attr "mode" "QI")])
12147 \f
12148 ;; Bit set / bit test instructions
12149
12150 (define_expand "extv"
12151   [(set (match_operand:SI 0 "register_operand" "")
12152         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12153                          (match_operand:SI 2 "immediate_operand" "")
12154                          (match_operand:SI 3 "immediate_operand" "")))]
12155   ""
12156 {
12157   /* Handle extractions from %ah et al.  */
12158   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12159     FAIL;
12160
12161   /* From mips.md: extract_bit_field doesn't verify that our source
12162      matches the predicate, so check it again here.  */
12163   if (! register_operand (operands[1], VOIDmode))
12164     FAIL;
12165 })
12166
12167 (define_expand "extzv"
12168   [(set (match_operand:SI 0 "register_operand" "")
12169         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12170                          (match_operand:SI 2 "immediate_operand" "")
12171                          (match_operand:SI 3 "immediate_operand" "")))]
12172   ""
12173 {
12174   /* Handle extractions from %ah et al.  */
12175   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12176     FAIL;
12177
12178   /* From mips.md: extract_bit_field doesn't verify that our source
12179      matches the predicate, so check it again here.  */
12180   if (! register_operand (operands[1], VOIDmode))
12181     FAIL;
12182 })
12183
12184 (define_expand "insv"
12185   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12186                       (match_operand 1 "immediate_operand" "")
12187                       (match_operand 2 "immediate_operand" ""))
12188         (match_operand 3 "register_operand" ""))]
12189   ""
12190 {
12191   /* Handle extractions from %ah et al.  */
12192   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12193     FAIL;
12194
12195   /* From mips.md: insert_bit_field doesn't verify that our source
12196      matches the predicate, so check it again here.  */
12197   if (! register_operand (operands[0], VOIDmode))
12198     FAIL;
12199
12200   if (TARGET_64BIT)
12201     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12202   else
12203     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12204
12205   DONE;
12206 })
12207
12208 ;; %%% bts, btr, btc, bt.
12209 ;; In general these instructions are *slow* when applied to memory,
12210 ;; since they enforce atomic operation.  When applied to registers,
12211 ;; it depends on the cpu implementation.  They're never faster than
12212 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12213 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12214 ;; within the instruction itself, so operating on bits in the high
12215 ;; 32-bits of a register becomes easier.
12216 ;;
12217 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12218 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12219 ;; negdf respectively, so they can never be disabled entirely.
12220
12221 (define_insn "*btsq"
12222   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12223                          (const_int 1)
12224                          (match_operand 1 "const_0_to_63_operand" ""))
12225         (const_int 1))
12226    (clobber (reg:CC FLAGS_REG))]
12227   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12228   "bts{q} %1,%0"
12229   [(set_attr "type" "alu1")])
12230
12231 (define_insn "*btrq"
12232   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12233                          (const_int 1)
12234                          (match_operand 1 "const_0_to_63_operand" ""))
12235         (const_int 0))
12236    (clobber (reg:CC FLAGS_REG))]
12237   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12238   "btr{q} %1,%0"
12239   [(set_attr "type" "alu1")])
12240
12241 (define_insn "*btcq"
12242   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12243                          (const_int 1)
12244                          (match_operand 1 "const_0_to_63_operand" ""))
12245         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12246    (clobber (reg:CC FLAGS_REG))]
12247   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12248   "btc{q} %1,%0"
12249   [(set_attr "type" "alu1")])
12250
12251 ;; Allow Nocona to avoid these instructions if a register is available.
12252
12253 (define_peephole2
12254   [(match_scratch:DI 2 "r")
12255    (parallel [(set (zero_extract:DI
12256                      (match_operand 0 "register_operand" "")
12257                      (const_int 1)
12258                      (match_operand 1 "const_0_to_63_operand" ""))
12259                    (const_int 1))
12260               (clobber (reg:CC FLAGS_REG))])]
12261   "TARGET_64BIT && !TARGET_USE_BT"
12262   [(const_int 0)]
12263 {
12264   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12265   rtx op1;
12266
12267   if (HOST_BITS_PER_WIDE_INT >= 64)
12268     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12269   else if (i < HOST_BITS_PER_WIDE_INT)
12270     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12271   else
12272     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12273
12274   op1 = immed_double_const (lo, hi, DImode);
12275   if (i >= 31)
12276     {
12277       emit_move_insn (operands[2], op1);
12278       op1 = operands[2];
12279     }
12280
12281   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12282   DONE;
12283 })
12284
12285 (define_peephole2
12286   [(match_scratch:DI 2 "r")
12287    (parallel [(set (zero_extract:DI
12288                      (match_operand 0 "register_operand" "")
12289                      (const_int 1)
12290                      (match_operand 1 "const_0_to_63_operand" ""))
12291                    (const_int 0))
12292               (clobber (reg:CC FLAGS_REG))])]
12293   "TARGET_64BIT && !TARGET_USE_BT"
12294   [(const_int 0)]
12295 {
12296   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12297   rtx op1;
12298
12299   if (HOST_BITS_PER_WIDE_INT >= 64)
12300     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12301   else if (i < HOST_BITS_PER_WIDE_INT)
12302     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12303   else
12304     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12305
12306   op1 = immed_double_const (~lo, ~hi, DImode);
12307   if (i >= 32)
12308     {
12309       emit_move_insn (operands[2], op1);
12310       op1 = operands[2];
12311     }
12312
12313   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12314   DONE;
12315 })
12316
12317 (define_peephole2
12318   [(match_scratch:DI 2 "r")
12319    (parallel [(set (zero_extract:DI
12320                      (match_operand 0 "register_operand" "")
12321                      (const_int 1)
12322                      (match_operand 1 "const_0_to_63_operand" ""))
12323               (not:DI (zero_extract:DI
12324                         (match_dup 0) (const_int 1) (match_dup 1))))
12325               (clobber (reg:CC FLAGS_REG))])]
12326   "TARGET_64BIT && !TARGET_USE_BT"
12327   [(const_int 0)]
12328 {
12329   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12330   rtx op1;
12331
12332   if (HOST_BITS_PER_WIDE_INT >= 64)
12333     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12334   else if (i < HOST_BITS_PER_WIDE_INT)
12335     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12336   else
12337     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12338
12339   op1 = immed_double_const (lo, hi, DImode);
12340   if (i >= 31)
12341     {
12342       emit_move_insn (operands[2], op1);
12343       op1 = operands[2];
12344     }
12345
12346   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12347   DONE;
12348 })
12349 \f
12350 ;; Store-flag instructions.
12351
12352 ;; For all sCOND expanders, also expand the compare or test insn that
12353 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12354
12355 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12356 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12357 ;; way, which can later delete the movzx if only QImode is needed.
12358
12359 (define_expand "seq"
12360   [(set (match_operand:QI 0 "register_operand" "")
12361         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362   ""
12363   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12364
12365 (define_expand "sne"
12366   [(set (match_operand:QI 0 "register_operand" "")
12367         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12368   ""
12369   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12370
12371 (define_expand "sgt"
12372   [(set (match_operand:QI 0 "register_operand" "")
12373         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12374   ""
12375   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12376
12377 (define_expand "sgtu"
12378   [(set (match_operand:QI 0 "register_operand" "")
12379         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12380   ""
12381   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12382
12383 (define_expand "slt"
12384   [(set (match_operand:QI 0 "register_operand" "")
12385         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12386   ""
12387   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12388
12389 (define_expand "sltu"
12390   [(set (match_operand:QI 0 "register_operand" "")
12391         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12392   ""
12393   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12394
12395 (define_expand "sge"
12396   [(set (match_operand:QI 0 "register_operand" "")
12397         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12398   ""
12399   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12400
12401 (define_expand "sgeu"
12402   [(set (match_operand:QI 0 "register_operand" "")
12403         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12404   ""
12405   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12406
12407 (define_expand "sle"
12408   [(set (match_operand:QI 0 "register_operand" "")
12409         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12410   ""
12411   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12412
12413 (define_expand "sleu"
12414   [(set (match_operand:QI 0 "register_operand" "")
12415         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12416   ""
12417   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12418
12419 (define_expand "sunordered"
12420   [(set (match_operand:QI 0 "register_operand" "")
12421         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12422   "TARGET_80387 || TARGET_SSE"
12423   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12424
12425 (define_expand "sordered"
12426   [(set (match_operand:QI 0 "register_operand" "")
12427         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12428   "TARGET_80387"
12429   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12430
12431 (define_expand "suneq"
12432   [(set (match_operand:QI 0 "register_operand" "")
12433         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12434   "TARGET_80387 || TARGET_SSE"
12435   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12436
12437 (define_expand "sunge"
12438   [(set (match_operand:QI 0 "register_operand" "")
12439         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12440   "TARGET_80387 || TARGET_SSE"
12441   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12442
12443 (define_expand "sungt"
12444   [(set (match_operand:QI 0 "register_operand" "")
12445         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12446   "TARGET_80387 || TARGET_SSE"
12447   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12448
12449 (define_expand "sunle"
12450   [(set (match_operand:QI 0 "register_operand" "")
12451         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12452   "TARGET_80387 || TARGET_SSE"
12453   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12454
12455 (define_expand "sunlt"
12456   [(set (match_operand:QI 0 "register_operand" "")
12457         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12458   "TARGET_80387 || TARGET_SSE"
12459   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12460
12461 (define_expand "sltgt"
12462   [(set (match_operand:QI 0 "register_operand" "")
12463         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12464   "TARGET_80387 || TARGET_SSE"
12465   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12466
12467 (define_insn "*setcc_1"
12468   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12469         (match_operator:QI 1 "ix86_comparison_operator"
12470           [(reg FLAGS_REG) (const_int 0)]))]
12471   ""
12472   "set%C1\t%0"
12473   [(set_attr "type" "setcc")
12474    (set_attr "mode" "QI")])
12475
12476 (define_insn "*setcc_2"
12477   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12478         (match_operator:QI 1 "ix86_comparison_operator"
12479           [(reg FLAGS_REG) (const_int 0)]))]
12480   ""
12481   "set%C1\t%0"
12482   [(set_attr "type" "setcc")
12483    (set_attr "mode" "QI")])
12484
12485 ;; In general it is not safe to assume too much about CCmode registers,
12486 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12487 ;; conditions this is safe on x86, so help combine not create
12488 ;;
12489 ;;      seta    %al
12490 ;;      testb   %al, %al
12491 ;;      sete    %al
12492
12493 (define_split 
12494   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12495         (ne:QI (match_operator 1 "ix86_comparison_operator"
12496                  [(reg FLAGS_REG) (const_int 0)])
12497             (const_int 0)))]
12498   ""
12499   [(set (match_dup 0) (match_dup 1))]
12500 {
12501   PUT_MODE (operands[1], QImode);
12502 })
12503
12504 (define_split 
12505   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12506         (ne:QI (match_operator 1 "ix86_comparison_operator"
12507                  [(reg FLAGS_REG) (const_int 0)])
12508             (const_int 0)))]
12509   ""
12510   [(set (match_dup 0) (match_dup 1))]
12511 {
12512   PUT_MODE (operands[1], QImode);
12513 })
12514
12515 (define_split 
12516   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12517         (eq:QI (match_operator 1 "ix86_comparison_operator"
12518                  [(reg FLAGS_REG) (const_int 0)])
12519             (const_int 0)))]
12520   ""
12521   [(set (match_dup 0) (match_dup 1))]
12522 {
12523   rtx new_op1 = copy_rtx (operands[1]);
12524   operands[1] = new_op1;
12525   PUT_MODE (new_op1, QImode);
12526   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12527                                              GET_MODE (XEXP (new_op1, 0))));
12528
12529   /* Make sure that (a) the CCmode we have for the flags is strong
12530      enough for the reversed compare or (b) we have a valid FP compare.  */
12531   if (! ix86_comparison_operator (new_op1, VOIDmode))
12532     FAIL;
12533 })
12534
12535 (define_split 
12536   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12537         (eq:QI (match_operator 1 "ix86_comparison_operator"
12538                  [(reg FLAGS_REG) (const_int 0)])
12539             (const_int 0)))]
12540   ""
12541   [(set (match_dup 0) (match_dup 1))]
12542 {
12543   rtx new_op1 = copy_rtx (operands[1]);
12544   operands[1] = new_op1;
12545   PUT_MODE (new_op1, QImode);
12546   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12547                                              GET_MODE (XEXP (new_op1, 0))));
12548
12549   /* Make sure that (a) the CCmode we have for the flags is strong
12550      enough for the reversed compare or (b) we have a valid FP compare.  */
12551   if (! ix86_comparison_operator (new_op1, VOIDmode))
12552     FAIL;
12553 })
12554
12555 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12556 ;; subsequent logical operations are used to imitate conditional moves.
12557 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12558 ;; it directly.  Further holding this value in pseudo register might bring
12559 ;; problem in implicit normalization in spill code.
12560 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12561 ;; instructions after reload by splitting the conditional move patterns.
12562
12563 (define_insn "*sse_setccsf"
12564   [(set (match_operand:SF 0 "register_operand" "=x")
12565         (match_operator:SF 1 "sse_comparison_operator"
12566           [(match_operand:SF 2 "register_operand" "0")
12567            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12568   "TARGET_SSE && reload_completed"
12569   "cmp%D1ss\t{%3, %0|%0, %3}"
12570   [(set_attr "type" "ssecmp")
12571    (set_attr "mode" "SF")])
12572
12573 (define_insn "*sse_setccdf"
12574   [(set (match_operand:DF 0 "register_operand" "=Y")
12575         (match_operator:DF 1 "sse_comparison_operator"
12576           [(match_operand:DF 2 "register_operand" "0")
12577            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12578   "TARGET_SSE2 && reload_completed"
12579   "cmp%D1sd\t{%3, %0|%0, %3}"
12580   [(set_attr "type" "ssecmp")
12581    (set_attr "mode" "DF")])
12582 \f
12583 ;; Basic conditional jump instructions.
12584 ;; We ignore the overflow flag for signed branch instructions.
12585
12586 ;; For all bCOND expanders, also expand the compare or test insn that
12587 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12588
12589 (define_expand "beq"
12590   [(set (pc)
12591         (if_then_else (match_dup 1)
12592                       (label_ref (match_operand 0 "" ""))
12593                       (pc)))]
12594   ""
12595   "ix86_expand_branch (EQ, operands[0]); DONE;")
12596
12597 (define_expand "bne"
12598   [(set (pc)
12599         (if_then_else (match_dup 1)
12600                       (label_ref (match_operand 0 "" ""))
12601                       (pc)))]
12602   ""
12603   "ix86_expand_branch (NE, operands[0]); DONE;")
12604
12605 (define_expand "bgt"
12606   [(set (pc)
12607         (if_then_else (match_dup 1)
12608                       (label_ref (match_operand 0 "" ""))
12609                       (pc)))]
12610   ""
12611   "ix86_expand_branch (GT, operands[0]); DONE;")
12612
12613 (define_expand "bgtu"
12614   [(set (pc)
12615         (if_then_else (match_dup 1)
12616                       (label_ref (match_operand 0 "" ""))
12617                       (pc)))]
12618   ""
12619   "ix86_expand_branch (GTU, operands[0]); DONE;")
12620
12621 (define_expand "blt"
12622   [(set (pc)
12623         (if_then_else (match_dup 1)
12624                       (label_ref (match_operand 0 "" ""))
12625                       (pc)))]
12626   ""
12627   "ix86_expand_branch (LT, operands[0]); DONE;")
12628
12629 (define_expand "bltu"
12630   [(set (pc)
12631         (if_then_else (match_dup 1)
12632                       (label_ref (match_operand 0 "" ""))
12633                       (pc)))]
12634   ""
12635   "ix86_expand_branch (LTU, operands[0]); DONE;")
12636
12637 (define_expand "bge"
12638   [(set (pc)
12639         (if_then_else (match_dup 1)
12640                       (label_ref (match_operand 0 "" ""))
12641                       (pc)))]
12642   ""
12643   "ix86_expand_branch (GE, operands[0]); DONE;")
12644
12645 (define_expand "bgeu"
12646   [(set (pc)
12647         (if_then_else (match_dup 1)
12648                       (label_ref (match_operand 0 "" ""))
12649                       (pc)))]
12650   ""
12651   "ix86_expand_branch (GEU, operands[0]); DONE;")
12652
12653 (define_expand "ble"
12654   [(set (pc)
12655         (if_then_else (match_dup 1)
12656                       (label_ref (match_operand 0 "" ""))
12657                       (pc)))]
12658   ""
12659   "ix86_expand_branch (LE, operands[0]); DONE;")
12660
12661 (define_expand "bleu"
12662   [(set (pc)
12663         (if_then_else (match_dup 1)
12664                       (label_ref (match_operand 0 "" ""))
12665                       (pc)))]
12666   ""
12667   "ix86_expand_branch (LEU, operands[0]); DONE;")
12668
12669 (define_expand "bunordered"
12670   [(set (pc)
12671         (if_then_else (match_dup 1)
12672                       (label_ref (match_operand 0 "" ""))
12673                       (pc)))]
12674   "TARGET_80387 || TARGET_SSE"
12675   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12676
12677 (define_expand "bordered"
12678   [(set (pc)
12679         (if_then_else (match_dup 1)
12680                       (label_ref (match_operand 0 "" ""))
12681                       (pc)))]
12682   "TARGET_80387 || TARGET_SSE"
12683   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12684
12685 (define_expand "buneq"
12686   [(set (pc)
12687         (if_then_else (match_dup 1)
12688                       (label_ref (match_operand 0 "" ""))
12689                       (pc)))]
12690   "TARGET_80387 || TARGET_SSE"
12691   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12692
12693 (define_expand "bunge"
12694   [(set (pc)
12695         (if_then_else (match_dup 1)
12696                       (label_ref (match_operand 0 "" ""))
12697                       (pc)))]
12698   "TARGET_80387 || TARGET_SSE"
12699   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12700
12701 (define_expand "bungt"
12702   [(set (pc)
12703         (if_then_else (match_dup 1)
12704                       (label_ref (match_operand 0 "" ""))
12705                       (pc)))]
12706   "TARGET_80387 || TARGET_SSE"
12707   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12708
12709 (define_expand "bunle"
12710   [(set (pc)
12711         (if_then_else (match_dup 1)
12712                       (label_ref (match_operand 0 "" ""))
12713                       (pc)))]
12714   "TARGET_80387 || TARGET_SSE"
12715   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12716
12717 (define_expand "bunlt"
12718   [(set (pc)
12719         (if_then_else (match_dup 1)
12720                       (label_ref (match_operand 0 "" ""))
12721                       (pc)))]
12722   "TARGET_80387 || TARGET_SSE"
12723   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12724
12725 (define_expand "bltgt"
12726   [(set (pc)
12727         (if_then_else (match_dup 1)
12728                       (label_ref (match_operand 0 "" ""))
12729                       (pc)))]
12730   "TARGET_80387 || TARGET_SSE"
12731   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12732
12733 (define_insn "*jcc_1"
12734   [(set (pc)
12735         (if_then_else (match_operator 1 "ix86_comparison_operator"
12736                                       [(reg FLAGS_REG) (const_int 0)])
12737                       (label_ref (match_operand 0 "" ""))
12738                       (pc)))]
12739   ""
12740   "%+j%C1\t%l0"
12741   [(set_attr "type" "ibr")
12742    (set_attr "modrm" "0")
12743    (set (attr "length")
12744            (if_then_else (and (ge (minus (match_dup 0) (pc))
12745                                   (const_int -126))
12746                               (lt (minus (match_dup 0) (pc))
12747                                   (const_int 128)))
12748              (const_int 2)
12749              (const_int 6)))])
12750
12751 (define_insn "*jcc_2"
12752   [(set (pc)
12753         (if_then_else (match_operator 1 "ix86_comparison_operator"
12754                                       [(reg FLAGS_REG) (const_int 0)])
12755                       (pc)
12756                       (label_ref (match_operand 0 "" ""))))]
12757   ""
12758   "%+j%c1\t%l0"
12759   [(set_attr "type" "ibr")
12760    (set_attr "modrm" "0")
12761    (set (attr "length")
12762            (if_then_else (and (ge (minus (match_dup 0) (pc))
12763                                   (const_int -126))
12764                               (lt (minus (match_dup 0) (pc))
12765                                   (const_int 128)))
12766              (const_int 2)
12767              (const_int 6)))])
12768
12769 ;; In general it is not safe to assume too much about CCmode registers,
12770 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12771 ;; conditions this is safe on x86, so help combine not create
12772 ;;
12773 ;;      seta    %al
12774 ;;      testb   %al, %al
12775 ;;      je      Lfoo
12776
12777 (define_split 
12778   [(set (pc)
12779         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12780                                       [(reg FLAGS_REG) (const_int 0)])
12781                           (const_int 0))
12782                       (label_ref (match_operand 1 "" ""))
12783                       (pc)))]
12784   ""
12785   [(set (pc)
12786         (if_then_else (match_dup 0)
12787                       (label_ref (match_dup 1))
12788                       (pc)))]
12789 {
12790   PUT_MODE (operands[0], VOIDmode);
12791 })
12792   
12793 (define_split 
12794   [(set (pc)
12795         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12796                                       [(reg FLAGS_REG) (const_int 0)])
12797                           (const_int 0))
12798                       (label_ref (match_operand 1 "" ""))
12799                       (pc)))]
12800   ""
12801   [(set (pc)
12802         (if_then_else (match_dup 0)
12803                       (label_ref (match_dup 1))
12804                       (pc)))]
12805 {
12806   rtx new_op0 = copy_rtx (operands[0]);
12807   operands[0] = new_op0;
12808   PUT_MODE (new_op0, VOIDmode);
12809   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12810                                              GET_MODE (XEXP (new_op0, 0))));
12811
12812   /* Make sure that (a) the CCmode we have for the flags is strong
12813      enough for the reversed compare or (b) we have a valid FP compare.  */
12814   if (! ix86_comparison_operator (new_op0, VOIDmode))
12815     FAIL;
12816 })
12817
12818 ;; Define combination compare-and-branch fp compare instructions to use
12819 ;; during early optimization.  Splitting the operation apart early makes
12820 ;; for bad code when we want to reverse the operation.
12821
12822 (define_insn "*fp_jcc_1"
12823   [(set (pc)
12824         (if_then_else (match_operator 0 "comparison_operator"
12825                         [(match_operand 1 "register_operand" "f")
12826                          (match_operand 2 "register_operand" "f")])
12827           (label_ref (match_operand 3 "" ""))
12828           (pc)))
12829    (clobber (reg:CCFP FPSR_REG))
12830    (clobber (reg:CCFP FLAGS_REG))]
12831   "TARGET_CMOVE && TARGET_80387
12832    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12833    && FLOAT_MODE_P (GET_MODE (operands[1]))
12834    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12835    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12836   "#")
12837
12838 (define_insn "*fp_jcc_1_sse"
12839   [(set (pc)
12840         (if_then_else (match_operator 0 "comparison_operator"
12841                         [(match_operand 1 "register_operand" "f#x,x#f")
12842                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12843           (label_ref (match_operand 3 "" ""))
12844           (pc)))
12845    (clobber (reg:CCFP FPSR_REG))
12846    (clobber (reg:CCFP FLAGS_REG))]
12847   "TARGET_80387
12848    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12849    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12850    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12851   "#")
12852
12853 (define_insn "*fp_jcc_1_sse_only"
12854   [(set (pc)
12855         (if_then_else (match_operator 0 "comparison_operator"
12856                         [(match_operand 1 "register_operand" "x")
12857                          (match_operand 2 "nonimmediate_operand" "xm")])
12858           (label_ref (match_operand 3 "" ""))
12859           (pc)))
12860    (clobber (reg:CCFP FPSR_REG))
12861    (clobber (reg:CCFP FLAGS_REG))]
12862   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12863    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12864    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12865   "#")
12866
12867 (define_insn "*fp_jcc_2"
12868   [(set (pc)
12869         (if_then_else (match_operator 0 "comparison_operator"
12870                         [(match_operand 1 "register_operand" "f")
12871                          (match_operand 2 "register_operand" "f")])
12872           (pc)
12873           (label_ref (match_operand 3 "" ""))))
12874    (clobber (reg:CCFP FPSR_REG))
12875    (clobber (reg:CCFP FLAGS_REG))]
12876   "TARGET_CMOVE && TARGET_80387
12877    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12878    && FLOAT_MODE_P (GET_MODE (operands[1]))
12879    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12880    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12881   "#")
12882
12883 (define_insn "*fp_jcc_2_sse"
12884   [(set (pc)
12885         (if_then_else (match_operator 0 "comparison_operator"
12886                         [(match_operand 1 "register_operand" "f#x,x#f")
12887                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12888           (pc)
12889           (label_ref (match_operand 3 "" ""))))
12890    (clobber (reg:CCFP FPSR_REG))
12891    (clobber (reg:CCFP FLAGS_REG))]
12892   "TARGET_80387
12893    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12894    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12895    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12896   "#")
12897
12898 (define_insn "*fp_jcc_2_sse_only"
12899   [(set (pc)
12900         (if_then_else (match_operator 0 "comparison_operator"
12901                         [(match_operand 1 "register_operand" "x")
12902                          (match_operand 2 "nonimmediate_operand" "xm")])
12903           (pc)
12904           (label_ref (match_operand 3 "" ""))))
12905    (clobber (reg:CCFP FPSR_REG))
12906    (clobber (reg:CCFP FLAGS_REG))]
12907   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12908    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12909    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12910   "#")
12911
12912 (define_insn "*fp_jcc_3"
12913   [(set (pc)
12914         (if_then_else (match_operator 0 "comparison_operator"
12915                         [(match_operand 1 "register_operand" "f")
12916                          (match_operand 2 "nonimmediate_operand" "fm")])
12917           (label_ref (match_operand 3 "" ""))
12918           (pc)))
12919    (clobber (reg:CCFP FPSR_REG))
12920    (clobber (reg:CCFP FLAGS_REG))
12921    (clobber (match_scratch:HI 4 "=a"))]
12922   "TARGET_80387
12923    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12924    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12925    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12926    && SELECT_CC_MODE (GET_CODE (operands[0]),
12927                       operands[1], operands[2]) == CCFPmode
12928    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12929   "#")
12930
12931 (define_insn "*fp_jcc_4"
12932   [(set (pc)
12933         (if_then_else (match_operator 0 "comparison_operator"
12934                         [(match_operand 1 "register_operand" "f")
12935                          (match_operand 2 "nonimmediate_operand" "fm")])
12936           (pc)
12937           (label_ref (match_operand 3 "" ""))))
12938    (clobber (reg:CCFP FPSR_REG))
12939    (clobber (reg:CCFP FLAGS_REG))
12940    (clobber (match_scratch:HI 4 "=a"))]
12941   "TARGET_80387
12942    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12943    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12944    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12945    && SELECT_CC_MODE (GET_CODE (operands[0]),
12946                       operands[1], operands[2]) == CCFPmode
12947    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12948   "#")
12949
12950 (define_insn "*fp_jcc_5"
12951   [(set (pc)
12952         (if_then_else (match_operator 0 "comparison_operator"
12953                         [(match_operand 1 "register_operand" "f")
12954                          (match_operand 2 "register_operand" "f")])
12955           (label_ref (match_operand 3 "" ""))
12956           (pc)))
12957    (clobber (reg:CCFP FPSR_REG))
12958    (clobber (reg:CCFP FLAGS_REG))
12959    (clobber (match_scratch:HI 4 "=a"))]
12960   "TARGET_80387
12961    && FLOAT_MODE_P (GET_MODE (operands[1]))
12962    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12963    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12964   "#")
12965
12966 (define_insn "*fp_jcc_6"
12967   [(set (pc)
12968         (if_then_else (match_operator 0 "comparison_operator"
12969                         [(match_operand 1 "register_operand" "f")
12970                          (match_operand 2 "register_operand" "f")])
12971           (pc)
12972           (label_ref (match_operand 3 "" ""))))
12973    (clobber (reg:CCFP FPSR_REG))
12974    (clobber (reg:CCFP FLAGS_REG))
12975    (clobber (match_scratch:HI 4 "=a"))]
12976   "TARGET_80387
12977    && FLOAT_MODE_P (GET_MODE (operands[1]))
12978    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12979    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12980   "#")
12981
12982 (define_insn "*fp_jcc_7"
12983   [(set (pc)
12984         (if_then_else (match_operator 0 "comparison_operator"
12985                         [(match_operand 1 "register_operand" "f")
12986                          (match_operand 2 "const_double_operand" "C")])
12987           (label_ref (match_operand 3 "" ""))
12988           (pc)))
12989    (clobber (reg:CCFP FPSR_REG))
12990    (clobber (reg:CCFP FLAGS_REG))
12991    (clobber (match_scratch:HI 4 "=a"))]
12992   "TARGET_80387
12993    && FLOAT_MODE_P (GET_MODE (operands[1]))
12994    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12995    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12996    && SELECT_CC_MODE (GET_CODE (operands[0]),
12997                       operands[1], operands[2]) == CCFPmode
12998    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12999   "#")
13000
13001 ;; The order of operands in *fp_jcc_8 is forced by combine in
13002 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13003 ;; with a precedence over other operators and is always put in the first
13004 ;; place. Swap condition and operands to match ficom instruction.
13005
13006 (define_insn "*fp_jcc_8"
13007   [(set (pc)
13008         (if_then_else (match_operator 0 "comparison_operator"
13009                         [(match_operator 1 "float_operator"
13010                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13011                            (match_operand 3 "register_operand" "f,f")])
13012           (label_ref (match_operand 4 "" ""))
13013           (pc)))
13014    (clobber (reg:CCFP FPSR_REG))
13015    (clobber (reg:CCFP FLAGS_REG))
13016    (clobber (match_scratch:HI 5 "=a,a"))]
13017   "TARGET_80387 && TARGET_USE_FIOP
13018    && FLOAT_MODE_P (GET_MODE (operands[3]))
13019    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13020    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13021    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13022    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13023   "#")
13024
13025 (define_split
13026   [(set (pc)
13027         (if_then_else (match_operator 0 "comparison_operator"
13028                         [(match_operand 1 "register_operand" "")
13029                          (match_operand 2 "nonimmediate_operand" "")])
13030           (match_operand 3 "" "")
13031           (match_operand 4 "" "")))
13032    (clobber (reg:CCFP FPSR_REG))
13033    (clobber (reg:CCFP FLAGS_REG))]
13034   "reload_completed"
13035   [(const_int 0)]
13036 {
13037   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13038                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13039   DONE;
13040 })
13041
13042 (define_split
13043   [(set (pc)
13044         (if_then_else (match_operator 0 "comparison_operator"
13045                         [(match_operand 1 "register_operand" "")
13046                          (match_operand 2 "general_operand" "")])
13047           (match_operand 3 "" "")
13048           (match_operand 4 "" "")))
13049    (clobber (reg:CCFP FPSR_REG))
13050    (clobber (reg:CCFP FLAGS_REG))
13051    (clobber (match_scratch:HI 5 "=a"))]
13052   "reload_completed"
13053   [(const_int 0)]
13054 {
13055   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13056                         operands[3], operands[4], operands[5], NULL_RTX);
13057   DONE;
13058 })
13059
13060 (define_split
13061   [(set (pc)
13062         (if_then_else (match_operator 0 "comparison_operator"
13063                         [(match_operator 1 "float_operator"
13064                            [(match_operand:SI 2 "memory_operand" "")])
13065                            (match_operand 3 "register_operand" "")])
13066           (match_operand 4 "" "")
13067           (match_operand 5 "" "")))
13068    (clobber (reg:CCFP FPSR_REG))
13069    (clobber (reg:CCFP FLAGS_REG))
13070    (clobber (match_scratch:HI 6 "=a"))]
13071   "reload_completed"
13072   [(const_int 0)]
13073 {
13074   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13075   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13076                         operands[3], operands[7],
13077                         operands[4], operands[5], operands[6], NULL_RTX);
13078   DONE;
13079 })
13080
13081 ;; %%% Kill this when reload knows how to do it.
13082 (define_split
13083   [(set (pc)
13084         (if_then_else (match_operator 0 "comparison_operator"
13085                         [(match_operator 1 "float_operator"
13086                            [(match_operand:SI 2 "register_operand" "")])
13087                            (match_operand 3 "register_operand" "")])
13088           (match_operand 4 "" "")
13089           (match_operand 5 "" "")))
13090    (clobber (reg:CCFP FPSR_REG))
13091    (clobber (reg:CCFP FLAGS_REG))
13092    (clobber (match_scratch:HI 6 "=a"))]
13093   "reload_completed"
13094   [(const_int 0)]
13095 {
13096   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13097   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13098   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13099                         operands[3], operands[7],
13100                         operands[4], operands[5], operands[6], operands[2]);
13101   DONE;
13102 })
13103 \f
13104 ;; Unconditional and other jump instructions
13105
13106 (define_insn "jump"
13107   [(set (pc)
13108         (label_ref (match_operand 0 "" "")))]
13109   ""
13110   "jmp\t%l0"
13111   [(set_attr "type" "ibr")
13112    (set (attr "length")
13113            (if_then_else (and (ge (minus (match_dup 0) (pc))
13114                                   (const_int -126))
13115                               (lt (minus (match_dup 0) (pc))
13116                                   (const_int 128)))
13117              (const_int 2)
13118              (const_int 5)))
13119    (set_attr "modrm" "0")])
13120
13121 (define_expand "indirect_jump"
13122   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13123   ""
13124   "")
13125
13126 (define_insn "*indirect_jump"
13127   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13128   "!TARGET_64BIT"
13129   "jmp\t%A0"
13130   [(set_attr "type" "ibr")
13131    (set_attr "length_immediate" "0")])
13132
13133 (define_insn "*indirect_jump_rtx64"
13134   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13135   "TARGET_64BIT"
13136   "jmp\t%A0"
13137   [(set_attr "type" "ibr")
13138    (set_attr "length_immediate" "0")])
13139
13140 (define_expand "tablejump"
13141   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13142               (use (label_ref (match_operand 1 "" "")))])]
13143   ""
13144 {
13145   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13146      relative.  Convert the relative address to an absolute address.  */
13147   if (flag_pic)
13148     {
13149       rtx op0, op1;
13150       enum rtx_code code;
13151
13152       if (TARGET_64BIT)
13153         {
13154           code = PLUS;
13155           op0 = operands[0];
13156           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13157         }
13158       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13159         {
13160           code = PLUS;
13161           op0 = operands[0];
13162           op1 = pic_offset_table_rtx;
13163         }
13164       else
13165         {
13166           code = MINUS;
13167           op0 = pic_offset_table_rtx;
13168           op1 = operands[0];
13169         }
13170
13171       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13172                                          OPTAB_DIRECT);
13173     }
13174 })
13175
13176 (define_insn "*tablejump_1"
13177   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13178    (use (label_ref (match_operand 1 "" "")))]
13179   "!TARGET_64BIT"
13180   "jmp\t%A0"
13181   [(set_attr "type" "ibr")
13182    (set_attr "length_immediate" "0")])
13183
13184 (define_insn "*tablejump_1_rtx64"
13185   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13186    (use (label_ref (match_operand 1 "" "")))]
13187   "TARGET_64BIT"
13188   "jmp\t%A0"
13189   [(set_attr "type" "ibr")
13190    (set_attr "length_immediate" "0")])
13191 \f
13192 ;; Loop instruction
13193 ;;
13194 ;; This is all complicated by the fact that since this is a jump insn
13195 ;; we must handle our own reloads.
13196
13197 (define_expand "doloop_end"
13198   [(use (match_operand 0 "" ""))        ; loop pseudo
13199    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13200    (use (match_operand 2 "" ""))        ; max iterations
13201    (use (match_operand 3 "" ""))        ; loop level 
13202    (use (match_operand 4 "" ""))]       ; label
13203   "!TARGET_64BIT && TARGET_USE_LOOP"
13204   "                                 
13205 {
13206   /* Only use cloop on innermost loops.  */
13207   if (INTVAL (operands[3]) > 1)
13208     FAIL;
13209   if (GET_MODE (operands[0]) != SImode)
13210     FAIL;
13211   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13212                                            operands[0]));
13213   DONE;
13214 }")
13215
13216 (define_insn "doloop_end_internal"
13217   [(set (pc)
13218         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13219                           (const_int 1))
13220                       (label_ref (match_operand 0 "" ""))
13221                       (pc)))
13222    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13223         (plus:SI (match_dup 1)
13224                  (const_int -1)))
13225    (clobber (match_scratch:SI 3 "=X,X,r"))
13226    (clobber (reg:CC FLAGS_REG))]
13227   "!TARGET_64BIT && TARGET_USE_LOOP
13228    && (reload_in_progress || reload_completed
13229        || register_operand (operands[2], VOIDmode))"
13230 {
13231   if (which_alternative != 0)
13232     return "#";
13233   if (get_attr_length (insn) == 2)
13234     return "%+loop\t%l0";
13235   else
13236     return "dec{l}\t%1\;%+jne\t%l0";
13237 }
13238   [(set (attr "length")
13239         (if_then_else (and (eq_attr "alternative" "0")
13240                            (and (ge (minus (match_dup 0) (pc))
13241                                     (const_int -126))
13242                                 (lt (minus (match_dup 0) (pc))
13243                                     (const_int 128))))
13244                       (const_int 2)
13245                       (const_int 16)))
13246    ;; We don't know the type before shorten branches.  Optimistically expect
13247    ;; the loop instruction to match.
13248    (set (attr "type") (const_string "ibr"))])
13249
13250 (define_split
13251   [(set (pc)
13252         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13253                           (const_int 1))
13254                       (match_operand 0 "" "")
13255                       (pc)))
13256    (set (match_dup 1)
13257         (plus:SI (match_dup 1)
13258                  (const_int -1)))
13259    (clobber (match_scratch:SI 2 ""))
13260    (clobber (reg:CC FLAGS_REG))]
13261   "!TARGET_64BIT && TARGET_USE_LOOP
13262    && reload_completed
13263    && REGNO (operands[1]) != 2"
13264   [(parallel [(set (reg:CCZ FLAGS_REG)
13265                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13266                                  (const_int 0)))
13267               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13268    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13269                            (match_dup 0)
13270                            (pc)))]
13271   "")
13272   
13273 (define_split
13274   [(set (pc)
13275         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13276                           (const_int 1))
13277                       (match_operand 0 "" "")
13278                       (pc)))
13279    (set (match_operand:SI 2 "nonimmediate_operand" "")
13280         (plus:SI (match_dup 1)
13281                  (const_int -1)))
13282    (clobber (match_scratch:SI 3 ""))
13283    (clobber (reg:CC FLAGS_REG))]
13284   "!TARGET_64BIT && TARGET_USE_LOOP
13285    && reload_completed
13286    && (! REG_P (operands[2])
13287        || ! rtx_equal_p (operands[1], operands[2]))"
13288   [(set (match_dup 3) (match_dup 1))
13289    (parallel [(set (reg:CCZ FLAGS_REG)
13290                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13291                                 (const_int 0)))
13292               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13293    (set (match_dup 2) (match_dup 3))
13294    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13295                            (match_dup 0)
13296                            (pc)))]
13297   "")
13298
13299 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13300
13301 (define_peephole2
13302   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13303    (set (match_operand:QI 1 "register_operand" "")
13304         (match_operator:QI 2 "ix86_comparison_operator"
13305           [(reg FLAGS_REG) (const_int 0)]))
13306    (set (match_operand 3 "q_regs_operand" "")
13307         (zero_extend (match_dup 1)))]
13308   "(peep2_reg_dead_p (3, operands[1])
13309     || operands_match_p (operands[1], operands[3]))
13310    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13311   [(set (match_dup 4) (match_dup 0))
13312    (set (strict_low_part (match_dup 5))
13313         (match_dup 2))]
13314 {
13315   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13316   operands[5] = gen_lowpart (QImode, operands[3]);
13317   ix86_expand_clear (operands[3]);
13318 })
13319
13320 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13321
13322 (define_peephole2
13323   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13324    (set (match_operand:QI 1 "register_operand" "")
13325         (match_operator:QI 2 "ix86_comparison_operator"
13326           [(reg FLAGS_REG) (const_int 0)]))
13327    (parallel [(set (match_operand 3 "q_regs_operand" "")
13328                    (zero_extend (match_dup 1)))
13329               (clobber (reg:CC FLAGS_REG))])]
13330   "(peep2_reg_dead_p (3, operands[1])
13331     || operands_match_p (operands[1], operands[3]))
13332    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13333   [(set (match_dup 4) (match_dup 0))
13334    (set (strict_low_part (match_dup 5))
13335         (match_dup 2))]
13336 {
13337   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13338   operands[5] = gen_lowpart (QImode, operands[3]);
13339   ix86_expand_clear (operands[3]);
13340 })
13341 \f
13342 ;; Call instructions.
13343
13344 ;; The predicates normally associated with named expanders are not properly
13345 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13346 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13347
13348 ;; Call subroutine returning no value.
13349
13350 (define_expand "call_pop"
13351   [(parallel [(call (match_operand:QI 0 "" "")
13352                     (match_operand:SI 1 "" ""))
13353               (set (reg:SI SP_REG)
13354                    (plus:SI (reg:SI SP_REG)
13355                             (match_operand:SI 3 "" "")))])]
13356   "!TARGET_64BIT"
13357 {
13358   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13359   DONE;
13360 })
13361
13362 (define_insn "*call_pop_0"
13363   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13364          (match_operand:SI 1 "" ""))
13365    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13366                             (match_operand:SI 2 "immediate_operand" "")))]
13367   "!TARGET_64BIT"
13368 {
13369   if (SIBLING_CALL_P (insn))
13370     return "jmp\t%P0";
13371   else
13372     return "call\t%P0";
13373 }
13374   [(set_attr "type" "call")])
13375   
13376 (define_insn "*call_pop_1"
13377   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13378          (match_operand:SI 1 "" ""))
13379    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13380                             (match_operand:SI 2 "immediate_operand" "i")))]
13381   "!TARGET_64BIT"
13382 {
13383   if (constant_call_address_operand (operands[0], Pmode))
13384     {
13385       if (SIBLING_CALL_P (insn))
13386         return "jmp\t%P0";
13387       else
13388         return "call\t%P0";
13389     }
13390   if (SIBLING_CALL_P (insn))
13391     return "jmp\t%A0";
13392   else
13393     return "call\t%A0";
13394 }
13395   [(set_attr "type" "call")])
13396
13397 (define_expand "call"
13398   [(call (match_operand:QI 0 "" "")
13399          (match_operand 1 "" ""))
13400    (use (match_operand 2 "" ""))]
13401   ""
13402 {
13403   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13404   DONE;
13405 })
13406
13407 (define_expand "sibcall"
13408   [(call (match_operand:QI 0 "" "")
13409          (match_operand 1 "" ""))
13410    (use (match_operand 2 "" ""))]
13411   ""
13412 {
13413   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13414   DONE;
13415 })
13416
13417 (define_insn "*call_0"
13418   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13419          (match_operand 1 "" ""))]
13420   ""
13421 {
13422   if (SIBLING_CALL_P (insn))
13423     return "jmp\t%P0";
13424   else
13425     return "call\t%P0";
13426 }
13427   [(set_attr "type" "call")])
13428
13429 (define_insn "*call_1"
13430   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13431          (match_operand 1 "" ""))]
13432   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13433 {
13434   if (constant_call_address_operand (operands[0], Pmode))
13435     return "call\t%P0";
13436   return "call\t%A0";
13437 }
13438   [(set_attr "type" "call")])
13439
13440 (define_insn "*sibcall_1"
13441   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13442          (match_operand 1 "" ""))]
13443   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13444 {
13445   if (constant_call_address_operand (operands[0], Pmode))
13446     return "jmp\t%P0";
13447   return "jmp\t%A0";
13448 }
13449   [(set_attr "type" "call")])
13450
13451 (define_insn "*call_1_rex64"
13452   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13453          (match_operand 1 "" ""))]
13454   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13455 {
13456   if (constant_call_address_operand (operands[0], Pmode))
13457     return "call\t%P0";
13458   return "call\t%A0";
13459 }
13460   [(set_attr "type" "call")])
13461
13462 (define_insn "*sibcall_1_rex64"
13463   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13464          (match_operand 1 "" ""))]
13465   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13466   "jmp\t%P0"
13467   [(set_attr "type" "call")])
13468
13469 (define_insn "*sibcall_1_rex64_v"
13470   [(call (mem:QI (reg:DI 40))
13471          (match_operand 0 "" ""))]
13472   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13473   "jmp\t*%%r11"
13474   [(set_attr "type" "call")])
13475
13476
13477 ;; Call subroutine, returning value in operand 0
13478
13479 (define_expand "call_value_pop"
13480   [(parallel [(set (match_operand 0 "" "")
13481                    (call (match_operand:QI 1 "" "")
13482                          (match_operand:SI 2 "" "")))
13483               (set (reg:SI SP_REG)
13484                    (plus:SI (reg:SI SP_REG)
13485                             (match_operand:SI 4 "" "")))])]
13486   "!TARGET_64BIT"
13487 {
13488   ix86_expand_call (operands[0], operands[1], operands[2],
13489                     operands[3], operands[4], 0);
13490   DONE;
13491 })
13492
13493 (define_expand "call_value"
13494   [(set (match_operand 0 "" "")
13495         (call (match_operand:QI 1 "" "")
13496               (match_operand:SI 2 "" "")))
13497    (use (match_operand:SI 3 "" ""))]
13498   ;; Operand 2 not used on the i386.
13499   ""
13500 {
13501   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13502   DONE;
13503 })
13504
13505 (define_expand "sibcall_value"
13506   [(set (match_operand 0 "" "")
13507         (call (match_operand:QI 1 "" "")
13508               (match_operand:SI 2 "" "")))
13509    (use (match_operand:SI 3 "" ""))]
13510   ;; Operand 2 not used on the i386.
13511   ""
13512 {
13513   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13514   DONE;
13515 })
13516
13517 ;; Call subroutine returning any type.
13518
13519 (define_expand "untyped_call"
13520   [(parallel [(call (match_operand 0 "" "")
13521                     (const_int 0))
13522               (match_operand 1 "" "")
13523               (match_operand 2 "" "")])]
13524   ""
13525 {
13526   int i;
13527
13528   /* In order to give reg-stack an easier job in validating two
13529      coprocessor registers as containing a possible return value,
13530      simply pretend the untyped call returns a complex long double
13531      value.  */
13532
13533   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13534                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13535                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13536                     NULL, 0);
13537
13538   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13539     {
13540       rtx set = XVECEXP (operands[2], 0, i);
13541       emit_move_insn (SET_DEST (set), SET_SRC (set));
13542     }
13543
13544   /* The optimizer does not know that the call sets the function value
13545      registers we stored in the result block.  We avoid problems by
13546      claiming that all hard registers are used and clobbered at this
13547      point.  */
13548   emit_insn (gen_blockage (const0_rtx));
13549
13550   DONE;
13551 })
13552 \f
13553 ;; Prologue and epilogue instructions
13554
13555 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13556 ;; all of memory.  This blocks insns from being moved across this point.
13557
13558 (define_insn "blockage"
13559   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13560   ""
13561   ""
13562   [(set_attr "length" "0")])
13563
13564 ;; Insn emitted into the body of a function to return from a function.
13565 ;; This is only done if the function's epilogue is known to be simple.
13566 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13567
13568 (define_expand "return"
13569   [(return)]
13570   "ix86_can_use_return_insn_p ()"
13571 {
13572   if (current_function_pops_args)
13573     {
13574       rtx popc = GEN_INT (current_function_pops_args);
13575       emit_jump_insn (gen_return_pop_internal (popc));
13576       DONE;
13577     }
13578 })
13579
13580 (define_insn "return_internal"
13581   [(return)]
13582   "reload_completed"
13583   "ret"
13584   [(set_attr "length" "1")
13585    (set_attr "length_immediate" "0")
13586    (set_attr "modrm" "0")])
13587
13588 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13589 ;; instruction Athlon and K8 have.
13590
13591 (define_insn "return_internal_long"
13592   [(return)
13593    (unspec [(const_int 0)] UNSPEC_REP)]
13594   "reload_completed"
13595   "rep {;} ret"
13596   [(set_attr "length" "1")
13597    (set_attr "length_immediate" "0")
13598    (set_attr "prefix_rep" "1")
13599    (set_attr "modrm" "0")])
13600
13601 (define_insn "return_pop_internal"
13602   [(return)
13603    (use (match_operand:SI 0 "const_int_operand" ""))]
13604   "reload_completed"
13605   "ret\t%0"
13606   [(set_attr "length" "3")
13607    (set_attr "length_immediate" "2")
13608    (set_attr "modrm" "0")])
13609
13610 (define_insn "return_indirect_internal"
13611   [(return)
13612    (use (match_operand:SI 0 "register_operand" "r"))]
13613   "reload_completed"
13614   "jmp\t%A0"
13615   [(set_attr "type" "ibr")
13616    (set_attr "length_immediate" "0")])
13617
13618 (define_insn "nop"
13619   [(const_int 0)]
13620   ""
13621   "nop"
13622   [(set_attr "length" "1")
13623    (set_attr "length_immediate" "0")
13624    (set_attr "modrm" "0")])
13625
13626 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13627 ;; branch prediction penalty for the third jump in a 16-byte
13628 ;; block on K8.
13629
13630 (define_insn "align"
13631   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13632   ""
13633 {
13634 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13635   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13636 #else
13637   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13638      The align insn is used to avoid 3 jump instructions in the row to improve
13639      branch prediction and the benefits hardly outweight the cost of extra 8
13640      nops on the average inserted by full alignment pseudo operation.  */
13641 #endif
13642   return "";
13643 }
13644   [(set_attr "length" "16")])
13645
13646 (define_expand "prologue"
13647   [(const_int 1)]
13648   ""
13649   "ix86_expand_prologue (); DONE;")
13650
13651 (define_insn "set_got"
13652   [(set (match_operand:SI 0 "register_operand" "=r")
13653         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13654    (clobber (reg:CC FLAGS_REG))]
13655   "!TARGET_64BIT"
13656   { return output_set_got (operands[0]); }
13657   [(set_attr "type" "multi")
13658    (set_attr "length" "12")])
13659
13660 (define_expand "epilogue"
13661   [(const_int 1)]
13662   ""
13663   "ix86_expand_epilogue (1); DONE;")
13664
13665 (define_expand "sibcall_epilogue"
13666   [(const_int 1)]
13667   ""
13668   "ix86_expand_epilogue (0); DONE;")
13669
13670 (define_expand "eh_return"
13671   [(use (match_operand 0 "register_operand" ""))]
13672   ""
13673 {
13674   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13675
13676   /* Tricky bit: we write the address of the handler to which we will
13677      be returning into someone else's stack frame, one word below the
13678      stack address we wish to restore.  */
13679   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13680   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13681   tmp = gen_rtx_MEM (Pmode, tmp);
13682   emit_move_insn (tmp, ra);
13683
13684   if (Pmode == SImode)
13685     emit_jump_insn (gen_eh_return_si (sa));
13686   else
13687     emit_jump_insn (gen_eh_return_di (sa));
13688   emit_barrier ();
13689   DONE;
13690 })
13691
13692 (define_insn_and_split "eh_return_si"
13693   [(set (pc) 
13694         (unspec [(match_operand:SI 0 "register_operand" "c")]
13695                  UNSPEC_EH_RETURN))]
13696   "!TARGET_64BIT"
13697   "#"
13698   "reload_completed"
13699   [(const_int 1)]
13700   "ix86_expand_epilogue (2); DONE;")
13701
13702 (define_insn_and_split "eh_return_di"
13703   [(set (pc) 
13704         (unspec [(match_operand:DI 0 "register_operand" "c")]
13705                  UNSPEC_EH_RETURN))]
13706   "TARGET_64BIT"
13707   "#"
13708   "reload_completed"
13709   [(const_int 1)]
13710   "ix86_expand_epilogue (2); DONE;")
13711
13712 (define_insn "leave"
13713   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13714    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13715    (clobber (mem:BLK (scratch)))]
13716   "!TARGET_64BIT"
13717   "leave"
13718   [(set_attr "type" "leave")])
13719
13720 (define_insn "leave_rex64"
13721   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13722    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13723    (clobber (mem:BLK (scratch)))]
13724   "TARGET_64BIT"
13725   "leave"
13726   [(set_attr "type" "leave")])
13727 \f
13728 (define_expand "ffssi2"
13729   [(parallel
13730      [(set (match_operand:SI 0 "register_operand" "") 
13731            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13732       (clobber (match_scratch:SI 2 ""))
13733       (clobber (reg:CC FLAGS_REG))])]
13734   ""
13735   "")
13736
13737 (define_insn_and_split "*ffs_cmove"
13738   [(set (match_operand:SI 0 "register_operand" "=r") 
13739         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13740    (clobber (match_scratch:SI 2 "=&r"))
13741    (clobber (reg:CC FLAGS_REG))]
13742   "TARGET_CMOVE"
13743   "#"
13744   "&& reload_completed"
13745   [(set (match_dup 2) (const_int -1))
13746    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13747               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13748    (set (match_dup 0) (if_then_else:SI
13749                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13750                         (match_dup 2)
13751                         (match_dup 0)))
13752    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13753               (clobber (reg:CC FLAGS_REG))])]
13754   "")
13755
13756 (define_insn_and_split "*ffs_no_cmove"
13757   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13758         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13759    (clobber (match_scratch:SI 2 "=&q"))
13760    (clobber (reg:CC FLAGS_REG))]
13761   ""
13762   "#"
13763   "reload_completed"
13764   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13765               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13766    (set (strict_low_part (match_dup 3))
13767         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13768    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13769               (clobber (reg:CC FLAGS_REG))])
13770    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13771               (clobber (reg:CC FLAGS_REG))])
13772    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13773               (clobber (reg:CC FLAGS_REG))])]
13774 {
13775   operands[3] = gen_lowpart (QImode, operands[2]);
13776   ix86_expand_clear (operands[2]);
13777 })
13778
13779 (define_insn "*ffssi_1"
13780   [(set (reg:CCZ FLAGS_REG)
13781         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13782                      (const_int 0)))
13783    (set (match_operand:SI 0 "register_operand" "=r")
13784         (ctz:SI (match_dup 1)))]
13785   ""
13786   "bsf{l}\t{%1, %0|%0, %1}"
13787   [(set_attr "prefix_0f" "1")])
13788
13789 (define_expand "ffsdi2"
13790   [(parallel
13791      [(set (match_operand:DI 0 "register_operand" "") 
13792            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13793       (clobber (match_scratch:DI 2 ""))
13794       (clobber (reg:CC FLAGS_REG))])]
13795   "TARGET_64BIT && TARGET_CMOVE"
13796   "")
13797
13798 (define_insn_and_split "*ffs_rex64"
13799   [(set (match_operand:DI 0 "register_operand" "=r") 
13800         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13801    (clobber (match_scratch:DI 2 "=&r"))
13802    (clobber (reg:CC FLAGS_REG))]
13803   "TARGET_64BIT && TARGET_CMOVE"
13804   "#"
13805   "&& reload_completed"
13806   [(set (match_dup 2) (const_int -1))
13807    (parallel [(set (reg:CCZ FLAGS_REG)
13808                    (compare:CCZ (match_dup 1) (const_int 0)))
13809               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13810    (set (match_dup 0) (if_then_else:DI
13811                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13812                         (match_dup 2)
13813                         (match_dup 0)))
13814    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13815               (clobber (reg:CC FLAGS_REG))])]
13816   "")
13817
13818 (define_insn "*ffsdi_1"
13819   [(set (reg:CCZ FLAGS_REG)
13820         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13821                      (const_int 0)))
13822    (set (match_operand:DI 0 "register_operand" "=r")
13823         (ctz:DI (match_dup 1)))]
13824   "TARGET_64BIT"
13825   "bsf{q}\t{%1, %0|%0, %1}"
13826   [(set_attr "prefix_0f" "1")])
13827
13828 (define_insn "ctzsi2"
13829   [(set (match_operand:SI 0 "register_operand" "=r")
13830         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13831    (clobber (reg:CC FLAGS_REG))]
13832   ""
13833   "bsf{l}\t{%1, %0|%0, %1}"
13834   [(set_attr "prefix_0f" "1")])
13835
13836 (define_insn "ctzdi2"
13837   [(set (match_operand:DI 0 "register_operand" "=r")
13838         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13839    (clobber (reg:CC FLAGS_REG))]
13840   "TARGET_64BIT"
13841   "bsf{q}\t{%1, %0|%0, %1}"
13842   [(set_attr "prefix_0f" "1")])
13843
13844 (define_expand "clzsi2"
13845   [(parallel
13846      [(set (match_operand:SI 0 "register_operand" "")
13847            (minus:SI (const_int 31)
13848                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13849       (clobber (reg:CC FLAGS_REG))])
13850    (parallel
13851      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13852       (clobber (reg:CC FLAGS_REG))])]
13853   ""
13854   "")
13855
13856 (define_insn "*bsr"
13857   [(set (match_operand:SI 0 "register_operand" "=r")
13858         (minus:SI (const_int 31)
13859                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13860    (clobber (reg:CC FLAGS_REG))]
13861   ""
13862   "bsr{l}\t{%1, %0|%0, %1}"
13863   [(set_attr "prefix_0f" "1")])
13864
13865 (define_expand "clzdi2"
13866   [(parallel
13867      [(set (match_operand:DI 0 "register_operand" "")
13868            (minus:DI (const_int 63)
13869                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13870       (clobber (reg:CC FLAGS_REG))])
13871    (parallel
13872      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13873       (clobber (reg:CC FLAGS_REG))])]
13874   "TARGET_64BIT"
13875   "")
13876
13877 (define_insn "*bsr_rex64"
13878   [(set (match_operand:DI 0 "register_operand" "=r")
13879         (minus:DI (const_int 63)
13880                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13881    (clobber (reg:CC FLAGS_REG))]
13882   "TARGET_64BIT"
13883   "bsr{q}\t{%1, %0|%0, %1}"
13884   [(set_attr "prefix_0f" "1")])
13885 \f
13886 ;; Thread-local storage patterns for ELF.
13887 ;;
13888 ;; Note that these code sequences must appear exactly as shown
13889 ;; in order to allow linker relaxation.
13890
13891 (define_insn "*tls_global_dynamic_32_gnu"
13892   [(set (match_operand:SI 0 "register_operand" "=a")
13893         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13894                     (match_operand:SI 2 "tls_symbolic_operand" "")
13895                     (match_operand:SI 3 "call_insn_operand" "")]
13896                     UNSPEC_TLS_GD))
13897    (clobber (match_scratch:SI 4 "=d"))
13898    (clobber (match_scratch:SI 5 "=c"))
13899    (clobber (reg:CC FLAGS_REG))]
13900   "!TARGET_64BIT && TARGET_GNU_TLS"
13901   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13902   [(set_attr "type" "multi")
13903    (set_attr "length" "12")])
13904
13905 (define_insn "*tls_global_dynamic_32_sun"
13906   [(set (match_operand:SI 0 "register_operand" "=a")
13907         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13908                     (match_operand:SI 2 "tls_symbolic_operand" "")
13909                     (match_operand:SI 3 "call_insn_operand" "")]
13910                     UNSPEC_TLS_GD))
13911    (clobber (match_scratch:SI 4 "=d"))
13912    (clobber (match_scratch:SI 5 "=c"))
13913    (clobber (reg:CC FLAGS_REG))]
13914   "!TARGET_64BIT && TARGET_SUN_TLS"
13915   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13916         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13917   [(set_attr "type" "multi")
13918    (set_attr "length" "14")])
13919
13920 (define_expand "tls_global_dynamic_32"
13921   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13922                    (unspec:SI
13923                     [(match_dup 2)
13924                      (match_operand:SI 1 "tls_symbolic_operand" "")
13925                      (match_dup 3)]
13926                     UNSPEC_TLS_GD))
13927               (clobber (match_scratch:SI 4 ""))
13928               (clobber (match_scratch:SI 5 ""))
13929               (clobber (reg:CC FLAGS_REG))])]
13930   ""
13931 {
13932   if (flag_pic)
13933     operands[2] = pic_offset_table_rtx;
13934   else
13935     {
13936       operands[2] = gen_reg_rtx (Pmode);
13937       emit_insn (gen_set_got (operands[2]));
13938     }
13939   operands[3] = ix86_tls_get_addr ();
13940 })
13941
13942 (define_insn "*tls_global_dynamic_64"
13943   [(set (match_operand:DI 0 "register_operand" "=a")
13944         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13945                       (match_operand:DI 3 "" "")))
13946    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13947               UNSPEC_TLS_GD)]
13948   "TARGET_64BIT"
13949   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13950   [(set_attr "type" "multi")
13951    (set_attr "length" "16")])
13952
13953 (define_expand "tls_global_dynamic_64"
13954   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13955                    (call (mem:QI (match_dup 2)) (const_int 0)))
13956               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13957                          UNSPEC_TLS_GD)])]
13958   ""
13959 {
13960   operands[2] = ix86_tls_get_addr ();
13961 })
13962
13963 (define_insn "*tls_local_dynamic_base_32_gnu"
13964   [(set (match_operand:SI 0 "register_operand" "=a")
13965         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13966                     (match_operand:SI 2 "call_insn_operand" "")]
13967                    UNSPEC_TLS_LD_BASE))
13968    (clobber (match_scratch:SI 3 "=d"))
13969    (clobber (match_scratch:SI 4 "=c"))
13970    (clobber (reg:CC FLAGS_REG))]
13971   "!TARGET_64BIT && TARGET_GNU_TLS"
13972   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13973   [(set_attr "type" "multi")
13974    (set_attr "length" "11")])
13975
13976 (define_insn "*tls_local_dynamic_base_32_sun"
13977   [(set (match_operand:SI 0 "register_operand" "=a")
13978         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13979                     (match_operand:SI 2 "call_insn_operand" "")]
13980                    UNSPEC_TLS_LD_BASE))
13981    (clobber (match_scratch:SI 3 "=d"))
13982    (clobber (match_scratch:SI 4 "=c"))
13983    (clobber (reg:CC FLAGS_REG))]
13984   "!TARGET_64BIT && TARGET_SUN_TLS"
13985   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13986         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13987   [(set_attr "type" "multi")
13988    (set_attr "length" "13")])
13989
13990 (define_expand "tls_local_dynamic_base_32"
13991   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13992                    (unspec:SI [(match_dup 1) (match_dup 2)]
13993                               UNSPEC_TLS_LD_BASE))
13994               (clobber (match_scratch:SI 3 ""))
13995               (clobber (match_scratch:SI 4 ""))
13996               (clobber (reg:CC FLAGS_REG))])]
13997   ""
13998 {
13999   if (flag_pic)
14000     operands[1] = pic_offset_table_rtx;
14001   else
14002     {
14003       operands[1] = gen_reg_rtx (Pmode);
14004       emit_insn (gen_set_got (operands[1]));
14005     }
14006   operands[2] = ix86_tls_get_addr ();
14007 })
14008
14009 (define_insn "*tls_local_dynamic_base_64"
14010   [(set (match_operand:DI 0 "register_operand" "=a")
14011         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14012                       (match_operand:DI 2 "" "")))
14013    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14014   "TARGET_64BIT"
14015   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14016   [(set_attr "type" "multi")
14017    (set_attr "length" "12")])
14018
14019 (define_expand "tls_local_dynamic_base_64"
14020   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14021                    (call (mem:QI (match_dup 1)) (const_int 0)))
14022               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14023   ""
14024 {
14025   operands[1] = ix86_tls_get_addr ();
14026 })
14027
14028 ;; Local dynamic of a single variable is a lose.  Show combine how
14029 ;; to convert that back to global dynamic.
14030
14031 (define_insn_and_split "*tls_local_dynamic_32_once"
14032   [(set (match_operand:SI 0 "register_operand" "=a")
14033         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14034                              (match_operand:SI 2 "call_insn_operand" "")]
14035                             UNSPEC_TLS_LD_BASE)
14036                  (const:SI (unspec:SI
14037                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14038                             UNSPEC_DTPOFF))))
14039    (clobber (match_scratch:SI 4 "=d"))
14040    (clobber (match_scratch:SI 5 "=c"))
14041    (clobber (reg:CC FLAGS_REG))]
14042   ""
14043   "#"
14044   ""
14045   [(parallel [(set (match_dup 0)
14046                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14047                               UNSPEC_TLS_GD))
14048               (clobber (match_dup 4))
14049               (clobber (match_dup 5))
14050               (clobber (reg:CC FLAGS_REG))])]
14051   "")
14052
14053 ;; Load and add the thread base pointer from %gs:0.
14054
14055 (define_insn "*load_tp_si"
14056   [(set (match_operand:SI 0 "register_operand" "=r")
14057         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14058   "!TARGET_64BIT"
14059   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14060   [(set_attr "type" "imov")
14061    (set_attr "modrm" "0")
14062    (set_attr "length" "7")
14063    (set_attr "memory" "load")
14064    (set_attr "imm_disp" "false")])
14065
14066 (define_insn "*add_tp_si"
14067   [(set (match_operand:SI 0 "register_operand" "=r")
14068         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14069                  (match_operand:SI 1 "register_operand" "0")))
14070    (clobber (reg:CC FLAGS_REG))]
14071   "!TARGET_64BIT"
14072   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14073   [(set_attr "type" "alu")
14074    (set_attr "modrm" "0")
14075    (set_attr "length" "7")
14076    (set_attr "memory" "load")
14077    (set_attr "imm_disp" "false")])
14078
14079 (define_insn "*load_tp_di"
14080   [(set (match_operand:DI 0 "register_operand" "=r")
14081         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14082   "TARGET_64BIT"
14083   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14084   [(set_attr "type" "imov")
14085    (set_attr "modrm" "0")
14086    (set_attr "length" "7")
14087    (set_attr "memory" "load")
14088    (set_attr "imm_disp" "false")])
14089
14090 (define_insn "*add_tp_di"
14091   [(set (match_operand:DI 0 "register_operand" "=r")
14092         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14093                  (match_operand:DI 1 "register_operand" "0")))
14094    (clobber (reg:CC FLAGS_REG))]
14095   "TARGET_64BIT"
14096   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14097   [(set_attr "type" "alu")
14098    (set_attr "modrm" "0")
14099    (set_attr "length" "7")
14100    (set_attr "memory" "load")
14101    (set_attr "imm_disp" "false")])
14102 \f
14103 ;; These patterns match the binary 387 instructions for addM3, subM3,
14104 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14105 ;; SFmode.  The first is the normal insn, the second the same insn but
14106 ;; with one operand a conversion, and the third the same insn but with
14107 ;; the other operand a conversion.  The conversion may be SFmode or
14108 ;; SImode if the target mode DFmode, but only SImode if the target mode
14109 ;; is SFmode.
14110
14111 ;; Gcc is slightly more smart about handling normal two address instructions
14112 ;; so use special patterns for add and mull.
14113 (define_insn "*fop_sf_comm_nosse"
14114   [(set (match_operand:SF 0 "register_operand" "=f")
14115         (match_operator:SF 3 "binary_fp_operator"
14116                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14117                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14118   "TARGET_80387 && !TARGET_SSE_MATH
14119    && COMMUTATIVE_ARITH_P (operands[3])
14120    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14121   "* return output_387_binary_op (insn, operands);"
14122   [(set (attr "type") 
14123         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14124            (const_string "fmul")
14125            (const_string "fop")))
14126    (set_attr "mode" "SF")])
14127
14128 (define_insn "*fop_sf_comm"
14129   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14130         (match_operator:SF 3 "binary_fp_operator"
14131                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14132                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14133   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14134    && COMMUTATIVE_ARITH_P (operands[3])
14135    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14136   "* return output_387_binary_op (insn, operands);"
14137   [(set (attr "type") 
14138         (if_then_else (eq_attr "alternative" "1")
14139            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14140               (const_string "ssemul")
14141               (const_string "sseadd"))
14142            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14143               (const_string "fmul")
14144               (const_string "fop"))))
14145    (set_attr "mode" "SF")])
14146
14147 (define_insn "*fop_sf_comm_sse"
14148   [(set (match_operand:SF 0 "register_operand" "=x")
14149         (match_operator:SF 3 "binary_fp_operator"
14150                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14151                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14152   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14153    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14154   "* return output_387_binary_op (insn, operands);"
14155   [(set (attr "type") 
14156         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14157            (const_string "ssemul")
14158            (const_string "sseadd")))
14159    (set_attr "mode" "SF")])
14160
14161 (define_insn "*fop_df_comm_nosse"
14162   [(set (match_operand:DF 0 "register_operand" "=f")
14163         (match_operator:DF 3 "binary_fp_operator"
14164                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14165                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14166   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14167    && COMMUTATIVE_ARITH_P (operands[3])
14168    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14169   "* return output_387_binary_op (insn, operands);"
14170   [(set (attr "type") 
14171         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14172            (const_string "fmul")
14173            (const_string "fop")))
14174    (set_attr "mode" "DF")])
14175
14176 (define_insn "*fop_df_comm"
14177   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14178         (match_operator:DF 3 "binary_fp_operator"
14179                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14180                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14181   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14182    && COMMUTATIVE_ARITH_P (operands[3])
14183    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14184   "* return output_387_binary_op (insn, operands);"
14185   [(set (attr "type") 
14186         (if_then_else (eq_attr "alternative" "1")
14187            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14188               (const_string "ssemul")
14189               (const_string "sseadd"))
14190            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14191               (const_string "fmul")
14192               (const_string "fop"))))
14193    (set_attr "mode" "DF")])
14194
14195 (define_insn "*fop_df_comm_sse"
14196   [(set (match_operand:DF 0 "register_operand" "=Y")
14197         (match_operator:DF 3 "binary_fp_operator"
14198                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14199                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14200   "TARGET_SSE2 && TARGET_SSE_MATH
14201    && COMMUTATIVE_ARITH_P (operands[3])
14202    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14203   "* return output_387_binary_op (insn, operands);"
14204   [(set (attr "type") 
14205         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14206            (const_string "ssemul")
14207            (const_string "sseadd")))
14208    (set_attr "mode" "DF")])
14209
14210 (define_insn "*fop_xf_comm"
14211   [(set (match_operand:XF 0 "register_operand" "=f")
14212         (match_operator:XF 3 "binary_fp_operator"
14213                         [(match_operand:XF 1 "register_operand" "%0")
14214                          (match_operand:XF 2 "register_operand" "f")]))]
14215   "TARGET_80387
14216    && COMMUTATIVE_ARITH_P (operands[3])"
14217   "* return output_387_binary_op (insn, operands);"
14218   [(set (attr "type") 
14219         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14220            (const_string "fmul")
14221            (const_string "fop")))
14222    (set_attr "mode" "XF")])
14223
14224 (define_insn "*fop_sf_1_nosse"
14225   [(set (match_operand:SF 0 "register_operand" "=f,f")
14226         (match_operator:SF 3 "binary_fp_operator"
14227                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14228                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14229   "TARGET_80387 && !TARGET_SSE_MATH
14230    && !COMMUTATIVE_ARITH_P (operands[3])
14231    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14232   "* return output_387_binary_op (insn, operands);"
14233   [(set (attr "type") 
14234         (cond [(match_operand:SF 3 "mult_operator" "") 
14235                  (const_string "fmul")
14236                (match_operand:SF 3 "div_operator" "") 
14237                  (const_string "fdiv")
14238               ]
14239               (const_string "fop")))
14240    (set_attr "mode" "SF")])
14241
14242 (define_insn "*fop_sf_1"
14243   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14244         (match_operator:SF 3 "binary_fp_operator"
14245                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14246                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14247   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14248    && !COMMUTATIVE_ARITH_P (operands[3])
14249    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14250   "* return output_387_binary_op (insn, operands);"
14251   [(set (attr "type") 
14252         (cond [(and (eq_attr "alternative" "2")
14253                     (match_operand:SF 3 "mult_operator" ""))
14254                  (const_string "ssemul")
14255                (and (eq_attr "alternative" "2")
14256                     (match_operand:SF 3 "div_operator" ""))
14257                  (const_string "ssediv")
14258                (eq_attr "alternative" "2")
14259                  (const_string "sseadd")
14260                (match_operand:SF 3 "mult_operator" "") 
14261                  (const_string "fmul")
14262                (match_operand:SF 3 "div_operator" "") 
14263                  (const_string "fdiv")
14264               ]
14265               (const_string "fop")))
14266    (set_attr "mode" "SF")])
14267
14268 (define_insn "*fop_sf_1_sse"
14269   [(set (match_operand:SF 0 "register_operand" "=x")
14270         (match_operator:SF 3 "binary_fp_operator"
14271                         [(match_operand:SF 1 "register_operand" "0")
14272                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14273   "TARGET_SSE_MATH
14274    && !COMMUTATIVE_ARITH_P (operands[3])"
14275   "* return output_387_binary_op (insn, operands);"
14276   [(set (attr "type") 
14277         (cond [(match_operand:SF 3 "mult_operator" "")
14278                  (const_string "ssemul")
14279                (match_operand:SF 3 "div_operator" "")
14280                  (const_string "ssediv")
14281               ]
14282               (const_string "sseadd")))
14283    (set_attr "mode" "SF")])
14284
14285 ;; ??? Add SSE splitters for these!
14286 (define_insn "*fop_sf_2"
14287   [(set (match_operand:SF 0 "register_operand" "=f,f")
14288         (match_operator:SF 3 "binary_fp_operator"
14289           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14290            (match_operand:SF 2 "register_operand" "0,0")]))]
14291   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14292   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14293   [(set (attr "type") 
14294         (cond [(match_operand:SF 3 "mult_operator" "") 
14295                  (const_string "fmul")
14296                (match_operand:SF 3 "div_operator" "") 
14297                  (const_string "fdiv")
14298               ]
14299               (const_string "fop")))
14300    (set_attr "fp_int_src" "true")
14301    (set_attr "mode" "SI")])
14302
14303 (define_insn "*fop_sf_3"
14304   [(set (match_operand:SF 0 "register_operand" "=f,f")
14305         (match_operator:SF 3 "binary_fp_operator"
14306           [(match_operand:SF 1 "register_operand" "0,0")
14307            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14308   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14309   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14310   [(set (attr "type") 
14311         (cond [(match_operand:SF 3 "mult_operator" "") 
14312                  (const_string "fmul")
14313                (match_operand:SF 3 "div_operator" "") 
14314                  (const_string "fdiv")
14315               ]
14316               (const_string "fop")))
14317    (set_attr "fp_int_src" "true")
14318    (set_attr "mode" "SI")])
14319
14320 (define_insn "*fop_df_1_nosse"
14321   [(set (match_operand:DF 0 "register_operand" "=f,f")
14322         (match_operator:DF 3 "binary_fp_operator"
14323                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14324                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14325   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14326    && !COMMUTATIVE_ARITH_P (operands[3])
14327    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14328   "* return output_387_binary_op (insn, operands);"
14329   [(set (attr "type") 
14330         (cond [(match_operand:DF 3 "mult_operator" "") 
14331                  (const_string "fmul")
14332                (match_operand:DF 3 "div_operator" "")
14333                  (const_string "fdiv")
14334               ]
14335               (const_string "fop")))
14336    (set_attr "mode" "DF")])
14337
14338
14339 (define_insn "*fop_df_1"
14340   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14341         (match_operator:DF 3 "binary_fp_operator"
14342                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14343                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14344   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14345    && !COMMUTATIVE_ARITH_P (operands[3])
14346    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14347   "* return output_387_binary_op (insn, operands);"
14348   [(set (attr "type") 
14349         (cond [(and (eq_attr "alternative" "2")
14350                     (match_operand:SF 3 "mult_operator" ""))
14351                  (const_string "ssemul")
14352                (and (eq_attr "alternative" "2")
14353                     (match_operand:SF 3 "div_operator" ""))
14354                  (const_string "ssediv")
14355                (eq_attr "alternative" "2")
14356                  (const_string "sseadd")
14357                (match_operand:DF 3 "mult_operator" "") 
14358                  (const_string "fmul")
14359                (match_operand:DF 3 "div_operator" "") 
14360                  (const_string "fdiv")
14361               ]
14362               (const_string "fop")))
14363    (set_attr "mode" "DF")])
14364
14365 (define_insn "*fop_df_1_sse"
14366   [(set (match_operand:DF 0 "register_operand" "=Y")
14367         (match_operator:DF 3 "binary_fp_operator"
14368                         [(match_operand:DF 1 "register_operand" "0")
14369                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14370   "TARGET_SSE2 && TARGET_SSE_MATH
14371    && !COMMUTATIVE_ARITH_P (operands[3])"
14372   "* return output_387_binary_op (insn, operands);"
14373   [(set_attr "mode" "DF")
14374    (set (attr "type") 
14375         (cond [(match_operand:SF 3 "mult_operator" "")
14376                  (const_string "ssemul")
14377                (match_operand:SF 3 "div_operator" "")
14378                  (const_string "ssediv")
14379               ]
14380               (const_string "sseadd")))])
14381
14382 ;; ??? Add SSE splitters for these!
14383 (define_insn "*fop_df_2"
14384   [(set (match_operand:DF 0 "register_operand" "=f,f")
14385         (match_operator:DF 3 "binary_fp_operator"
14386            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14387             (match_operand:DF 2 "register_operand" "0,0")]))]
14388   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14389   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14390   [(set (attr "type") 
14391         (cond [(match_operand:DF 3 "mult_operator" "") 
14392                  (const_string "fmul")
14393                (match_operand:DF 3 "div_operator" "") 
14394                  (const_string "fdiv")
14395               ]
14396               (const_string "fop")))
14397    (set_attr "fp_int_src" "true")
14398    (set_attr "mode" "SI")])
14399
14400 (define_insn "*fop_df_3"
14401   [(set (match_operand:DF 0 "register_operand" "=f,f")
14402         (match_operator:DF 3 "binary_fp_operator"
14403            [(match_operand:DF 1 "register_operand" "0,0")
14404             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14405   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14406   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14407   [(set (attr "type") 
14408         (cond [(match_operand:DF 3 "mult_operator" "") 
14409                  (const_string "fmul")
14410                (match_operand:DF 3 "div_operator" "") 
14411                  (const_string "fdiv")
14412               ]
14413               (const_string "fop")))
14414    (set_attr "fp_int_src" "true")
14415    (set_attr "mode" "SI")])
14416
14417 (define_insn "*fop_df_4"
14418   [(set (match_operand:DF 0 "register_operand" "=f,f")
14419         (match_operator:DF 3 "binary_fp_operator"
14420            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14421             (match_operand:DF 2 "register_operand" "0,f")]))]
14422   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14423    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14424   "* return output_387_binary_op (insn, operands);"
14425   [(set (attr "type") 
14426         (cond [(match_operand:DF 3 "mult_operator" "") 
14427                  (const_string "fmul")
14428                (match_operand:DF 3 "div_operator" "") 
14429                  (const_string "fdiv")
14430               ]
14431               (const_string "fop")))
14432    (set_attr "mode" "SF")])
14433
14434 (define_insn "*fop_df_5"
14435   [(set (match_operand:DF 0 "register_operand" "=f,f")
14436         (match_operator:DF 3 "binary_fp_operator"
14437           [(match_operand:DF 1 "register_operand" "0,f")
14438            (float_extend:DF
14439             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14440   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14441   "* return output_387_binary_op (insn, operands);"
14442   [(set (attr "type") 
14443         (cond [(match_operand:DF 3 "mult_operator" "") 
14444                  (const_string "fmul")
14445                (match_operand:DF 3 "div_operator" "") 
14446                  (const_string "fdiv")
14447               ]
14448               (const_string "fop")))
14449    (set_attr "mode" "SF")])
14450
14451 (define_insn "*fop_df_6"
14452   [(set (match_operand:DF 0 "register_operand" "=f,f")
14453         (match_operator:DF 3 "binary_fp_operator"
14454           [(float_extend:DF
14455             (match_operand:SF 1 "register_operand" "0,f"))
14456            (float_extend:DF
14457             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14458   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14459   "* return output_387_binary_op (insn, operands);"
14460   [(set (attr "type") 
14461         (cond [(match_operand:DF 3 "mult_operator" "") 
14462                  (const_string "fmul")
14463                (match_operand:DF 3 "div_operator" "") 
14464                  (const_string "fdiv")
14465               ]
14466               (const_string "fop")))
14467    (set_attr "mode" "SF")])
14468
14469 (define_insn "*fop_xf_1"
14470   [(set (match_operand:XF 0 "register_operand" "=f,f")
14471         (match_operator:XF 3 "binary_fp_operator"
14472                         [(match_operand:XF 1 "register_operand" "0,f")
14473                          (match_operand:XF 2 "register_operand" "f,0")]))]
14474   "TARGET_80387
14475    && !COMMUTATIVE_ARITH_P (operands[3])"
14476   "* return output_387_binary_op (insn, operands);"
14477   [(set (attr "type") 
14478         (cond [(match_operand:XF 3 "mult_operator" "") 
14479                  (const_string "fmul")
14480                (match_operand:XF 3 "div_operator" "") 
14481                  (const_string "fdiv")
14482               ]
14483               (const_string "fop")))
14484    (set_attr "mode" "XF")])
14485
14486 (define_insn "*fop_xf_2"
14487   [(set (match_operand:XF 0 "register_operand" "=f,f")
14488         (match_operator:XF 3 "binary_fp_operator"
14489            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14490             (match_operand:XF 2 "register_operand" "0,0")]))]
14491   "TARGET_80387 && TARGET_USE_FIOP"
14492   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14493   [(set (attr "type") 
14494         (cond [(match_operand:XF 3 "mult_operator" "") 
14495                  (const_string "fmul")
14496                (match_operand:XF 3 "div_operator" "") 
14497                  (const_string "fdiv")
14498               ]
14499               (const_string "fop")))
14500    (set_attr "fp_int_src" "true")
14501    (set_attr "mode" "SI")])
14502
14503 (define_insn "*fop_xf_3"
14504   [(set (match_operand:XF 0 "register_operand" "=f,f")
14505         (match_operator:XF 3 "binary_fp_operator"
14506           [(match_operand:XF 1 "register_operand" "0,0")
14507            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14508   "TARGET_80387 && TARGET_USE_FIOP"
14509   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14510   [(set (attr "type") 
14511         (cond [(match_operand:XF 3 "mult_operator" "") 
14512                  (const_string "fmul")
14513                (match_operand:XF 3 "div_operator" "") 
14514                  (const_string "fdiv")
14515               ]
14516               (const_string "fop")))
14517    (set_attr "fp_int_src" "true")
14518    (set_attr "mode" "SI")])
14519
14520 (define_insn "*fop_xf_4"
14521   [(set (match_operand:XF 0 "register_operand" "=f,f")
14522         (match_operator:XF 3 "binary_fp_operator"
14523            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14524             (match_operand:XF 2 "register_operand" "0,f")]))]
14525   "TARGET_80387"
14526   "* return output_387_binary_op (insn, operands);"
14527   [(set (attr "type") 
14528         (cond [(match_operand:XF 3 "mult_operator" "") 
14529                  (const_string "fmul")
14530                (match_operand:XF 3 "div_operator" "") 
14531                  (const_string "fdiv")
14532               ]
14533               (const_string "fop")))
14534    (set_attr "mode" "SF")])
14535
14536 (define_insn "*fop_xf_5"
14537   [(set (match_operand:XF 0 "register_operand" "=f,f")
14538         (match_operator:XF 3 "binary_fp_operator"
14539           [(match_operand:XF 1 "register_operand" "0,f")
14540            (float_extend:XF
14541             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14542   "TARGET_80387"
14543   "* return output_387_binary_op (insn, operands);"
14544   [(set (attr "type") 
14545         (cond [(match_operand:XF 3 "mult_operator" "") 
14546                  (const_string "fmul")
14547                (match_operand:XF 3 "div_operator" "") 
14548                  (const_string "fdiv")
14549               ]
14550               (const_string "fop")))
14551    (set_attr "mode" "SF")])
14552
14553 (define_insn "*fop_xf_6"
14554   [(set (match_operand:XF 0 "register_operand" "=f,f")
14555         (match_operator:XF 3 "binary_fp_operator"
14556           [(float_extend:XF
14557             (match_operand 1 "register_operand" "0,f"))
14558            (float_extend:XF
14559             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14560   "TARGET_80387"
14561   "* return output_387_binary_op (insn, operands);"
14562   [(set (attr "type") 
14563         (cond [(match_operand:XF 3 "mult_operator" "") 
14564                  (const_string "fmul")
14565                (match_operand:XF 3 "div_operator" "") 
14566                  (const_string "fdiv")
14567               ]
14568               (const_string "fop")))
14569    (set_attr "mode" "SF")])
14570
14571 (define_split
14572   [(set (match_operand 0 "register_operand" "")
14573         (match_operator 3 "binary_fp_operator"
14574            [(float (match_operand:SI 1 "register_operand" ""))
14575             (match_operand 2 "register_operand" "")]))]
14576   "TARGET_80387 && reload_completed
14577    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14578   [(const_int 0)]
14579
14580   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14581   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14582   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14583                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14584                                           GET_MODE (operands[3]),
14585                                           operands[4],
14586                                           operands[2])));
14587   ix86_free_from_memory (GET_MODE (operands[1]));
14588   DONE;
14589 })
14590
14591 (define_split
14592   [(set (match_operand 0 "register_operand" "")
14593         (match_operator 3 "binary_fp_operator"
14594            [(match_operand 1 "register_operand" "")
14595             (float (match_operand:SI 2 "register_operand" ""))]))]
14596   "TARGET_80387 && reload_completed
14597    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14598   [(const_int 0)]
14599 {
14600   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14601   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14602   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14603                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14604                                           GET_MODE (operands[3]),
14605                                           operands[1],
14606                                           operands[4])));
14607   ix86_free_from_memory (GET_MODE (operands[2]));
14608   DONE;
14609 })
14610 \f
14611 ;; FPU special functions.
14612
14613 (define_expand "sqrtsf2"
14614   [(set (match_operand:SF 0 "register_operand" "")
14615         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14616   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14617 {
14618   if (!TARGET_SSE_MATH)
14619     operands[1] = force_reg (SFmode, operands[1]);
14620 })
14621
14622 (define_insn "sqrtsf2_1"
14623   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14624         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14625   "TARGET_USE_FANCY_MATH_387
14626    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14627   "@
14628    fsqrt
14629    sqrtss\t{%1, %0|%0, %1}"
14630   [(set_attr "type" "fpspc,sse")
14631    (set_attr "mode" "SF,SF")
14632    (set_attr "athlon_decode" "direct,*")])
14633
14634 (define_insn "sqrtsf2_1_sse_only"
14635   [(set (match_operand:SF 0 "register_operand" "=x")
14636         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14637   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14638   "sqrtss\t{%1, %0|%0, %1}"
14639   [(set_attr "type" "sse")
14640    (set_attr "mode" "SF")
14641    (set_attr "athlon_decode" "*")])
14642
14643 (define_insn "sqrtsf2_i387"
14644   [(set (match_operand:SF 0 "register_operand" "=f")
14645         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14646   "TARGET_USE_FANCY_MATH_387
14647    && !TARGET_SSE_MATH"
14648   "fsqrt"
14649   [(set_attr "type" "fpspc")
14650    (set_attr "mode" "SF")
14651    (set_attr "athlon_decode" "direct")])
14652
14653 (define_expand "sqrtdf2"
14654   [(set (match_operand:DF 0 "register_operand" "")
14655         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14656   "TARGET_USE_FANCY_MATH_387
14657    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14658 {
14659   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14660     operands[1] = force_reg (DFmode, operands[1]);
14661 })
14662
14663 (define_insn "sqrtdf2_1"
14664   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14665         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14666   "TARGET_USE_FANCY_MATH_387
14667    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14668   "@
14669    fsqrt
14670    sqrtsd\t{%1, %0|%0, %1}"
14671   [(set_attr "type" "fpspc,sse")
14672    (set_attr "mode" "DF,DF")
14673    (set_attr "athlon_decode" "direct,*")])
14674
14675 (define_insn "sqrtdf2_1_sse_only"
14676   [(set (match_operand:DF 0 "register_operand" "=Y")
14677         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14678   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14679   "sqrtsd\t{%1, %0|%0, %1}"
14680   [(set_attr "type" "sse")
14681    (set_attr "mode" "DF")
14682    (set_attr "athlon_decode" "*")])
14683
14684 (define_insn "sqrtdf2_i387"
14685   [(set (match_operand:DF 0 "register_operand" "=f")
14686         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14687   "TARGET_USE_FANCY_MATH_387
14688    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14689   "fsqrt"
14690   [(set_attr "type" "fpspc")
14691    (set_attr "mode" "DF")
14692    (set_attr "athlon_decode" "direct")])
14693
14694 (define_insn "*sqrtextendsfdf2"
14695   [(set (match_operand:DF 0 "register_operand" "=f")
14696         (sqrt:DF (float_extend:DF
14697                   (match_operand:SF 1 "register_operand" "0"))))]
14698   "TARGET_USE_FANCY_MATH_387
14699    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14700   "fsqrt"
14701   [(set_attr "type" "fpspc")
14702    (set_attr "mode" "DF")
14703    (set_attr "athlon_decode" "direct")])
14704
14705 (define_insn "sqrtxf2"
14706   [(set (match_operand:XF 0 "register_operand" "=f")
14707         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14708   "TARGET_USE_FANCY_MATH_387 
14709    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14710   "fsqrt"
14711   [(set_attr "type" "fpspc")
14712    (set_attr "mode" "XF")
14713    (set_attr "athlon_decode" "direct")])
14714
14715 (define_insn "*sqrtextenddfxf2"
14716   [(set (match_operand:XF 0 "register_operand" "=f")
14717         (sqrt:XF (float_extend:XF
14718                   (match_operand:DF 1 "register_operand" "0"))))]
14719   "TARGET_USE_FANCY_MATH_387"
14720   "fsqrt"
14721   [(set_attr "type" "fpspc")
14722    (set_attr "mode" "XF")
14723    (set_attr "athlon_decode" "direct")])
14724
14725 (define_insn "*sqrtextendsfxf2"
14726   [(set (match_operand:XF 0 "register_operand" "=f")
14727         (sqrt:XF (float_extend:XF
14728                   (match_operand:SF 1 "register_operand" "0"))))]
14729   "TARGET_USE_FANCY_MATH_387"
14730   "fsqrt"
14731   [(set_attr "type" "fpspc")
14732    (set_attr "mode" "XF")
14733    (set_attr "athlon_decode" "direct")])
14734
14735 (define_insn "fpremxf4"
14736   [(set (match_operand:XF 0 "register_operand" "=f")
14737         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14738                     (match_operand:XF 3 "register_operand" "1")]
14739                    UNSPEC_FPREM_F))
14740    (set (match_operand:XF 1 "register_operand" "=u")
14741         (unspec:XF [(match_dup 2) (match_dup 3)]
14742                    UNSPEC_FPREM_U))
14743    (set (reg:CCFP FPSR_REG)
14744         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14745   "TARGET_USE_FANCY_MATH_387
14746    && flag_unsafe_math_optimizations"
14747   "fprem"
14748   [(set_attr "type" "fpspc")
14749    (set_attr "mode" "XF")])
14750
14751 (define_expand "fmodsf3"
14752   [(use (match_operand:SF 0 "register_operand" ""))
14753    (use (match_operand:SF 1 "register_operand" ""))
14754    (use (match_operand:SF 2 "register_operand" ""))]
14755   "TARGET_USE_FANCY_MATH_387
14756    && flag_unsafe_math_optimizations"
14757 {
14758   rtx label = gen_label_rtx ();
14759
14760   rtx op1 = gen_reg_rtx (XFmode);
14761   rtx op2 = gen_reg_rtx (XFmode);
14762
14763   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14764   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14765
14766   emit_label (label);
14767
14768   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14769   ix86_emit_fp_unordered_jump (label);
14770
14771   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14772   DONE;
14773 })
14774
14775 (define_expand "fmoddf3"
14776   [(use (match_operand:DF 0 "register_operand" ""))
14777    (use (match_operand:DF 1 "register_operand" ""))
14778    (use (match_operand:DF 2 "register_operand" ""))]
14779   "TARGET_USE_FANCY_MATH_387
14780    && flag_unsafe_math_optimizations"
14781 {
14782   rtx label = gen_label_rtx ();
14783
14784   rtx op1 = gen_reg_rtx (XFmode);
14785   rtx op2 = gen_reg_rtx (XFmode);
14786
14787   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14788   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14789
14790   emit_label (label);
14791
14792   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14793   ix86_emit_fp_unordered_jump (label);
14794
14795   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14796   DONE;
14797 })
14798
14799 (define_expand "fmodxf3"
14800   [(use (match_operand:XF 0 "register_operand" ""))
14801    (use (match_operand:XF 1 "register_operand" ""))
14802    (use (match_operand:XF 2 "register_operand" ""))]
14803   "TARGET_USE_FANCY_MATH_387
14804    && flag_unsafe_math_optimizations"
14805 {
14806   rtx label = gen_label_rtx ();
14807
14808   emit_label (label);
14809
14810   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14811                            operands[1], operands[2]));
14812   ix86_emit_fp_unordered_jump (label);
14813
14814   emit_move_insn (operands[0], operands[1]);
14815   DONE;
14816 })
14817
14818 (define_insn "fprem1xf4"
14819   [(set (match_operand:XF 0 "register_operand" "=f")
14820         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14821                     (match_operand:XF 3 "register_operand" "1")]
14822                    UNSPEC_FPREM1_F))
14823    (set (match_operand:XF 1 "register_operand" "=u")
14824         (unspec:XF [(match_dup 2) (match_dup 3)]
14825                    UNSPEC_FPREM1_U))
14826    (set (reg:CCFP FPSR_REG)
14827         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14828   "TARGET_USE_FANCY_MATH_387
14829    && flag_unsafe_math_optimizations"
14830   "fprem1"
14831   [(set_attr "type" "fpspc")
14832    (set_attr "mode" "XF")])
14833
14834 (define_expand "dremsf3"
14835   [(use (match_operand:SF 0 "register_operand" ""))
14836    (use (match_operand:SF 1 "register_operand" ""))
14837    (use (match_operand:SF 2 "register_operand" ""))]
14838   "TARGET_USE_FANCY_MATH_387
14839    && flag_unsafe_math_optimizations"
14840 {
14841   rtx label = gen_label_rtx ();
14842
14843   rtx op1 = gen_reg_rtx (XFmode);
14844   rtx op2 = gen_reg_rtx (XFmode);
14845
14846   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14847   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14848
14849   emit_label (label);
14850
14851   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14852   ix86_emit_fp_unordered_jump (label);
14853
14854   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14855   DONE;
14856 })
14857
14858 (define_expand "dremdf3"
14859   [(use (match_operand:DF 0 "register_operand" ""))
14860    (use (match_operand:DF 1 "register_operand" ""))
14861    (use (match_operand:DF 2 "register_operand" ""))]
14862   "TARGET_USE_FANCY_MATH_387
14863    && flag_unsafe_math_optimizations"
14864 {
14865   rtx label = gen_label_rtx ();
14866
14867   rtx op1 = gen_reg_rtx (XFmode);
14868   rtx op2 = gen_reg_rtx (XFmode);
14869
14870   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14871   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14872
14873   emit_label (label);
14874
14875   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14876   ix86_emit_fp_unordered_jump (label);
14877
14878   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14879   DONE;
14880 })
14881
14882 (define_expand "dremxf3"
14883   [(use (match_operand:XF 0 "register_operand" ""))
14884    (use (match_operand:XF 1 "register_operand" ""))
14885    (use (match_operand:XF 2 "register_operand" ""))]
14886   "TARGET_USE_FANCY_MATH_387
14887    && flag_unsafe_math_optimizations"
14888 {
14889   rtx label = gen_label_rtx ();
14890
14891   emit_label (label);
14892
14893   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14894                             operands[1], operands[2]));
14895   ix86_emit_fp_unordered_jump (label);
14896
14897   emit_move_insn (operands[0], operands[1]);
14898   DONE;
14899 })
14900
14901 (define_insn "*sindf2"
14902   [(set (match_operand:DF 0 "register_operand" "=f")
14903         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14904   "TARGET_USE_FANCY_MATH_387
14905    && flag_unsafe_math_optimizations"
14906   "fsin"
14907   [(set_attr "type" "fpspc")
14908    (set_attr "mode" "DF")])
14909
14910 (define_insn "*sinsf2"
14911   [(set (match_operand:SF 0 "register_operand" "=f")
14912         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14913   "TARGET_USE_FANCY_MATH_387
14914    && flag_unsafe_math_optimizations"
14915   "fsin"
14916   [(set_attr "type" "fpspc")
14917    (set_attr "mode" "SF")])
14918
14919 (define_insn "*sinextendsfdf2"
14920   [(set (match_operand:DF 0 "register_operand" "=f")
14921         (unspec:DF [(float_extend:DF
14922                      (match_operand:SF 1 "register_operand" "0"))]
14923                    UNSPEC_SIN))]
14924   "TARGET_USE_FANCY_MATH_387
14925    && flag_unsafe_math_optimizations"
14926   "fsin"
14927   [(set_attr "type" "fpspc")
14928    (set_attr "mode" "DF")])
14929
14930 (define_insn "*sinxf2"
14931   [(set (match_operand:XF 0 "register_operand" "=f")
14932         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14933   "TARGET_USE_FANCY_MATH_387
14934    && flag_unsafe_math_optimizations"
14935   "fsin"
14936   [(set_attr "type" "fpspc")
14937    (set_attr "mode" "XF")])
14938
14939 (define_insn "*cosdf2"
14940   [(set (match_operand:DF 0 "register_operand" "=f")
14941         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14942   "TARGET_USE_FANCY_MATH_387
14943    && flag_unsafe_math_optimizations"
14944   "fcos"
14945   [(set_attr "type" "fpspc")
14946    (set_attr "mode" "DF")])
14947
14948 (define_insn "*cossf2"
14949   [(set (match_operand:SF 0 "register_operand" "=f")
14950         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14951   "TARGET_USE_FANCY_MATH_387
14952    && flag_unsafe_math_optimizations"
14953   "fcos"
14954   [(set_attr "type" "fpspc")
14955    (set_attr "mode" "SF")])
14956
14957 (define_insn "*cosextendsfdf2"
14958   [(set (match_operand:DF 0 "register_operand" "=f")
14959         (unspec:DF [(float_extend:DF
14960                      (match_operand:SF 1 "register_operand" "0"))]
14961                    UNSPEC_COS))]
14962   "TARGET_USE_FANCY_MATH_387
14963    && flag_unsafe_math_optimizations"
14964   "fcos"
14965   [(set_attr "type" "fpspc")
14966    (set_attr "mode" "DF")])
14967
14968 (define_insn "*cosxf2"
14969   [(set (match_operand:XF 0 "register_operand" "=f")
14970         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14971   "TARGET_USE_FANCY_MATH_387
14972    && flag_unsafe_math_optimizations"
14973   "fcos"
14974   [(set_attr "type" "fpspc")
14975    (set_attr "mode" "XF")])
14976
14977 ;; With sincos pattern defined, sin and cos builtin function will be
14978 ;; expanded to sincos pattern with one of its outputs left unused. 
14979 ;; Cse pass  will detected, if two sincos patterns can be combined,
14980 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14981 ;; depending on the unused output.
14982
14983 (define_insn "sincosdf3"
14984   [(set (match_operand:DF 0 "register_operand" "=f")
14985         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14986                    UNSPEC_SINCOS_COS))
14987    (set (match_operand:DF 1 "register_operand" "=u")
14988         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14989   "TARGET_USE_FANCY_MATH_387
14990    && flag_unsafe_math_optimizations"
14991   "fsincos"
14992   [(set_attr "type" "fpspc")
14993    (set_attr "mode" "DF")])
14994
14995 (define_split
14996   [(set (match_operand:DF 0 "register_operand" "")
14997         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14998                    UNSPEC_SINCOS_COS))
14999    (set (match_operand:DF 1 "register_operand" "")
15000         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15001   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15002    && !reload_completed && !reload_in_progress"
15003   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15004   "")
15005
15006 (define_split
15007   [(set (match_operand:DF 0 "register_operand" "")
15008         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15009                    UNSPEC_SINCOS_COS))
15010    (set (match_operand:DF 1 "register_operand" "")
15011         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15012   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15013    && !reload_completed && !reload_in_progress"
15014   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15015   "")
15016
15017 (define_insn "sincossf3"
15018   [(set (match_operand:SF 0 "register_operand" "=f")
15019         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15020                    UNSPEC_SINCOS_COS))
15021    (set (match_operand:SF 1 "register_operand" "=u")
15022         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15023   "TARGET_USE_FANCY_MATH_387
15024    && flag_unsafe_math_optimizations"
15025   "fsincos"
15026   [(set_attr "type" "fpspc")
15027    (set_attr "mode" "SF")])
15028
15029 (define_split
15030   [(set (match_operand:SF 0 "register_operand" "")
15031         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15032                    UNSPEC_SINCOS_COS))
15033    (set (match_operand:SF 1 "register_operand" "")
15034         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15035   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15036    && !reload_completed && !reload_in_progress"
15037   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15038   "")
15039
15040 (define_split
15041   [(set (match_operand:SF 0 "register_operand" "")
15042         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15043                    UNSPEC_SINCOS_COS))
15044    (set (match_operand:SF 1 "register_operand" "")
15045         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15046   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15047    && !reload_completed && !reload_in_progress"
15048   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15049   "")
15050
15051 (define_insn "*sincosextendsfdf3"
15052   [(set (match_operand:DF 0 "register_operand" "=f")
15053         (unspec:DF [(float_extend:DF
15054                      (match_operand:SF 2 "register_operand" "0"))]
15055                    UNSPEC_SINCOS_COS))
15056    (set (match_operand:DF 1 "register_operand" "=u")
15057         (unspec:DF [(float_extend:DF
15058                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15059   "TARGET_USE_FANCY_MATH_387
15060    && flag_unsafe_math_optimizations"
15061   "fsincos"
15062   [(set_attr "type" "fpspc")
15063    (set_attr "mode" "DF")])
15064
15065 (define_split
15066   [(set (match_operand:DF 0 "register_operand" "")
15067         (unspec:DF [(float_extend:DF
15068                      (match_operand:SF 2 "register_operand" ""))]
15069                    UNSPEC_SINCOS_COS))
15070    (set (match_operand:DF 1 "register_operand" "")
15071         (unspec:DF [(float_extend:DF
15072                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15073   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15074    && !reload_completed && !reload_in_progress"
15075   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15076                                    (match_dup 2))] UNSPEC_SIN))]
15077   "")
15078
15079 (define_split
15080   [(set (match_operand:DF 0 "register_operand" "")
15081         (unspec:DF [(float_extend:DF
15082                      (match_operand:SF 2 "register_operand" ""))]
15083                    UNSPEC_SINCOS_COS))
15084    (set (match_operand:DF 1 "register_operand" "")
15085         (unspec:DF [(float_extend:DF
15086                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15087   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15088    && !reload_completed && !reload_in_progress"
15089   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15090                                    (match_dup 2))] UNSPEC_COS))]
15091   "")
15092
15093 (define_insn "sincosxf3"
15094   [(set (match_operand:XF 0 "register_operand" "=f")
15095         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15096                    UNSPEC_SINCOS_COS))
15097    (set (match_operand:XF 1 "register_operand" "=u")
15098         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15099   "TARGET_USE_FANCY_MATH_387
15100    && flag_unsafe_math_optimizations"
15101   "fsincos"
15102   [(set_attr "type" "fpspc")
15103    (set_attr "mode" "XF")])
15104
15105 (define_split
15106   [(set (match_operand:XF 0 "register_operand" "")
15107         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15108                    UNSPEC_SINCOS_COS))
15109    (set (match_operand:XF 1 "register_operand" "")
15110         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15111   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15112    && !reload_completed && !reload_in_progress"
15113   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15114   "")
15115
15116 (define_split
15117   [(set (match_operand:XF 0 "register_operand" "")
15118         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15119                    UNSPEC_SINCOS_COS))
15120    (set (match_operand:XF 1 "register_operand" "")
15121         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15122   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15123    && !reload_completed && !reload_in_progress"
15124   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15125   "")
15126
15127 (define_insn "*tandf3_1"
15128   [(set (match_operand:DF 0 "register_operand" "=f")
15129         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15130                    UNSPEC_TAN_ONE))
15131    (set (match_operand:DF 1 "register_operand" "=u")
15132         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15133   "TARGET_USE_FANCY_MATH_387
15134    && flag_unsafe_math_optimizations"
15135   "fptan"
15136   [(set_attr "type" "fpspc")
15137    (set_attr "mode" "DF")])
15138
15139 ;; optimize sequence: fptan
15140 ;;                    fstp    %st(0)
15141 ;;                    fld1
15142 ;; into fptan insn.
15143
15144 (define_peephole2
15145   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15146                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15147                              UNSPEC_TAN_ONE))
15148              (set (match_operand:DF 1 "register_operand" "")
15149                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15150    (set (match_dup 0)
15151         (match_operand:DF 3 "immediate_operand" ""))]
15152   "standard_80387_constant_p (operands[3]) == 2"
15153   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15154              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15155   "")
15156
15157 (define_expand "tandf2"
15158   [(parallel [(set (match_dup 2)
15159                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15160                               UNSPEC_TAN_ONE))
15161               (set (match_operand:DF 0 "register_operand" "")
15162                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15163   "TARGET_USE_FANCY_MATH_387
15164    && flag_unsafe_math_optimizations"
15165 {
15166   operands[2] = gen_reg_rtx (DFmode);
15167 })
15168
15169 (define_insn "*tansf3_1"
15170   [(set (match_operand:SF 0 "register_operand" "=f")
15171         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15172                    UNSPEC_TAN_ONE))
15173    (set (match_operand:SF 1 "register_operand" "=u")
15174         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15175   "TARGET_USE_FANCY_MATH_387
15176    && flag_unsafe_math_optimizations"
15177   "fptan"
15178   [(set_attr "type" "fpspc")
15179    (set_attr "mode" "SF")])
15180
15181 ;; optimize sequence: fptan
15182 ;;                    fstp    %st(0)
15183 ;;                    fld1
15184 ;; into fptan insn.
15185
15186 (define_peephole2
15187   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15188                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15189                              UNSPEC_TAN_ONE))
15190              (set (match_operand:SF 1 "register_operand" "")
15191                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15192    (set (match_dup 0)
15193         (match_operand:SF 3 "immediate_operand" ""))]
15194   "standard_80387_constant_p (operands[3]) == 2"
15195   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15196              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15197   "")
15198
15199 (define_expand "tansf2"
15200   [(parallel [(set (match_dup 2)
15201                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15202                               UNSPEC_TAN_ONE))
15203               (set (match_operand:SF 0 "register_operand" "")
15204                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15205   "TARGET_USE_FANCY_MATH_387
15206    && flag_unsafe_math_optimizations"
15207 {
15208   operands[2] = gen_reg_rtx (SFmode);
15209 })
15210
15211 (define_insn "*tanxf3_1"
15212   [(set (match_operand:XF 0 "register_operand" "=f")
15213         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15214                    UNSPEC_TAN_ONE))
15215    (set (match_operand:XF 1 "register_operand" "=u")
15216         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15217   "TARGET_USE_FANCY_MATH_387
15218    && flag_unsafe_math_optimizations"
15219   "fptan"
15220   [(set_attr "type" "fpspc")
15221    (set_attr "mode" "XF")])
15222
15223 ;; optimize sequence: fptan
15224 ;;                    fstp    %st(0)
15225 ;;                    fld1
15226 ;; into fptan insn.
15227
15228 (define_peephole2
15229   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15230                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15231                              UNSPEC_TAN_ONE))
15232              (set (match_operand:XF 1 "register_operand" "")
15233                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15234    (set (match_dup 0)
15235         (match_operand:XF 3 "immediate_operand" ""))]
15236   "standard_80387_constant_p (operands[3]) == 2"
15237   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15238              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15239   "")
15240
15241 (define_expand "tanxf2"
15242   [(parallel [(set (match_dup 2)
15243                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15244                               UNSPEC_TAN_ONE))
15245               (set (match_operand:XF 0 "register_operand" "")
15246                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15247   "TARGET_USE_FANCY_MATH_387
15248    && flag_unsafe_math_optimizations"
15249 {
15250   operands[2] = gen_reg_rtx (XFmode);
15251 })
15252
15253 (define_insn "atan2df3_1"
15254   [(set (match_operand:DF 0 "register_operand" "=f")
15255         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15256                     (match_operand:DF 1 "register_operand" "u")]
15257                    UNSPEC_FPATAN))
15258    (clobber (match_scratch:DF 3 "=1"))]
15259   "TARGET_USE_FANCY_MATH_387
15260    && flag_unsafe_math_optimizations"
15261   "fpatan"
15262   [(set_attr "type" "fpspc")
15263    (set_attr "mode" "DF")])
15264
15265 (define_expand "atan2df3"
15266   [(use (match_operand:DF 0 "register_operand" "=f"))
15267    (use (match_operand:DF 2 "register_operand" "0"))
15268    (use (match_operand:DF 1 "register_operand" "u"))]
15269   "TARGET_USE_FANCY_MATH_387
15270    && flag_unsafe_math_optimizations"
15271 {
15272   rtx copy = gen_reg_rtx (DFmode);
15273   emit_move_insn (copy, operands[1]);
15274   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15275   DONE;
15276 })
15277
15278 (define_expand "atandf2"
15279   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15280                    (unspec:DF [(match_dup 2)
15281                                (match_operand:DF 1 "register_operand" "")]
15282                     UNSPEC_FPATAN))
15283               (clobber (match_scratch:DF 3 ""))])]
15284   "TARGET_USE_FANCY_MATH_387
15285    && flag_unsafe_math_optimizations"
15286 {
15287   operands[2] = gen_reg_rtx (DFmode);
15288   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15289 })
15290
15291 (define_insn "atan2sf3_1"
15292   [(set (match_operand:SF 0 "register_operand" "=f")
15293         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15294                     (match_operand:SF 1 "register_operand" "u")]
15295                    UNSPEC_FPATAN))
15296    (clobber (match_scratch:SF 3 "=1"))]
15297   "TARGET_USE_FANCY_MATH_387
15298    && flag_unsafe_math_optimizations"
15299   "fpatan"
15300   [(set_attr "type" "fpspc")
15301    (set_attr "mode" "SF")])
15302
15303 (define_expand "atan2sf3"
15304   [(use (match_operand:SF 0 "register_operand" "=f"))
15305    (use (match_operand:SF 2 "register_operand" "0"))
15306    (use (match_operand:SF 1 "register_operand" "u"))]
15307   "TARGET_USE_FANCY_MATH_387
15308    && flag_unsafe_math_optimizations"
15309 {
15310   rtx copy = gen_reg_rtx (SFmode);
15311   emit_move_insn (copy, operands[1]);
15312   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15313   DONE;
15314 })
15315
15316 (define_expand "atansf2"
15317   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15318                    (unspec:SF [(match_dup 2)
15319                                (match_operand:SF 1 "register_operand" "")]
15320                     UNSPEC_FPATAN))
15321               (clobber (match_scratch:SF 3 ""))])]
15322   "TARGET_USE_FANCY_MATH_387
15323    && flag_unsafe_math_optimizations"
15324 {
15325   operands[2] = gen_reg_rtx (SFmode);
15326   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15327 })
15328
15329 (define_insn "atan2xf3_1"
15330   [(set (match_operand:XF 0 "register_operand" "=f")
15331         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15332                     (match_operand:XF 1 "register_operand" "u")]
15333                    UNSPEC_FPATAN))
15334    (clobber (match_scratch:XF 3 "=1"))]
15335   "TARGET_USE_FANCY_MATH_387
15336    && flag_unsafe_math_optimizations"
15337   "fpatan"
15338   [(set_attr "type" "fpspc")
15339    (set_attr "mode" "XF")])
15340
15341 (define_expand "atan2xf3"
15342   [(use (match_operand:XF 0 "register_operand" "=f"))
15343    (use (match_operand:XF 2 "register_operand" "0"))
15344    (use (match_operand:XF 1 "register_operand" "u"))]
15345   "TARGET_USE_FANCY_MATH_387
15346    && flag_unsafe_math_optimizations"
15347 {
15348   rtx copy = gen_reg_rtx (XFmode);
15349   emit_move_insn (copy, operands[1]);
15350   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15351   DONE;
15352 })
15353
15354 (define_expand "atanxf2"
15355   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15356                    (unspec:XF [(match_dup 2)
15357                                (match_operand:XF 1 "register_operand" "")]
15358                     UNSPEC_FPATAN))
15359               (clobber (match_scratch:XF 3 ""))])]
15360   "TARGET_USE_FANCY_MATH_387
15361    && flag_unsafe_math_optimizations"
15362 {
15363   operands[2] = gen_reg_rtx (XFmode);
15364   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15365 })
15366
15367 (define_expand "asindf2"
15368   [(set (match_dup 2)
15369         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15370    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15371    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15372    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15373    (parallel [(set (match_dup 7)
15374                    (unspec:XF [(match_dup 6) (match_dup 2)]
15375                               UNSPEC_FPATAN))
15376               (clobber (match_scratch:XF 8 ""))])
15377    (set (match_operand:DF 0 "register_operand" "")
15378         (float_truncate:DF (match_dup 7)))]
15379   "TARGET_USE_FANCY_MATH_387
15380    && flag_unsafe_math_optimizations"
15381 {
15382   int i;
15383
15384   for (i=2; i<8; i++)
15385     operands[i] = gen_reg_rtx (XFmode);
15386
15387   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15388 })
15389
15390 (define_expand "asinsf2"
15391   [(set (match_dup 2)
15392         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15393    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15394    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15395    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15396    (parallel [(set (match_dup 7)
15397                    (unspec:XF [(match_dup 6) (match_dup 2)]
15398                               UNSPEC_FPATAN))
15399               (clobber (match_scratch:XF 8 ""))])
15400    (set (match_operand:SF 0 "register_operand" "")
15401         (float_truncate:SF (match_dup 7)))]
15402   "TARGET_USE_FANCY_MATH_387
15403    && flag_unsafe_math_optimizations"
15404 {
15405   int i;
15406
15407   for (i=2; i<8; i++)
15408     operands[i] = gen_reg_rtx (XFmode);
15409
15410   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15411 })
15412
15413 (define_expand "asinxf2"
15414   [(set (match_dup 2)
15415         (mult:XF (match_operand:XF 1 "register_operand" "")
15416                  (match_dup 1)))
15417    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15418    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15419    (parallel [(set (match_operand:XF 0 "register_operand" "")
15420                    (unspec:XF [(match_dup 5) (match_dup 1)]
15421                               UNSPEC_FPATAN))
15422               (clobber (match_scratch:XF 6 ""))])]
15423   "TARGET_USE_FANCY_MATH_387
15424    && flag_unsafe_math_optimizations"
15425 {
15426   int i;
15427
15428   for (i=2; i<6; i++)
15429     operands[i] = gen_reg_rtx (XFmode);
15430
15431   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15432 })
15433
15434 (define_expand "acosdf2"
15435   [(set (match_dup 2)
15436         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15437    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15438    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15439    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15440    (parallel [(set (match_dup 7)
15441                    (unspec:XF [(match_dup 2) (match_dup 6)]
15442                               UNSPEC_FPATAN))
15443               (clobber (match_scratch:XF 8 ""))])
15444    (set (match_operand:DF 0 "register_operand" "")
15445         (float_truncate:DF (match_dup 7)))]
15446   "TARGET_USE_FANCY_MATH_387
15447    && flag_unsafe_math_optimizations"
15448 {
15449   int i;
15450
15451   for (i=2; i<8; i++)
15452     operands[i] = gen_reg_rtx (XFmode);
15453
15454   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15455 })
15456
15457 (define_expand "acossf2"
15458   [(set (match_dup 2)
15459         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15460    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15461    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15462    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15463    (parallel [(set (match_dup 7)
15464                    (unspec:XF [(match_dup 2) (match_dup 6)]
15465                               UNSPEC_FPATAN))
15466               (clobber (match_scratch:XF 8 ""))])
15467    (set (match_operand:SF 0 "register_operand" "")
15468         (float_truncate:SF (match_dup 7)))]
15469   "TARGET_USE_FANCY_MATH_387
15470    && flag_unsafe_math_optimizations"
15471 {
15472   int i;
15473
15474   for (i=2; i<8; i++)
15475     operands[i] = gen_reg_rtx (XFmode);
15476
15477   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15478 })
15479
15480 (define_expand "acosxf2"
15481   [(set (match_dup 2)
15482         (mult:XF (match_operand:XF 1 "register_operand" "")
15483                  (match_dup 1)))
15484    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15485    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15486    (parallel [(set (match_operand:XF 0 "register_operand" "")
15487                    (unspec:XF [(match_dup 1) (match_dup 5)]
15488                               UNSPEC_FPATAN))
15489               (clobber (match_scratch:XF 6 ""))])]
15490   "TARGET_USE_FANCY_MATH_387
15491    && flag_unsafe_math_optimizations"
15492 {
15493   int i;
15494
15495   for (i=2; i<6; i++)
15496     operands[i] = gen_reg_rtx (XFmode);
15497
15498   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15499 })
15500
15501 (define_insn "fyl2x_xf3"
15502   [(set (match_operand:XF 0 "register_operand" "=f")
15503         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15504                     (match_operand:XF 1 "register_operand" "u")]
15505                    UNSPEC_FYL2X))
15506    (clobber (match_scratch:XF 3 "=1"))]
15507   "TARGET_USE_FANCY_MATH_387
15508    && flag_unsafe_math_optimizations"
15509   "fyl2x"
15510   [(set_attr "type" "fpspc")
15511    (set_attr "mode" "XF")])
15512
15513 (define_expand "logsf2"
15514   [(set (match_dup 2)
15515         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15516    (parallel [(set (match_dup 4)
15517                    (unspec:XF [(match_dup 2)
15518                                (match_dup 3)] UNSPEC_FYL2X))
15519               (clobber (match_scratch:XF 5 ""))])
15520    (set (match_operand:SF 0 "register_operand" "")
15521         (float_truncate:SF (match_dup 4)))]
15522   "TARGET_USE_FANCY_MATH_387
15523    && flag_unsafe_math_optimizations"
15524 {
15525   rtx temp;
15526
15527   operands[2] = gen_reg_rtx (XFmode);
15528   operands[3] = gen_reg_rtx (XFmode);
15529   operands[4] = gen_reg_rtx (XFmode);
15530
15531   temp = standard_80387_constant_rtx (4); /* fldln2 */
15532   emit_move_insn (operands[3], temp);
15533 })
15534
15535 (define_expand "logdf2"
15536   [(set (match_dup 2)
15537         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15538    (parallel [(set (match_dup 4)
15539                    (unspec:XF [(match_dup 2)
15540                                (match_dup 3)] UNSPEC_FYL2X))
15541               (clobber (match_scratch:XF 5 ""))])
15542    (set (match_operand:DF 0 "register_operand" "")
15543         (float_truncate:DF (match_dup 4)))]
15544   "TARGET_USE_FANCY_MATH_387
15545    && flag_unsafe_math_optimizations"
15546 {
15547   rtx temp;
15548
15549   operands[2] = gen_reg_rtx (XFmode);
15550   operands[3] = gen_reg_rtx (XFmode);
15551   operands[4] = gen_reg_rtx (XFmode);
15552
15553   temp = standard_80387_constant_rtx (4); /* fldln2 */
15554   emit_move_insn (operands[3], temp);
15555 })
15556
15557 (define_expand "logxf2"
15558   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15559                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15560                                (match_dup 2)] UNSPEC_FYL2X))
15561               (clobber (match_scratch:XF 3 ""))])]
15562   "TARGET_USE_FANCY_MATH_387
15563    && flag_unsafe_math_optimizations"
15564 {
15565   rtx temp;
15566
15567   operands[2] = gen_reg_rtx (XFmode);
15568   temp = standard_80387_constant_rtx (4); /* fldln2 */
15569   emit_move_insn (operands[2], temp);
15570 })
15571
15572 (define_expand "log10sf2"
15573   [(set (match_dup 2)
15574         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15575    (parallel [(set (match_dup 4)
15576                    (unspec:XF [(match_dup 2)
15577                                (match_dup 3)] UNSPEC_FYL2X))
15578               (clobber (match_scratch:XF 5 ""))])
15579    (set (match_operand:SF 0 "register_operand" "")
15580         (float_truncate:SF (match_dup 4)))]
15581   "TARGET_USE_FANCY_MATH_387
15582    && flag_unsafe_math_optimizations"
15583 {
15584   rtx temp;
15585
15586   operands[2] = gen_reg_rtx (XFmode);
15587   operands[3] = gen_reg_rtx (XFmode);
15588   operands[4] = gen_reg_rtx (XFmode);
15589
15590   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15591   emit_move_insn (operands[3], temp);
15592 })
15593
15594 (define_expand "log10df2"
15595   [(set (match_dup 2)
15596         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15597    (parallel [(set (match_dup 4)
15598                    (unspec:XF [(match_dup 2)
15599                                (match_dup 3)] UNSPEC_FYL2X))
15600               (clobber (match_scratch:XF 5 ""))])
15601    (set (match_operand:DF 0 "register_operand" "")
15602         (float_truncate:DF (match_dup 4)))]
15603   "TARGET_USE_FANCY_MATH_387
15604    && flag_unsafe_math_optimizations"
15605 {
15606   rtx temp;
15607
15608   operands[2] = gen_reg_rtx (XFmode);
15609   operands[3] = gen_reg_rtx (XFmode);
15610   operands[4] = gen_reg_rtx (XFmode);
15611
15612   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15613   emit_move_insn (operands[3], temp);
15614 })
15615
15616 (define_expand "log10xf2"
15617   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15618                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15619                                (match_dup 2)] UNSPEC_FYL2X))
15620               (clobber (match_scratch:XF 3 ""))])]
15621   "TARGET_USE_FANCY_MATH_387
15622    && flag_unsafe_math_optimizations"
15623 {
15624   rtx temp;
15625
15626   operands[2] = gen_reg_rtx (XFmode);
15627   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15628   emit_move_insn (operands[2], temp);
15629 })
15630
15631 (define_expand "log2sf2"
15632   [(set (match_dup 2)
15633         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15634    (parallel [(set (match_dup 4)
15635                    (unspec:XF [(match_dup 2)
15636                                (match_dup 3)] UNSPEC_FYL2X))
15637               (clobber (match_scratch:XF 5 ""))])
15638    (set (match_operand:SF 0 "register_operand" "")
15639         (float_truncate:SF (match_dup 4)))]
15640   "TARGET_USE_FANCY_MATH_387
15641    && flag_unsafe_math_optimizations"
15642 {
15643   operands[2] = gen_reg_rtx (XFmode);
15644   operands[3] = gen_reg_rtx (XFmode);
15645   operands[4] = gen_reg_rtx (XFmode);
15646
15647   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15648 })
15649
15650 (define_expand "log2df2"
15651   [(set (match_dup 2)
15652         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15653    (parallel [(set (match_dup 4)
15654                    (unspec:XF [(match_dup 2)
15655                                (match_dup 3)] UNSPEC_FYL2X))
15656               (clobber (match_scratch:XF 5 ""))])
15657    (set (match_operand:DF 0 "register_operand" "")
15658         (float_truncate:DF (match_dup 4)))]
15659   "TARGET_USE_FANCY_MATH_387
15660    && flag_unsafe_math_optimizations"
15661 {
15662   operands[2] = gen_reg_rtx (XFmode);
15663   operands[3] = gen_reg_rtx (XFmode);
15664   operands[4] = gen_reg_rtx (XFmode);
15665
15666   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15667 })
15668
15669 (define_expand "log2xf2"
15670   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15671                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15672                                (match_dup 2)] UNSPEC_FYL2X))
15673               (clobber (match_scratch:XF 3 ""))])]
15674   "TARGET_USE_FANCY_MATH_387
15675    && flag_unsafe_math_optimizations"
15676 {
15677   operands[2] = gen_reg_rtx (XFmode);
15678   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15679 })
15680
15681 (define_insn "fyl2xp1_xf3"
15682   [(set (match_operand:XF 0 "register_operand" "=f")
15683         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15684                     (match_operand:XF 1 "register_operand" "u")]
15685                    UNSPEC_FYL2XP1))
15686    (clobber (match_scratch:XF 3 "=1"))]
15687   "TARGET_USE_FANCY_MATH_387
15688    && flag_unsafe_math_optimizations"
15689   "fyl2xp1"
15690   [(set_attr "type" "fpspc")
15691    (set_attr "mode" "XF")])
15692
15693 (define_expand "log1psf2"
15694   [(use (match_operand:XF 0 "register_operand" ""))
15695    (use (match_operand:XF 1 "register_operand" ""))]
15696   "TARGET_USE_FANCY_MATH_387
15697    && flag_unsafe_math_optimizations"
15698 {
15699   rtx op0 = gen_reg_rtx (XFmode);
15700   rtx op1 = gen_reg_rtx (XFmode);
15701
15702   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15703   ix86_emit_i387_log1p (op0, op1);
15704   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15705   DONE;
15706 })
15707
15708 (define_expand "log1pdf2"
15709   [(use (match_operand:XF 0 "register_operand" ""))
15710    (use (match_operand:XF 1 "register_operand" ""))]
15711   "TARGET_USE_FANCY_MATH_387
15712    && flag_unsafe_math_optimizations"
15713 {
15714   rtx op0 = gen_reg_rtx (XFmode);
15715   rtx op1 = gen_reg_rtx (XFmode);
15716
15717   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15718   ix86_emit_i387_log1p (op0, op1);
15719   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15720   DONE;
15721 })
15722
15723 (define_expand "log1pxf2"
15724   [(use (match_operand:XF 0 "register_operand" ""))
15725    (use (match_operand:XF 1 "register_operand" ""))]
15726   "TARGET_USE_FANCY_MATH_387
15727    && flag_unsafe_math_optimizations"
15728 {
15729   ix86_emit_i387_log1p (operands[0], operands[1]);
15730   DONE;
15731 })
15732
15733 (define_insn "*fxtractxf3"
15734   [(set (match_operand:XF 0 "register_operand" "=f")
15735         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15736                    UNSPEC_XTRACT_FRACT))
15737    (set (match_operand:XF 1 "register_operand" "=u")
15738         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15739   "TARGET_USE_FANCY_MATH_387
15740    && flag_unsafe_math_optimizations"
15741   "fxtract"
15742   [(set_attr "type" "fpspc")
15743    (set_attr "mode" "XF")])
15744
15745 (define_expand "logbsf2"
15746   [(set (match_dup 2)
15747         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15748    (parallel [(set (match_dup 3)
15749                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15750               (set (match_dup 4)
15751                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15752    (set (match_operand:SF 0 "register_operand" "")
15753         (float_truncate:SF (match_dup 4)))]
15754   "TARGET_USE_FANCY_MATH_387
15755    && flag_unsafe_math_optimizations"
15756 {
15757   operands[2] = gen_reg_rtx (XFmode);
15758   operands[3] = gen_reg_rtx (XFmode);
15759   operands[4] = gen_reg_rtx (XFmode);
15760 })
15761
15762 (define_expand "logbdf2"
15763   [(set (match_dup 2)
15764         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15765    (parallel [(set (match_dup 3)
15766                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15767               (set (match_dup 4)
15768                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15769    (set (match_operand:DF 0 "register_operand" "")
15770         (float_truncate:DF (match_dup 4)))]
15771   "TARGET_USE_FANCY_MATH_387
15772    && flag_unsafe_math_optimizations"
15773 {
15774   operands[2] = gen_reg_rtx (XFmode);
15775   operands[3] = gen_reg_rtx (XFmode);
15776   operands[4] = gen_reg_rtx (XFmode);
15777 })
15778
15779 (define_expand "logbxf2"
15780   [(parallel [(set (match_dup 2)
15781                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15782                               UNSPEC_XTRACT_FRACT))
15783               (set (match_operand:XF 0 "register_operand" "")
15784                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15785   "TARGET_USE_FANCY_MATH_387
15786    && flag_unsafe_math_optimizations"
15787 {
15788   operands[2] = gen_reg_rtx (XFmode);
15789 })
15790
15791 (define_expand "ilogbsi2"
15792   [(parallel [(set (match_dup 2)
15793                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15794                               UNSPEC_XTRACT_FRACT))
15795               (set (match_operand:XF 3 "register_operand" "")
15796                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15797    (parallel [(set (match_operand:SI 0 "register_operand" "")
15798                    (fix:SI (match_dup 3)))
15799               (clobber (reg:CC FLAGS_REG))])]
15800   "TARGET_USE_FANCY_MATH_387
15801    && flag_unsafe_math_optimizations"
15802 {
15803   operands[2] = gen_reg_rtx (XFmode);
15804   operands[3] = gen_reg_rtx (XFmode);
15805 })
15806
15807 (define_insn "*f2xm1xf2"
15808   [(set (match_operand:XF 0 "register_operand" "=f")
15809         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15810          UNSPEC_F2XM1))]
15811   "TARGET_USE_FANCY_MATH_387
15812    && flag_unsafe_math_optimizations"
15813   "f2xm1"
15814   [(set_attr "type" "fpspc")
15815    (set_attr "mode" "XF")])
15816
15817 (define_insn "*fscalexf4"
15818   [(set (match_operand:XF 0 "register_operand" "=f")
15819         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15820                     (match_operand:XF 3 "register_operand" "1")]
15821                    UNSPEC_FSCALE_FRACT))
15822    (set (match_operand:XF 1 "register_operand" "=u")
15823         (unspec:XF [(match_dup 2) (match_dup 3)]
15824                    UNSPEC_FSCALE_EXP))]
15825   "TARGET_USE_FANCY_MATH_387
15826    && flag_unsafe_math_optimizations"
15827   "fscale"
15828   [(set_attr "type" "fpspc")
15829    (set_attr "mode" "XF")])
15830
15831 (define_expand "expsf2"
15832   [(set (match_dup 2)
15833         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15834    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15835    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15836    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15837    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15838    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15839    (parallel [(set (match_dup 10)
15840                    (unspec:XF [(match_dup 9) (match_dup 5)]
15841                               UNSPEC_FSCALE_FRACT))
15842               (set (match_dup 11)
15843                    (unspec:XF [(match_dup 9) (match_dup 5)]
15844                               UNSPEC_FSCALE_EXP))])
15845    (set (match_operand:SF 0 "register_operand" "")
15846         (float_truncate:SF (match_dup 10)))]
15847   "TARGET_USE_FANCY_MATH_387
15848    && flag_unsafe_math_optimizations"
15849 {
15850   rtx temp;
15851   int i;
15852
15853   for (i=2; i<12; i++)
15854     operands[i] = gen_reg_rtx (XFmode);
15855   temp = standard_80387_constant_rtx (5); /* fldl2e */
15856   emit_move_insn (operands[3], temp);
15857   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15858 })
15859
15860 (define_expand "expdf2"
15861   [(set (match_dup 2)
15862         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15863    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15864    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15865    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15866    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15867    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15868    (parallel [(set (match_dup 10)
15869                    (unspec:XF [(match_dup 9) (match_dup 5)]
15870                               UNSPEC_FSCALE_FRACT))
15871               (set (match_dup 11)
15872                    (unspec:XF [(match_dup 9) (match_dup 5)]
15873                               UNSPEC_FSCALE_EXP))])
15874    (set (match_operand:DF 0 "register_operand" "")
15875         (float_truncate:DF (match_dup 10)))]
15876   "TARGET_USE_FANCY_MATH_387
15877    && flag_unsafe_math_optimizations"
15878 {
15879   rtx temp;
15880   int i;
15881
15882   for (i=2; i<12; i++)
15883     operands[i] = gen_reg_rtx (XFmode);
15884   temp = standard_80387_constant_rtx (5); /* fldl2e */
15885   emit_move_insn (operands[3], temp);
15886   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15887 })
15888
15889 (define_expand "expxf2"
15890   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15891                                (match_dup 2)))
15892    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15893    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15894    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15895    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15896    (parallel [(set (match_operand:XF 0 "register_operand" "")
15897                    (unspec:XF [(match_dup 8) (match_dup 4)]
15898                               UNSPEC_FSCALE_FRACT))
15899               (set (match_dup 9)
15900                    (unspec:XF [(match_dup 8) (match_dup 4)]
15901                               UNSPEC_FSCALE_EXP))])]
15902   "TARGET_USE_FANCY_MATH_387
15903    && flag_unsafe_math_optimizations"
15904 {
15905   rtx temp;
15906   int i;
15907
15908   for (i=2; i<10; i++)
15909     operands[i] = gen_reg_rtx (XFmode);
15910   temp = standard_80387_constant_rtx (5); /* fldl2e */
15911   emit_move_insn (operands[2], temp);
15912   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15913 })
15914
15915 (define_expand "exp10sf2"
15916   [(set (match_dup 2)
15917         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15918    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15919    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15920    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15921    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15922    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15923    (parallel [(set (match_dup 10)
15924                    (unspec:XF [(match_dup 9) (match_dup 5)]
15925                               UNSPEC_FSCALE_FRACT))
15926               (set (match_dup 11)
15927                    (unspec:XF [(match_dup 9) (match_dup 5)]
15928                               UNSPEC_FSCALE_EXP))])
15929    (set (match_operand:SF 0 "register_operand" "")
15930         (float_truncate:SF (match_dup 10)))]
15931   "TARGET_USE_FANCY_MATH_387
15932    && flag_unsafe_math_optimizations"
15933 {
15934   rtx temp;
15935   int i;
15936
15937   for (i=2; i<12; i++)
15938     operands[i] = gen_reg_rtx (XFmode);
15939   temp = standard_80387_constant_rtx (6); /* fldl2t */
15940   emit_move_insn (operands[3], temp);
15941   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15942 })
15943
15944 (define_expand "exp10df2"
15945   [(set (match_dup 2)
15946         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15947    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15948    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15949    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15950    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15951    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15952    (parallel [(set (match_dup 10)
15953                    (unspec:XF [(match_dup 9) (match_dup 5)]
15954                               UNSPEC_FSCALE_FRACT))
15955               (set (match_dup 11)
15956                    (unspec:XF [(match_dup 9) (match_dup 5)]
15957                               UNSPEC_FSCALE_EXP))])
15958    (set (match_operand:DF 0 "register_operand" "")
15959         (float_truncate:DF (match_dup 10)))]
15960   "TARGET_USE_FANCY_MATH_387
15961    && flag_unsafe_math_optimizations"
15962 {
15963   rtx temp;
15964   int i;
15965
15966   for (i=2; i<12; i++)
15967     operands[i] = gen_reg_rtx (XFmode);
15968   temp = standard_80387_constant_rtx (6); /* fldl2t */
15969   emit_move_insn (operands[3], temp);
15970   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15971 })
15972
15973 (define_expand "exp10xf2"
15974   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15975                                (match_dup 2)))
15976    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15977    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15978    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15979    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15980    (parallel [(set (match_operand:XF 0 "register_operand" "")
15981                    (unspec:XF [(match_dup 8) (match_dup 4)]
15982                               UNSPEC_FSCALE_FRACT))
15983               (set (match_dup 9)
15984                    (unspec:XF [(match_dup 8) (match_dup 4)]
15985                               UNSPEC_FSCALE_EXP))])]
15986   "TARGET_USE_FANCY_MATH_387
15987    && flag_unsafe_math_optimizations"
15988 {
15989   rtx temp;
15990   int i;
15991
15992   for (i=2; i<10; i++)
15993     operands[i] = gen_reg_rtx (XFmode);
15994   temp = standard_80387_constant_rtx (6); /* fldl2t */
15995   emit_move_insn (operands[2], temp);
15996   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15997 })
15998
15999 (define_expand "exp2sf2"
16000   [(set (match_dup 2)
16001         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16002    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16003    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16004    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16005    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16006    (parallel [(set (match_dup 8)
16007                    (unspec:XF [(match_dup 7) (match_dup 3)]
16008                               UNSPEC_FSCALE_FRACT))
16009               (set (match_dup 9)
16010                    (unspec:XF [(match_dup 7) (match_dup 3)]
16011                               UNSPEC_FSCALE_EXP))])
16012    (set (match_operand:SF 0 "register_operand" "")
16013         (float_truncate:SF (match_dup 8)))]
16014   "TARGET_USE_FANCY_MATH_387
16015    && flag_unsafe_math_optimizations"
16016 {
16017   int i;
16018
16019   for (i=2; i<10; i++)
16020     operands[i] = gen_reg_rtx (XFmode);
16021   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16022 })
16023
16024 (define_expand "exp2df2"
16025   [(set (match_dup 2)
16026         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16027    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16028    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16029    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16030    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16031    (parallel [(set (match_dup 8)
16032                    (unspec:XF [(match_dup 7) (match_dup 3)]
16033                               UNSPEC_FSCALE_FRACT))
16034               (set (match_dup 9)
16035                    (unspec:XF [(match_dup 7) (match_dup 3)]
16036                               UNSPEC_FSCALE_EXP))])
16037    (set (match_operand:DF 0 "register_operand" "")
16038         (float_truncate:DF (match_dup 8)))]
16039   "TARGET_USE_FANCY_MATH_387
16040    && flag_unsafe_math_optimizations"
16041 {
16042   int i;
16043
16044   for (i=2; i<10; i++)
16045     operands[i] = gen_reg_rtx (XFmode);
16046   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16047 })
16048
16049 (define_expand "exp2xf2"
16050   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16051    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16052    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16053    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16054    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16055    (parallel [(set (match_operand:XF 0 "register_operand" "")
16056                    (unspec:XF [(match_dup 7) (match_dup 3)]
16057                               UNSPEC_FSCALE_FRACT))
16058               (set (match_dup 8)
16059                    (unspec:XF [(match_dup 7) (match_dup 3)]
16060                               UNSPEC_FSCALE_EXP))])]
16061   "TARGET_USE_FANCY_MATH_387
16062    && flag_unsafe_math_optimizations"
16063 {
16064   int i;
16065
16066   for (i=2; i<9; i++)
16067     operands[i] = gen_reg_rtx (XFmode);
16068   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16069 })
16070
16071 (define_expand "expm1df2"
16072   [(set (match_dup 2)
16073         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16074    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16075    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16076    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16077    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16078    (parallel [(set (match_dup 8)
16079                    (unspec:XF [(match_dup 7) (match_dup 5)]
16080                               UNSPEC_FSCALE_FRACT))
16081                    (set (match_dup 9)
16082                    (unspec:XF [(match_dup 7) (match_dup 5)]
16083                               UNSPEC_FSCALE_EXP))])
16084    (parallel [(set (match_dup 11)
16085                    (unspec:XF [(match_dup 10) (match_dup 9)]
16086                               UNSPEC_FSCALE_FRACT))
16087               (set (match_dup 12)
16088                    (unspec:XF [(match_dup 10) (match_dup 9)]
16089                               UNSPEC_FSCALE_EXP))])
16090    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16091    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16092    (set (match_operand:DF 0 "register_operand" "")
16093         (float_truncate:DF (match_dup 14)))]
16094   "TARGET_USE_FANCY_MATH_387
16095    && flag_unsafe_math_optimizations"
16096 {
16097   rtx temp;
16098   int i;
16099
16100   for (i=2; i<15; i++)
16101     operands[i] = gen_reg_rtx (XFmode);
16102   temp = standard_80387_constant_rtx (5); /* fldl2e */
16103   emit_move_insn (operands[3], temp);
16104   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16105 })
16106
16107 (define_expand "expm1sf2"
16108   [(set (match_dup 2)
16109         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16110    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16111    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16112    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16113    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16114    (parallel [(set (match_dup 8)
16115                    (unspec:XF [(match_dup 7) (match_dup 5)]
16116                               UNSPEC_FSCALE_FRACT))
16117                    (set (match_dup 9)
16118                    (unspec:XF [(match_dup 7) (match_dup 5)]
16119                               UNSPEC_FSCALE_EXP))])
16120    (parallel [(set (match_dup 11)
16121                    (unspec:XF [(match_dup 10) (match_dup 9)]
16122                               UNSPEC_FSCALE_FRACT))
16123               (set (match_dup 12)
16124                    (unspec:XF [(match_dup 10) (match_dup 9)]
16125                               UNSPEC_FSCALE_EXP))])
16126    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16127    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16128    (set (match_operand:SF 0 "register_operand" "")
16129         (float_truncate:SF (match_dup 14)))]
16130   "TARGET_USE_FANCY_MATH_387
16131    && flag_unsafe_math_optimizations"
16132 {
16133   rtx temp;
16134   int i;
16135
16136   for (i=2; i<15; i++)
16137     operands[i] = gen_reg_rtx (XFmode);
16138   temp = standard_80387_constant_rtx (5); /* fldl2e */
16139   emit_move_insn (operands[3], temp);
16140   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16141 })
16142
16143 (define_expand "expm1xf2"
16144   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16145                                (match_dup 2)))
16146    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16147    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16148    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16149    (parallel [(set (match_dup 7)
16150                    (unspec:XF [(match_dup 6) (match_dup 4)]
16151                               UNSPEC_FSCALE_FRACT))
16152                    (set (match_dup 8)
16153                    (unspec:XF [(match_dup 6) (match_dup 4)]
16154                               UNSPEC_FSCALE_EXP))])
16155    (parallel [(set (match_dup 10)
16156                    (unspec:XF [(match_dup 9) (match_dup 8)]
16157                               UNSPEC_FSCALE_FRACT))
16158               (set (match_dup 11)
16159                    (unspec:XF [(match_dup 9) (match_dup 8)]
16160                               UNSPEC_FSCALE_EXP))])
16161    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16162    (set (match_operand:XF 0 "register_operand" "")
16163         (plus:XF (match_dup 12) (match_dup 7)))]
16164   "TARGET_USE_FANCY_MATH_387
16165    && flag_unsafe_math_optimizations"
16166 {
16167   rtx temp;
16168   int i;
16169
16170   for (i=2; i<13; i++)
16171     operands[i] = gen_reg_rtx (XFmode);
16172   temp = standard_80387_constant_rtx (5); /* fldl2e */
16173   emit_move_insn (operands[2], temp);
16174   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16175 })
16176 \f
16177
16178 (define_insn "frndintxf2"
16179   [(set (match_operand:XF 0 "register_operand" "=f")
16180         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16181          UNSPEC_FRNDINT))]
16182   "TARGET_USE_FANCY_MATH_387
16183    && flag_unsafe_math_optimizations"
16184   "frndint"
16185   [(set_attr "type" "fpspc")
16186    (set_attr "mode" "XF")])
16187
16188 (define_expand "rintdf2"
16189   [(use (match_operand:DF 0 "register_operand" ""))
16190    (use (match_operand:DF 1 "register_operand" ""))]
16191   "TARGET_USE_FANCY_MATH_387
16192    && flag_unsafe_math_optimizations"
16193 {
16194   rtx op0 = gen_reg_rtx (XFmode);
16195   rtx op1 = gen_reg_rtx (XFmode);
16196
16197   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16198   emit_insn (gen_frndintxf2 (op0, op1));
16199
16200   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16201   DONE;
16202 })
16203
16204 (define_expand "rintsf2"
16205   [(use (match_operand:SF 0 "register_operand" ""))
16206    (use (match_operand:SF 1 "register_operand" ""))]
16207   "TARGET_USE_FANCY_MATH_387
16208    && flag_unsafe_math_optimizations"
16209 {
16210   rtx op0 = gen_reg_rtx (XFmode);
16211   rtx op1 = gen_reg_rtx (XFmode);
16212
16213   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16214   emit_insn (gen_frndintxf2 (op0, op1));
16215
16216   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16217   DONE;
16218 })
16219
16220 (define_expand "rintxf2"
16221   [(use (match_operand:XF 0 "register_operand" ""))
16222    (use (match_operand:XF 1 "register_operand" ""))]
16223   "TARGET_USE_FANCY_MATH_387
16224    && flag_unsafe_math_optimizations"
16225 {
16226   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16227   DONE;
16228 })
16229
16230 (define_insn "frndintxf2_floor"
16231   [(set (match_operand:XF 0 "register_operand" "=f")
16232         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16233          UNSPEC_FRNDINT_FLOOR))
16234    (use (match_operand:HI 2 "memory_operand" "m"))
16235    (use (match_operand:HI 3 "memory_operand" "m"))]
16236   "TARGET_USE_FANCY_MATH_387
16237    && flag_unsafe_math_optimizations"
16238   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16239   [(set_attr "type" "frndint")
16240    (set_attr "i387_cw" "floor")
16241    (set_attr "mode" "XF")])
16242
16243 (define_expand "floordf2"
16244   [(use (match_operand:DF 0 "register_operand" ""))
16245    (use (match_operand:DF 1 "register_operand" ""))]
16246   "TARGET_USE_FANCY_MATH_387
16247    && flag_unsafe_math_optimizations"
16248 {
16249   rtx op0 = gen_reg_rtx (XFmode);
16250   rtx op1 = gen_reg_rtx (XFmode);
16251   rtx op2 = assign_386_stack_local (HImode, 1);
16252   rtx op3 = assign_386_stack_local (HImode, 2);
16253         
16254   ix86_optimize_mode_switching = 1;
16255
16256   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16257   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16258
16259   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16260   DONE;
16261 })
16262
16263 (define_expand "floorsf2"
16264   [(use (match_operand:SF 0 "register_operand" ""))
16265    (use (match_operand:SF 1 "register_operand" ""))]
16266   "TARGET_USE_FANCY_MATH_387
16267    && flag_unsafe_math_optimizations"
16268 {
16269   rtx op0 = gen_reg_rtx (XFmode);
16270   rtx op1 = gen_reg_rtx (XFmode);
16271   rtx op2 = assign_386_stack_local (HImode, 1);
16272   rtx op3 = assign_386_stack_local (HImode, 2);
16273         
16274   ix86_optimize_mode_switching = 1;
16275
16276   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16277   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16278
16279   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16280   DONE;
16281 })
16282
16283 (define_expand "floorxf2"
16284   [(use (match_operand:XF 0 "register_operand" ""))
16285    (use (match_operand:XF 1 "register_operand" ""))]
16286   "TARGET_USE_FANCY_MATH_387
16287    && flag_unsafe_math_optimizations"
16288 {
16289   rtx op2 = assign_386_stack_local (HImode, 1);
16290   rtx op3 = assign_386_stack_local (HImode, 2);
16291         
16292   ix86_optimize_mode_switching = 1;
16293
16294   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16295   DONE;
16296 })
16297
16298 (define_insn "frndintxf2_ceil"
16299   [(set (match_operand:XF 0 "register_operand" "=f")
16300         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16301          UNSPEC_FRNDINT_CEIL))
16302    (use (match_operand:HI 2 "memory_operand" "m"))
16303    (use (match_operand:HI 3 "memory_operand" "m"))]
16304   "TARGET_USE_FANCY_MATH_387
16305    && flag_unsafe_math_optimizations"
16306   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16307   [(set_attr "type" "frndint")
16308    (set_attr "i387_cw" "ceil")
16309    (set_attr "mode" "XF")])
16310
16311 (define_expand "ceildf2"
16312   [(use (match_operand:DF 0 "register_operand" ""))
16313    (use (match_operand:DF 1 "register_operand" ""))]
16314   "TARGET_USE_FANCY_MATH_387
16315    && flag_unsafe_math_optimizations"
16316 {
16317   rtx op0 = gen_reg_rtx (XFmode);
16318   rtx op1 = gen_reg_rtx (XFmode);
16319   rtx op2 = assign_386_stack_local (HImode, 1);
16320   rtx op3 = assign_386_stack_local (HImode, 2);
16321         
16322   ix86_optimize_mode_switching = 1;
16323
16324   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16325   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16326
16327   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16328   DONE;
16329 })
16330
16331 (define_expand "ceilsf2"
16332   [(use (match_operand:SF 0 "register_operand" ""))
16333    (use (match_operand:SF 1 "register_operand" ""))]
16334   "TARGET_USE_FANCY_MATH_387
16335    && flag_unsafe_math_optimizations"
16336 {
16337   rtx op0 = gen_reg_rtx (XFmode);
16338   rtx op1 = gen_reg_rtx (XFmode);
16339   rtx op2 = assign_386_stack_local (HImode, 1);
16340   rtx op3 = assign_386_stack_local (HImode, 2);
16341         
16342   ix86_optimize_mode_switching = 1;
16343
16344   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16345   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16346
16347   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16348   DONE;
16349 })
16350
16351 (define_expand "ceilxf2"
16352   [(use (match_operand:XF 0 "register_operand" ""))
16353    (use (match_operand:XF 1 "register_operand" ""))]
16354   "TARGET_USE_FANCY_MATH_387
16355    && flag_unsafe_math_optimizations"
16356 {
16357   rtx op2 = assign_386_stack_local (HImode, 1);
16358   rtx op3 = assign_386_stack_local (HImode, 2);
16359         
16360   ix86_optimize_mode_switching = 1;
16361
16362   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16363   DONE;
16364 })
16365
16366 (define_insn "frndintxf2_trunc"
16367   [(set (match_operand:XF 0 "register_operand" "=f")
16368         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16369          UNSPEC_FRNDINT_TRUNC))
16370    (use (match_operand:HI 2 "memory_operand" "m"))
16371    (use (match_operand:HI 3 "memory_operand" "m"))]
16372   "TARGET_USE_FANCY_MATH_387
16373    && flag_unsafe_math_optimizations"
16374   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16375   [(set_attr "type" "frndint")
16376    (set_attr "i387_cw" "trunc")
16377    (set_attr "mode" "XF")])
16378
16379 (define_expand "btruncdf2"
16380   [(use (match_operand:DF 0 "register_operand" ""))
16381    (use (match_operand:DF 1 "register_operand" ""))]
16382   "TARGET_USE_FANCY_MATH_387
16383    && flag_unsafe_math_optimizations"
16384 {
16385   rtx op0 = gen_reg_rtx (XFmode);
16386   rtx op1 = gen_reg_rtx (XFmode);
16387   rtx op2 = assign_386_stack_local (HImode, 1);
16388   rtx op3 = assign_386_stack_local (HImode, 2);
16389         
16390   ix86_optimize_mode_switching = 1;
16391
16392   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16393   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16394
16395   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16396   DONE;
16397 })
16398
16399 (define_expand "btruncsf2"
16400   [(use (match_operand:SF 0 "register_operand" ""))
16401    (use (match_operand:SF 1 "register_operand" ""))]
16402   "TARGET_USE_FANCY_MATH_387
16403    && flag_unsafe_math_optimizations"
16404 {
16405   rtx op0 = gen_reg_rtx (XFmode);
16406   rtx op1 = gen_reg_rtx (XFmode);
16407   rtx op2 = assign_386_stack_local (HImode, 1);
16408   rtx op3 = assign_386_stack_local (HImode, 2);
16409         
16410   ix86_optimize_mode_switching = 1;
16411
16412   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16413   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16414
16415   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16416   DONE;
16417 })
16418
16419 (define_expand "btruncxf2"
16420   [(use (match_operand:XF 0 "register_operand" ""))
16421    (use (match_operand:XF 1 "register_operand" ""))]
16422   "TARGET_USE_FANCY_MATH_387
16423    && flag_unsafe_math_optimizations"
16424 {
16425   rtx op2 = assign_386_stack_local (HImode, 1);
16426   rtx op3 = assign_386_stack_local (HImode, 2);
16427         
16428   ix86_optimize_mode_switching = 1;
16429
16430   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16431   DONE;
16432 })
16433
16434 (define_insn "frndintxf2_mask_pm"
16435   [(set (match_operand:XF 0 "register_operand" "=f")
16436         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16437          UNSPEC_FRNDINT_MASK_PM))
16438    (use (match_operand:HI 2 "memory_operand" "m"))
16439    (use (match_operand:HI 3 "memory_operand" "m"))]
16440   "TARGET_USE_FANCY_MATH_387
16441    && flag_unsafe_math_optimizations"
16442   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16443   [(set_attr "type" "frndint")
16444    (set_attr "i387_cw" "mask_pm")
16445    (set_attr "mode" "XF")])
16446
16447 (define_expand "nearbyintdf2"
16448   [(use (match_operand:DF 0 "register_operand" ""))
16449    (use (match_operand:DF 1 "register_operand" ""))]
16450   "TARGET_USE_FANCY_MATH_387
16451    && flag_unsafe_math_optimizations"
16452 {
16453   rtx op0 = gen_reg_rtx (XFmode);
16454   rtx op1 = gen_reg_rtx (XFmode);
16455   rtx op2 = assign_386_stack_local (HImode, 1);
16456   rtx op3 = assign_386_stack_local (HImode, 2);
16457         
16458   ix86_optimize_mode_switching = 1;
16459
16460   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16461   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16462
16463   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16464   DONE;
16465 })
16466
16467 (define_expand "nearbyintsf2"
16468   [(use (match_operand:SF 0 "register_operand" ""))
16469    (use (match_operand:SF 1 "register_operand" ""))]
16470   "TARGET_USE_FANCY_MATH_387
16471    && flag_unsafe_math_optimizations"
16472 {
16473   rtx op0 = gen_reg_rtx (XFmode);
16474   rtx op1 = gen_reg_rtx (XFmode);
16475   rtx op2 = assign_386_stack_local (HImode, 1);
16476   rtx op3 = assign_386_stack_local (HImode, 2);
16477         
16478   ix86_optimize_mode_switching = 1;
16479
16480   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16481   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16482
16483   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16484   DONE;
16485 })
16486
16487 (define_expand "nearbyintxf2"
16488   [(use (match_operand:XF 0 "register_operand" ""))
16489    (use (match_operand:XF 1 "register_operand" ""))]
16490   "TARGET_USE_FANCY_MATH_387
16491    && flag_unsafe_math_optimizations"
16492 {
16493   rtx op2 = assign_386_stack_local (HImode, 1);
16494   rtx op3 = assign_386_stack_local (HImode, 2);
16495         
16496   ix86_optimize_mode_switching = 1;
16497
16498   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16499                                      op2, op3));
16500   DONE;
16501 })
16502
16503 \f
16504 ;; Block operation instructions
16505
16506 (define_insn "cld"
16507  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16508  ""
16509  "cld"
16510   [(set_attr "type" "cld")])
16511
16512 (define_expand "movmemsi"
16513   [(use (match_operand:BLK 0 "memory_operand" ""))
16514    (use (match_operand:BLK 1 "memory_operand" ""))
16515    (use (match_operand:SI 2 "nonmemory_operand" ""))
16516    (use (match_operand:SI 3 "const_int_operand" ""))]
16517   "! optimize_size"
16518 {
16519  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16520    DONE;
16521  else
16522    FAIL;
16523 })
16524
16525 (define_expand "movmemdi"
16526   [(use (match_operand:BLK 0 "memory_operand" ""))
16527    (use (match_operand:BLK 1 "memory_operand" ""))
16528    (use (match_operand:DI 2 "nonmemory_operand" ""))
16529    (use (match_operand:DI 3 "const_int_operand" ""))]
16530   "TARGET_64BIT"
16531 {
16532  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16533    DONE;
16534  else
16535    FAIL;
16536 })
16537
16538 ;; Most CPUs don't like single string operations
16539 ;; Handle this case here to simplify previous expander.
16540
16541 (define_expand "strmov"
16542   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16543    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16544    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16545               (clobber (reg:CC FLAGS_REG))])
16546    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16547               (clobber (reg:CC FLAGS_REG))])]
16548   ""
16549 {
16550   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16551
16552   /* If .md ever supports :P for Pmode, these can be directly
16553      in the pattern above.  */
16554   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16555   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16556
16557   if (TARGET_SINGLE_STRINGOP || optimize_size)
16558     {
16559       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16560                                       operands[2], operands[3],
16561                                       operands[5], operands[6]));
16562       DONE;
16563     }
16564
16565   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16566 })
16567
16568 (define_expand "strmov_singleop"
16569   [(parallel [(set (match_operand 1 "memory_operand" "")
16570                    (match_operand 3 "memory_operand" ""))
16571               (set (match_operand 0 "register_operand" "")
16572                    (match_operand 4 "" ""))
16573               (set (match_operand 2 "register_operand" "")
16574                    (match_operand 5 "" ""))
16575               (use (reg:SI DIRFLAG_REG))])]
16576   "TARGET_SINGLE_STRINGOP || optimize_size"
16577   "")
16578
16579 (define_insn "*strmovdi_rex_1"
16580   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16581         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16582    (set (match_operand:DI 0 "register_operand" "=D")
16583         (plus:DI (match_dup 2)
16584                  (const_int 8)))
16585    (set (match_operand:DI 1 "register_operand" "=S")
16586         (plus:DI (match_dup 3)
16587                  (const_int 8)))
16588    (use (reg:SI DIRFLAG_REG))]
16589   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16590   "movsq"
16591   [(set_attr "type" "str")
16592    (set_attr "mode" "DI")
16593    (set_attr "memory" "both")])
16594
16595 (define_insn "*strmovsi_1"
16596   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16597         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16598    (set (match_operand:SI 0 "register_operand" "=D")
16599         (plus:SI (match_dup 2)
16600                  (const_int 4)))
16601    (set (match_operand:SI 1 "register_operand" "=S")
16602         (plus:SI (match_dup 3)
16603                  (const_int 4)))
16604    (use (reg:SI DIRFLAG_REG))]
16605   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16606   "{movsl|movsd}"
16607   [(set_attr "type" "str")
16608    (set_attr "mode" "SI")
16609    (set_attr "memory" "both")])
16610
16611 (define_insn "*strmovsi_rex_1"
16612   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16613         (mem:SI (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 4)))
16617    (set (match_operand:DI 1 "register_operand" "=S")
16618         (plus:DI (match_dup 3)
16619                  (const_int 4)))
16620    (use (reg:SI DIRFLAG_REG))]
16621   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16622   "{movsl|movsd}"
16623   [(set_attr "type" "str")
16624    (set_attr "mode" "SI")
16625    (set_attr "memory" "both")])
16626
16627 (define_insn "*strmovhi_1"
16628   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16629         (mem:HI (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 2)))
16633    (set (match_operand:SI 1 "register_operand" "=S")
16634         (plus:SI (match_dup 3)
16635                  (const_int 2)))
16636    (use (reg:SI DIRFLAG_REG))]
16637   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16638   "movsw"
16639   [(set_attr "type" "str")
16640    (set_attr "memory" "both")
16641    (set_attr "mode" "HI")])
16642
16643 (define_insn "*strmovhi_rex_1"
16644   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16645         (mem:HI (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 2)))
16649    (set (match_operand:DI 1 "register_operand" "=S")
16650         (plus:DI (match_dup 3)
16651                  (const_int 2)))
16652    (use (reg:SI DIRFLAG_REG))]
16653   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16654   "movsw"
16655   [(set_attr "type" "str")
16656    (set_attr "memory" "both")
16657    (set_attr "mode" "HI")])
16658
16659 (define_insn "*strmovqi_1"
16660   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16661         (mem:QI (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 1)))
16665    (set (match_operand:SI 1 "register_operand" "=S")
16666         (plus:SI (match_dup 3)
16667                  (const_int 1)))
16668    (use (reg:SI DIRFLAG_REG))]
16669   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16670   "movsb"
16671   [(set_attr "type" "str")
16672    (set_attr "memory" "both")
16673    (set_attr "mode" "QI")])
16674
16675 (define_insn "*strmovqi_rex_1"
16676   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16677         (mem:QI (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 1)))
16681    (set (match_operand:DI 1 "register_operand" "=S")
16682         (plus:DI (match_dup 3)
16683                  (const_int 1)))
16684    (use (reg:SI DIRFLAG_REG))]
16685   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16686   "movsb"
16687   [(set_attr "type" "str")
16688    (set_attr "memory" "both")
16689    (set_attr "mode" "QI")])
16690
16691 (define_expand "rep_mov"
16692   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16693               (set (match_operand 0 "register_operand" "")
16694                    (match_operand 5 "" ""))
16695               (set (match_operand 2 "register_operand" "")
16696                    (match_operand 6 "" ""))
16697               (set (match_operand 1 "memory_operand" "")
16698                    (match_operand 3 "memory_operand" ""))
16699               (use (match_dup 4))
16700               (use (reg:SI DIRFLAG_REG))])]
16701   ""
16702   "")
16703
16704 (define_insn "*rep_movdi_rex64"
16705   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16706    (set (match_operand:DI 0 "register_operand" "=D") 
16707         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16708                             (const_int 3))
16709                  (match_operand:DI 3 "register_operand" "0")))
16710    (set (match_operand:DI 1 "register_operand" "=S") 
16711         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16712                  (match_operand:DI 4 "register_operand" "1")))
16713    (set (mem:BLK (match_dup 3))
16714         (mem:BLK (match_dup 4)))
16715    (use (match_dup 5))
16716    (use (reg:SI DIRFLAG_REG))]
16717   "TARGET_64BIT"
16718   "{rep\;movsq|rep movsq}"
16719   [(set_attr "type" "str")
16720    (set_attr "prefix_rep" "1")
16721    (set_attr "memory" "both")
16722    (set_attr "mode" "DI")])
16723
16724 (define_insn "*rep_movsi"
16725   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16726    (set (match_operand:SI 0 "register_operand" "=D") 
16727         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16728                             (const_int 2))
16729                  (match_operand:SI 3 "register_operand" "0")))
16730    (set (match_operand:SI 1 "register_operand" "=S") 
16731         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16732                  (match_operand:SI 4 "register_operand" "1")))
16733    (set (mem:BLK (match_dup 3))
16734         (mem:BLK (match_dup 4)))
16735    (use (match_dup 5))
16736    (use (reg:SI DIRFLAG_REG))]
16737   "!TARGET_64BIT"
16738   "{rep\;movsl|rep movsd}"
16739   [(set_attr "type" "str")
16740    (set_attr "prefix_rep" "1")
16741    (set_attr "memory" "both")
16742    (set_attr "mode" "SI")])
16743
16744 (define_insn "*rep_movsi_rex64"
16745   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16746    (set (match_operand:DI 0 "register_operand" "=D") 
16747         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16748                             (const_int 2))
16749                  (match_operand:DI 3 "register_operand" "0")))
16750    (set (match_operand:DI 1 "register_operand" "=S") 
16751         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16752                  (match_operand:DI 4 "register_operand" "1")))
16753    (set (mem:BLK (match_dup 3))
16754         (mem:BLK (match_dup 4)))
16755    (use (match_dup 5))
16756    (use (reg:SI DIRFLAG_REG))]
16757   "TARGET_64BIT"
16758   "{rep\;movsl|rep movsd}"
16759   [(set_attr "type" "str")
16760    (set_attr "prefix_rep" "1")
16761    (set_attr "memory" "both")
16762    (set_attr "mode" "SI")])
16763
16764 (define_insn "*rep_movqi"
16765   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16766    (set (match_operand:SI 0 "register_operand" "=D") 
16767         (plus:SI (match_operand:SI 3 "register_operand" "0")
16768                  (match_operand:SI 5 "register_operand" "2")))
16769    (set (match_operand:SI 1 "register_operand" "=S") 
16770         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16771    (set (mem:BLK (match_dup 3))
16772         (mem:BLK (match_dup 4)))
16773    (use (match_dup 5))
16774    (use (reg:SI DIRFLAG_REG))]
16775   "!TARGET_64BIT"
16776   "{rep\;movsb|rep movsb}"
16777   [(set_attr "type" "str")
16778    (set_attr "prefix_rep" "1")
16779    (set_attr "memory" "both")
16780    (set_attr "mode" "SI")])
16781
16782 (define_insn "*rep_movqi_rex64"
16783   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16784    (set (match_operand:DI 0 "register_operand" "=D") 
16785         (plus:DI (match_operand:DI 3 "register_operand" "0")
16786                  (match_operand:DI 5 "register_operand" "2")))
16787    (set (match_operand:DI 1 "register_operand" "=S") 
16788         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16789    (set (mem:BLK (match_dup 3))
16790         (mem:BLK (match_dup 4)))
16791    (use (match_dup 5))
16792    (use (reg:SI DIRFLAG_REG))]
16793   "TARGET_64BIT"
16794   "{rep\;movsb|rep movsb}"
16795   [(set_attr "type" "str")
16796    (set_attr "prefix_rep" "1")
16797    (set_attr "memory" "both")
16798    (set_attr "mode" "SI")])
16799
16800 (define_expand "clrmemsi"
16801    [(use (match_operand:BLK 0 "memory_operand" ""))
16802     (use (match_operand:SI 1 "nonmemory_operand" ""))
16803     (use (match_operand 2 "const_int_operand" ""))]
16804   ""
16805 {
16806  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16807    DONE;
16808  else
16809    FAIL;
16810 })
16811
16812 (define_expand "clrmemdi"
16813    [(use (match_operand:BLK 0 "memory_operand" ""))
16814     (use (match_operand:DI 1 "nonmemory_operand" ""))
16815     (use (match_operand 2 "const_int_operand" ""))]
16816   "TARGET_64BIT"
16817 {
16818  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16819    DONE;
16820  else
16821    FAIL;
16822 })
16823
16824 ;; Most CPUs don't like single string operations
16825 ;; Handle this case here to simplify previous expander.
16826
16827 (define_expand "strset"
16828   [(set (match_operand 1 "memory_operand" "")
16829         (match_operand 2 "register_operand" ""))
16830    (parallel [(set (match_operand 0 "register_operand" "")
16831                    (match_dup 3))
16832               (clobber (reg:CC FLAGS_REG))])]
16833   ""
16834 {
16835   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16836     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16837
16838   /* If .md ever supports :P for Pmode, this can be directly
16839      in the pattern above.  */
16840   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16841                               GEN_INT (GET_MODE_SIZE (GET_MODE
16842                                                       (operands[2]))));
16843   if (TARGET_SINGLE_STRINGOP || optimize_size)
16844     {
16845       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16846                                       operands[3]));
16847       DONE;
16848     }
16849 })
16850
16851 (define_expand "strset_singleop"
16852   [(parallel [(set (match_operand 1 "memory_operand" "")
16853                    (match_operand 2 "register_operand" ""))
16854               (set (match_operand 0 "register_operand" "")
16855                    (match_operand 3 "" ""))
16856               (use (reg:SI DIRFLAG_REG))])]
16857   "TARGET_SINGLE_STRINGOP || optimize_size"
16858   "")
16859
16860 (define_insn "*strsetdi_rex_1"
16861   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16862         (match_operand:DI 2 "register_operand" "a"))
16863    (set (match_operand:DI 0 "register_operand" "=D")
16864         (plus:DI (match_dup 1)
16865                  (const_int 8)))
16866    (use (reg:SI DIRFLAG_REG))]
16867   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16868   "stosq"
16869   [(set_attr "type" "str")
16870    (set_attr "memory" "store")
16871    (set_attr "mode" "DI")])
16872
16873 (define_insn "*strsetsi_1"
16874   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16875         (match_operand:SI 2 "register_operand" "a"))
16876    (set (match_operand:SI 0 "register_operand" "=D")
16877         (plus:SI (match_dup 1)
16878                  (const_int 4)))
16879    (use (reg:SI DIRFLAG_REG))]
16880   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16881   "{stosl|stosd}"
16882   [(set_attr "type" "str")
16883    (set_attr "memory" "store")
16884    (set_attr "mode" "SI")])
16885
16886 (define_insn "*strsetsi_rex_1"
16887   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16888         (match_operand:SI 2 "register_operand" "a"))
16889    (set (match_operand:DI 0 "register_operand" "=D")
16890         (plus:DI (match_dup 1)
16891                  (const_int 4)))
16892    (use (reg:SI DIRFLAG_REG))]
16893   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16894   "{stosl|stosd}"
16895   [(set_attr "type" "str")
16896    (set_attr "memory" "store")
16897    (set_attr "mode" "SI")])
16898
16899 (define_insn "*strsethi_1"
16900   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16901         (match_operand:HI 2 "register_operand" "a"))
16902    (set (match_operand:SI 0 "register_operand" "=D")
16903         (plus:SI (match_dup 1)
16904                  (const_int 2)))
16905    (use (reg:SI DIRFLAG_REG))]
16906   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16907   "stosw"
16908   [(set_attr "type" "str")
16909    (set_attr "memory" "store")
16910    (set_attr "mode" "HI")])
16911
16912 (define_insn "*strsethi_rex_1"
16913   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16914         (match_operand:HI 2 "register_operand" "a"))
16915    (set (match_operand:DI 0 "register_operand" "=D")
16916         (plus:DI (match_dup 1)
16917                  (const_int 2)))
16918    (use (reg:SI DIRFLAG_REG))]
16919   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16920   "stosw"
16921   [(set_attr "type" "str")
16922    (set_attr "memory" "store")
16923    (set_attr "mode" "HI")])
16924
16925 (define_insn "*strsetqi_1"
16926   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16927         (match_operand:QI 2 "register_operand" "a"))
16928    (set (match_operand:SI 0 "register_operand" "=D")
16929         (plus:SI (match_dup 1)
16930                  (const_int 1)))
16931    (use (reg:SI DIRFLAG_REG))]
16932   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16933   "stosb"
16934   [(set_attr "type" "str")
16935    (set_attr "memory" "store")
16936    (set_attr "mode" "QI")])
16937
16938 (define_insn "*strsetqi_rex_1"
16939   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16940         (match_operand:QI 2 "register_operand" "a"))
16941    (set (match_operand:DI 0 "register_operand" "=D")
16942         (plus:DI (match_dup 1)
16943                  (const_int 1)))
16944    (use (reg:SI DIRFLAG_REG))]
16945   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16946   "stosb"
16947   [(set_attr "type" "str")
16948    (set_attr "memory" "store")
16949    (set_attr "mode" "QI")])
16950
16951 (define_expand "rep_stos"
16952   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16953               (set (match_operand 0 "register_operand" "")
16954                    (match_operand 4 "" ""))
16955               (set (match_operand 2 "memory_operand" "") (const_int 0))
16956               (use (match_operand 3 "register_operand" ""))
16957               (use (match_dup 1))
16958               (use (reg:SI DIRFLAG_REG))])]
16959   ""
16960   "")
16961
16962 (define_insn "*rep_stosdi_rex64"
16963   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16964    (set (match_operand:DI 0 "register_operand" "=D") 
16965         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16966                             (const_int 3))
16967                  (match_operand:DI 3 "register_operand" "0")))
16968    (set (mem:BLK (match_dup 3))
16969         (const_int 0))
16970    (use (match_operand:DI 2 "register_operand" "a"))
16971    (use (match_dup 4))
16972    (use (reg:SI DIRFLAG_REG))]
16973   "TARGET_64BIT"
16974   "{rep\;stosq|rep stosq}"
16975   [(set_attr "type" "str")
16976    (set_attr "prefix_rep" "1")
16977    (set_attr "memory" "store")
16978    (set_attr "mode" "DI")])
16979
16980 (define_insn "*rep_stossi"
16981   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16982    (set (match_operand:SI 0 "register_operand" "=D") 
16983         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16984                             (const_int 2))
16985                  (match_operand:SI 3 "register_operand" "0")))
16986    (set (mem:BLK (match_dup 3))
16987         (const_int 0))
16988    (use (match_operand:SI 2 "register_operand" "a"))
16989    (use (match_dup 4))
16990    (use (reg:SI DIRFLAG_REG))]
16991   "!TARGET_64BIT"
16992   "{rep\;stosl|rep stosd}"
16993   [(set_attr "type" "str")
16994    (set_attr "prefix_rep" "1")
16995    (set_attr "memory" "store")
16996    (set_attr "mode" "SI")])
16997
16998 (define_insn "*rep_stossi_rex64"
16999   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17000    (set (match_operand:DI 0 "register_operand" "=D") 
17001         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17002                             (const_int 2))
17003                  (match_operand:DI 3 "register_operand" "0")))
17004    (set (mem:BLK (match_dup 3))
17005         (const_int 0))
17006    (use (match_operand:SI 2 "register_operand" "a"))
17007    (use (match_dup 4))
17008    (use (reg:SI DIRFLAG_REG))]
17009   "TARGET_64BIT"
17010   "{rep\;stosl|rep stosd}"
17011   [(set_attr "type" "str")
17012    (set_attr "prefix_rep" "1")
17013    (set_attr "memory" "store")
17014    (set_attr "mode" "SI")])
17015
17016 (define_insn "*rep_stosqi"
17017   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17018    (set (match_operand:SI 0 "register_operand" "=D") 
17019         (plus:SI (match_operand:SI 3 "register_operand" "0")
17020                  (match_operand:SI 4 "register_operand" "1")))
17021    (set (mem:BLK (match_dup 3))
17022         (const_int 0))
17023    (use (match_operand:QI 2 "register_operand" "a"))
17024    (use (match_dup 4))
17025    (use (reg:SI DIRFLAG_REG))]
17026   "!TARGET_64BIT"
17027   "{rep\;stosb|rep stosb}"
17028   [(set_attr "type" "str")
17029    (set_attr "prefix_rep" "1")
17030    (set_attr "memory" "store")
17031    (set_attr "mode" "QI")])
17032
17033 (define_insn "*rep_stosqi_rex64"
17034   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17035    (set (match_operand:DI 0 "register_operand" "=D") 
17036         (plus:DI (match_operand:DI 3 "register_operand" "0")
17037                  (match_operand:DI 4 "register_operand" "1")))
17038    (set (mem:BLK (match_dup 3))
17039         (const_int 0))
17040    (use (match_operand:QI 2 "register_operand" "a"))
17041    (use (match_dup 4))
17042    (use (reg:SI DIRFLAG_REG))]
17043   "TARGET_64BIT"
17044   "{rep\;stosb|rep stosb}"
17045   [(set_attr "type" "str")
17046    (set_attr "prefix_rep" "1")
17047    (set_attr "memory" "store")
17048    (set_attr "mode" "QI")])
17049
17050 (define_expand "cmpstrsi"
17051   [(set (match_operand:SI 0 "register_operand" "")
17052         (compare:SI (match_operand:BLK 1 "general_operand" "")
17053                     (match_operand:BLK 2 "general_operand" "")))
17054    (use (match_operand 3 "general_operand" ""))
17055    (use (match_operand 4 "immediate_operand" ""))]
17056   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17057 {
17058   rtx addr1, addr2, out, outlow, count, countreg, align;
17059
17060   /* Can't use this if the user has appropriated esi or edi.  */
17061   if (global_regs[4] || global_regs[5])
17062     FAIL;
17063
17064   out = operands[0];
17065   if (GET_CODE (out) != REG)
17066     out = gen_reg_rtx (SImode);
17067
17068   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17069   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17070   if (addr1 != XEXP (operands[1], 0))
17071     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17072   if (addr2 != XEXP (operands[2], 0))
17073     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17074
17075   count = operands[3];
17076   countreg = ix86_zero_extend_to_Pmode (count);
17077
17078   /* %%% Iff we are testing strict equality, we can use known alignment
17079      to good advantage.  This may be possible with combine, particularly
17080      once cc0 is dead.  */
17081   align = operands[4];
17082
17083   emit_insn (gen_cld ());
17084   if (GET_CODE (count) == CONST_INT)
17085     {
17086       if (INTVAL (count) == 0)
17087         {
17088           emit_move_insn (operands[0], const0_rtx);
17089           DONE;
17090         }
17091       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17092                                     operands[1], operands[2]));
17093     }
17094   else
17095     {
17096       if (TARGET_64BIT)
17097         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17098       else
17099         emit_insn (gen_cmpsi_1 (countreg, countreg));
17100       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17101                                  operands[1], operands[2]));
17102     }
17103
17104   outlow = gen_lowpart (QImode, out);
17105   emit_insn (gen_cmpintqi (outlow));
17106   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17107
17108   if (operands[0] != out)
17109     emit_move_insn (operands[0], out);
17110
17111   DONE;
17112 })
17113
17114 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17115
17116 (define_expand "cmpintqi"
17117   [(set (match_dup 1)
17118         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17119    (set (match_dup 2)
17120         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17121    (parallel [(set (match_operand:QI 0 "register_operand" "")
17122                    (minus:QI (match_dup 1)
17123                              (match_dup 2)))
17124               (clobber (reg:CC FLAGS_REG))])]
17125   ""
17126   "operands[1] = gen_reg_rtx (QImode);
17127    operands[2] = gen_reg_rtx (QImode);")
17128
17129 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17130 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17131
17132 (define_expand "cmpstrqi_nz_1"
17133   [(parallel [(set (reg:CC FLAGS_REG)
17134                    (compare:CC (match_operand 4 "memory_operand" "")
17135                                (match_operand 5 "memory_operand" "")))
17136               (use (match_operand 2 "register_operand" ""))
17137               (use (match_operand:SI 3 "immediate_operand" ""))
17138               (use (reg:SI DIRFLAG_REG))
17139               (clobber (match_operand 0 "register_operand" ""))
17140               (clobber (match_operand 1 "register_operand" ""))
17141               (clobber (match_dup 2))])]
17142   ""
17143   "")
17144
17145 (define_insn "*cmpstrqi_nz_1"
17146   [(set (reg:CC FLAGS_REG)
17147         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17148                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17149    (use (match_operand:SI 6 "register_operand" "2"))
17150    (use (match_operand:SI 3 "immediate_operand" "i"))
17151    (use (reg:SI DIRFLAG_REG))
17152    (clobber (match_operand:SI 0 "register_operand" "=S"))
17153    (clobber (match_operand:SI 1 "register_operand" "=D"))
17154    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17155   "!TARGET_64BIT"
17156   "repz{\;| }cmpsb"
17157   [(set_attr "type" "str")
17158    (set_attr "mode" "QI")
17159    (set_attr "prefix_rep" "1")])
17160
17161 (define_insn "*cmpstrqi_nz_rex_1"
17162   [(set (reg:CC FLAGS_REG)
17163         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17164                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17165    (use (match_operand:DI 6 "register_operand" "2"))
17166    (use (match_operand:SI 3 "immediate_operand" "i"))
17167    (use (reg:SI DIRFLAG_REG))
17168    (clobber (match_operand:DI 0 "register_operand" "=S"))
17169    (clobber (match_operand:DI 1 "register_operand" "=D"))
17170    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17171   "TARGET_64BIT"
17172   "repz{\;| }cmpsb"
17173   [(set_attr "type" "str")
17174    (set_attr "mode" "QI")
17175    (set_attr "prefix_rep" "1")])
17176
17177 ;; The same, but the count is not known to not be zero.
17178
17179 (define_expand "cmpstrqi_1"
17180   [(parallel [(set (reg:CC FLAGS_REG)
17181                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17182                                      (const_int 0))
17183                   (compare:CC (match_operand 4 "memory_operand" "")
17184                               (match_operand 5 "memory_operand" ""))
17185                   (const_int 0)))
17186               (use (match_operand:SI 3 "immediate_operand" ""))
17187               (use (reg:CC FLAGS_REG))
17188               (use (reg:SI DIRFLAG_REG))
17189               (clobber (match_operand 0 "register_operand" ""))
17190               (clobber (match_operand 1 "register_operand" ""))
17191               (clobber (match_dup 2))])]
17192   ""
17193   "")
17194
17195 (define_insn "*cmpstrqi_1"
17196   [(set (reg:CC FLAGS_REG)
17197         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17198                              (const_int 0))
17199           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17200                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17201           (const_int 0)))
17202    (use (match_operand:SI 3 "immediate_operand" "i"))
17203    (use (reg:CC FLAGS_REG))
17204    (use (reg:SI DIRFLAG_REG))
17205    (clobber (match_operand:SI 0 "register_operand" "=S"))
17206    (clobber (match_operand:SI 1 "register_operand" "=D"))
17207    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17208   "!TARGET_64BIT"
17209   "repz{\;| }cmpsb"
17210   [(set_attr "type" "str")
17211    (set_attr "mode" "QI")
17212    (set_attr "prefix_rep" "1")])
17213
17214 (define_insn "*cmpstrqi_rex_1"
17215   [(set (reg:CC FLAGS_REG)
17216         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17217                              (const_int 0))
17218           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17219                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17220           (const_int 0)))
17221    (use (match_operand:SI 3 "immediate_operand" "i"))
17222    (use (reg:CC FLAGS_REG))
17223    (use (reg:SI DIRFLAG_REG))
17224    (clobber (match_operand:DI 0 "register_operand" "=S"))
17225    (clobber (match_operand:DI 1 "register_operand" "=D"))
17226    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17227   "TARGET_64BIT"
17228   "repz{\;| }cmpsb"
17229   [(set_attr "type" "str")
17230    (set_attr "mode" "QI")
17231    (set_attr "prefix_rep" "1")])
17232
17233 (define_expand "strlensi"
17234   [(set (match_operand:SI 0 "register_operand" "")
17235         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17236                     (match_operand:QI 2 "immediate_operand" "")
17237                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17238   ""
17239 {
17240  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17241    DONE;
17242  else
17243    FAIL;
17244 })
17245
17246 (define_expand "strlendi"
17247   [(set (match_operand:DI 0 "register_operand" "")
17248         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17249                     (match_operand:QI 2 "immediate_operand" "")
17250                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17251   ""
17252 {
17253  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17254    DONE;
17255  else
17256    FAIL;
17257 })
17258
17259 (define_expand "strlenqi_1"
17260   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17261               (use (reg:SI DIRFLAG_REG))
17262               (clobber (match_operand 1 "register_operand" ""))
17263               (clobber (reg:CC FLAGS_REG))])]
17264   ""
17265   "")
17266
17267 (define_insn "*strlenqi_1"
17268   [(set (match_operand:SI 0 "register_operand" "=&c")
17269         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17270                     (match_operand:QI 2 "register_operand" "a")
17271                     (match_operand:SI 3 "immediate_operand" "i")
17272                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17273    (use (reg:SI DIRFLAG_REG))
17274    (clobber (match_operand:SI 1 "register_operand" "=D"))
17275    (clobber (reg:CC FLAGS_REG))]
17276   "!TARGET_64BIT"
17277   "repnz{\;| }scasb"
17278   [(set_attr "type" "str")
17279    (set_attr "mode" "QI")
17280    (set_attr "prefix_rep" "1")])
17281
17282 (define_insn "*strlenqi_rex_1"
17283   [(set (match_operand:DI 0 "register_operand" "=&c")
17284         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17285                     (match_operand:QI 2 "register_operand" "a")
17286                     (match_operand:DI 3 "immediate_operand" "i")
17287                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17288    (use (reg:SI DIRFLAG_REG))
17289    (clobber (match_operand:DI 1 "register_operand" "=D"))
17290    (clobber (reg:CC FLAGS_REG))]
17291   "TARGET_64BIT"
17292   "repnz{\;| }scasb"
17293   [(set_attr "type" "str")
17294    (set_attr "mode" "QI")
17295    (set_attr "prefix_rep" "1")])
17296
17297 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17298 ;; handled in combine, but it is not currently up to the task.
17299 ;; When used for their truth value, the cmpstr* expanders generate
17300 ;; code like this:
17301 ;;
17302 ;;   repz cmpsb
17303 ;;   seta       %al
17304 ;;   setb       %dl
17305 ;;   cmpb       %al, %dl
17306 ;;   jcc        label
17307 ;;
17308 ;; The intermediate three instructions are unnecessary.
17309
17310 ;; This one handles cmpstr*_nz_1...
17311 (define_peephole2
17312   [(parallel[
17313      (set (reg:CC FLAGS_REG)
17314           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17315                       (mem:BLK (match_operand 5 "register_operand" ""))))
17316      (use (match_operand 6 "register_operand" ""))
17317      (use (match_operand:SI 3 "immediate_operand" ""))
17318      (use (reg:SI DIRFLAG_REG))
17319      (clobber (match_operand 0 "register_operand" ""))
17320      (clobber (match_operand 1 "register_operand" ""))
17321      (clobber (match_operand 2 "register_operand" ""))])
17322    (set (match_operand:QI 7 "register_operand" "")
17323         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17324    (set (match_operand:QI 8 "register_operand" "")
17325         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17326    (set (reg FLAGS_REG)
17327         (compare (match_dup 7) (match_dup 8)))
17328   ]
17329   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17330   [(parallel[
17331      (set (reg:CC FLAGS_REG)
17332           (compare:CC (mem:BLK (match_dup 4))
17333                       (mem:BLK (match_dup 5))))
17334      (use (match_dup 6))
17335      (use (match_dup 3))
17336      (use (reg:SI DIRFLAG_REG))
17337      (clobber (match_dup 0))
17338      (clobber (match_dup 1))
17339      (clobber (match_dup 2))])]
17340   "")
17341
17342 ;; ...and this one handles cmpstr*_1.
17343 (define_peephole2
17344   [(parallel[
17345      (set (reg:CC FLAGS_REG)
17346           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17347                                (const_int 0))
17348             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17349                         (mem:BLK (match_operand 5 "register_operand" "")))
17350             (const_int 0)))
17351      (use (match_operand:SI 3 "immediate_operand" ""))
17352      (use (reg:CC FLAGS_REG))
17353      (use (reg:SI DIRFLAG_REG))
17354      (clobber (match_operand 0 "register_operand" ""))
17355      (clobber (match_operand 1 "register_operand" ""))
17356      (clobber (match_operand 2 "register_operand" ""))])
17357    (set (match_operand:QI 7 "register_operand" "")
17358         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17359    (set (match_operand:QI 8 "register_operand" "")
17360         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17361    (set (reg FLAGS_REG)
17362         (compare (match_dup 7) (match_dup 8)))
17363   ]
17364   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17365   [(parallel[
17366      (set (reg:CC FLAGS_REG)
17367           (if_then_else:CC (ne (match_dup 6)
17368                                (const_int 0))
17369             (compare:CC (mem:BLK (match_dup 4))
17370                         (mem:BLK (match_dup 5)))
17371             (const_int 0)))
17372      (use (match_dup 3))
17373      (use (reg:CC FLAGS_REG))
17374      (use (reg:SI DIRFLAG_REG))
17375      (clobber (match_dup 0))
17376      (clobber (match_dup 1))
17377      (clobber (match_dup 2))])]
17378   "")
17379
17380
17381 \f
17382 ;; Conditional move instructions.
17383
17384 (define_expand "movdicc"
17385   [(set (match_operand:DI 0 "register_operand" "")
17386         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17387                          (match_operand:DI 2 "general_operand" "")
17388                          (match_operand:DI 3 "general_operand" "")))]
17389   "TARGET_64BIT"
17390   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17391
17392 (define_insn "x86_movdicc_0_m1_rex64"
17393   [(set (match_operand:DI 0 "register_operand" "=r")
17394         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17395           (const_int -1)
17396           (const_int 0)))
17397    (clobber (reg:CC FLAGS_REG))]
17398   "TARGET_64BIT"
17399   "sbb{q}\t%0, %0"
17400   ; Since we don't have the proper number of operands for an alu insn,
17401   ; fill in all the blanks.
17402   [(set_attr "type" "alu")
17403    (set_attr "pent_pair" "pu")
17404    (set_attr "memory" "none")
17405    (set_attr "imm_disp" "false")
17406    (set_attr "mode" "DI")
17407    (set_attr "length_immediate" "0")])
17408
17409 (define_insn "movdicc_c_rex64"
17410   [(set (match_operand:DI 0 "register_operand" "=r,r")
17411         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17412                                 [(reg FLAGS_REG) (const_int 0)])
17413                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17414                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17415   "TARGET_64BIT && TARGET_CMOVE
17416    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17417   "@
17418    cmov%O2%C1\t{%2, %0|%0, %2}
17419    cmov%O2%c1\t{%3, %0|%0, %3}"
17420   [(set_attr "type" "icmov")
17421    (set_attr "mode" "DI")])
17422
17423 (define_expand "movsicc"
17424   [(set (match_operand:SI 0 "register_operand" "")
17425         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17426                          (match_operand:SI 2 "general_operand" "")
17427                          (match_operand:SI 3 "general_operand" "")))]
17428   ""
17429   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17430
17431 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17432 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17433 ;; So just document what we're doing explicitly.
17434
17435 (define_insn "x86_movsicc_0_m1"
17436   [(set (match_operand:SI 0 "register_operand" "=r")
17437         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17438           (const_int -1)
17439           (const_int 0)))
17440    (clobber (reg:CC FLAGS_REG))]
17441   ""
17442   "sbb{l}\t%0, %0"
17443   ; Since we don't have the proper number of operands for an alu insn,
17444   ; fill in all the blanks.
17445   [(set_attr "type" "alu")
17446    (set_attr "pent_pair" "pu")
17447    (set_attr "memory" "none")
17448    (set_attr "imm_disp" "false")
17449    (set_attr "mode" "SI")
17450    (set_attr "length_immediate" "0")])
17451
17452 (define_insn "*movsicc_noc"
17453   [(set (match_operand:SI 0 "register_operand" "=r,r")
17454         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17455                                 [(reg FLAGS_REG) (const_int 0)])
17456                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17457                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17458   "TARGET_CMOVE
17459    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17460   "@
17461    cmov%O2%C1\t{%2, %0|%0, %2}
17462    cmov%O2%c1\t{%3, %0|%0, %3}"
17463   [(set_attr "type" "icmov")
17464    (set_attr "mode" "SI")])
17465
17466 (define_expand "movhicc"
17467   [(set (match_operand:HI 0 "register_operand" "")
17468         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17469                          (match_operand:HI 2 "general_operand" "")
17470                          (match_operand:HI 3 "general_operand" "")))]
17471   "TARGET_HIMODE_MATH"
17472   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17473
17474 (define_insn "*movhicc_noc"
17475   [(set (match_operand:HI 0 "register_operand" "=r,r")
17476         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17477                                 [(reg FLAGS_REG) (const_int 0)])
17478                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17479                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17480   "TARGET_CMOVE
17481    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17482   "@
17483    cmov%O2%C1\t{%2, %0|%0, %2}
17484    cmov%O2%c1\t{%3, %0|%0, %3}"
17485   [(set_attr "type" "icmov")
17486    (set_attr "mode" "HI")])
17487
17488 (define_expand "movqicc"
17489   [(set (match_operand:QI 0 "register_operand" "")
17490         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17491                          (match_operand:QI 2 "general_operand" "")
17492                          (match_operand:QI 3 "general_operand" "")))]
17493   "TARGET_QIMODE_MATH"
17494   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17495
17496 (define_insn_and_split "*movqicc_noc"
17497   [(set (match_operand:QI 0 "register_operand" "=r,r")
17498         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17499                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17500                       (match_operand:QI 2 "register_operand" "r,0")
17501                       (match_operand:QI 3 "register_operand" "0,r")))]
17502   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17503   "#"
17504   "&& reload_completed"
17505   [(set (match_dup 0)
17506         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17507                       (match_dup 2)
17508                       (match_dup 3)))]
17509   "operands[0] = gen_lowpart (SImode, operands[0]);
17510    operands[2] = gen_lowpart (SImode, operands[2]);
17511    operands[3] = gen_lowpart (SImode, operands[3]);"
17512   [(set_attr "type" "icmov")
17513    (set_attr "mode" "SI")])
17514
17515 (define_expand "movsfcc"
17516   [(set (match_operand:SF 0 "register_operand" "")
17517         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17518                          (match_operand:SF 2 "register_operand" "")
17519                          (match_operand:SF 3 "register_operand" "")))]
17520   "TARGET_CMOVE"
17521   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17522
17523 (define_insn "*movsfcc_1"
17524   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17525         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17526                                 [(reg FLAGS_REG) (const_int 0)])
17527                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17528                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17529   "TARGET_CMOVE
17530    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17531   "@
17532    fcmov%F1\t{%2, %0|%0, %2}
17533    fcmov%f1\t{%3, %0|%0, %3}
17534    cmov%O2%C1\t{%2, %0|%0, %2}
17535    cmov%O2%c1\t{%3, %0|%0, %3}"
17536   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17537    (set_attr "mode" "SF,SF,SI,SI")])
17538
17539 (define_expand "movdfcc"
17540   [(set (match_operand:DF 0 "register_operand" "")
17541         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17542                          (match_operand:DF 2 "register_operand" "")
17543                          (match_operand:DF 3 "register_operand" "")))]
17544   "TARGET_CMOVE"
17545   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17546
17547 (define_insn "*movdfcc_1"
17548   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17549         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17550                                 [(reg FLAGS_REG) (const_int 0)])
17551                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17552                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17553   "!TARGET_64BIT && TARGET_CMOVE
17554    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17555   "@
17556    fcmov%F1\t{%2, %0|%0, %2}
17557    fcmov%f1\t{%3, %0|%0, %3}
17558    #
17559    #"
17560   [(set_attr "type" "fcmov,fcmov,multi,multi")
17561    (set_attr "mode" "DF")])
17562
17563 (define_insn "*movdfcc_1_rex64"
17564   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17565         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17566                                 [(reg FLAGS_REG) (const_int 0)])
17567                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17568                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17569   "TARGET_64BIT && TARGET_CMOVE
17570    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17571   "@
17572    fcmov%F1\t{%2, %0|%0, %2}
17573    fcmov%f1\t{%3, %0|%0, %3}
17574    cmov%O2%C1\t{%2, %0|%0, %2}
17575    cmov%O2%c1\t{%3, %0|%0, %3}"
17576   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17577    (set_attr "mode" "DF")])
17578
17579 (define_split
17580   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17581         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17582                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17583                       (match_operand:DF 2 "nonimmediate_operand" "")
17584                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17585   "!TARGET_64BIT && reload_completed"
17586   [(set (match_dup 2)
17587         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17588                       (match_dup 5)
17589                       (match_dup 7)))
17590    (set (match_dup 3)
17591         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17592                       (match_dup 6)
17593                       (match_dup 8)))]
17594   "split_di (operands+2, 1, operands+5, operands+6);
17595    split_di (operands+3, 1, operands+7, operands+8);
17596    split_di (operands, 1, operands+2, operands+3);")
17597
17598 (define_expand "movxfcc"
17599   [(set (match_operand:XF 0 "register_operand" "")
17600         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17601                          (match_operand:XF 2 "register_operand" "")
17602                          (match_operand:XF 3 "register_operand" "")))]
17603   "TARGET_CMOVE"
17604   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17605
17606 (define_insn "*movxfcc_1"
17607   [(set (match_operand:XF 0 "register_operand" "=f,f")
17608         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17609                                 [(reg FLAGS_REG) (const_int 0)])
17610                       (match_operand:XF 2 "register_operand" "f,0")
17611                       (match_operand:XF 3 "register_operand" "0,f")))]
17612   "TARGET_CMOVE"
17613   "@
17614    fcmov%F1\t{%2, %0|%0, %2}
17615    fcmov%f1\t{%3, %0|%0, %3}"
17616   [(set_attr "type" "fcmov")
17617    (set_attr "mode" "XF")])
17618
17619 (define_expand "minsf3"
17620   [(parallel [
17621      (set (match_operand:SF 0 "register_operand" "")
17622           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17623                                (match_operand:SF 2 "nonimmediate_operand" ""))
17624                            (match_dup 1)
17625                            (match_dup 2)))
17626      (clobber (reg:CC FLAGS_REG))])]
17627   "TARGET_SSE"
17628   "")
17629
17630 (define_insn "*minsf"
17631   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17632         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17633                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17634                          (match_dup 1)
17635                          (match_dup 2)))
17636    (clobber (reg:CC FLAGS_REG))]
17637   "TARGET_SSE && TARGET_IEEE_FP"
17638   "#")
17639
17640 (define_insn "*minsf_nonieee"
17641   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17642         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17643                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17644                          (match_dup 1)
17645                          (match_dup 2)))
17646    (clobber (reg:CC FLAGS_REG))]
17647   "TARGET_SSE && !TARGET_IEEE_FP
17648    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17649   "#")
17650
17651 (define_split
17652   [(set (match_operand:SF 0 "register_operand" "")
17653         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17654                              (match_operand:SF 2 "nonimmediate_operand" ""))
17655                          (match_operand:SF 3 "register_operand" "")
17656                          (match_operand:SF 4 "nonimmediate_operand" "")))
17657    (clobber (reg:CC FLAGS_REG))]
17658   "SSE_REG_P (operands[0]) && reload_completed
17659    && ((operands_match_p (operands[1], operands[3])
17660         && operands_match_p (operands[2], operands[4]))
17661        || (operands_match_p (operands[1], operands[4])
17662            && operands_match_p (operands[2], operands[3])))"
17663   [(set (match_dup 0)
17664         (if_then_else:SF (lt (match_dup 1)
17665                              (match_dup 2))
17666                          (match_dup 1)
17667                          (match_dup 2)))])
17668
17669 ;; Conditional addition patterns
17670 (define_expand "addqicc"
17671   [(match_operand:QI 0 "register_operand" "")
17672    (match_operand 1 "comparison_operator" "")
17673    (match_operand:QI 2 "register_operand" "")
17674    (match_operand:QI 3 "const_int_operand" "")]
17675   ""
17676   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17677
17678 (define_expand "addhicc"
17679   [(match_operand:HI 0 "register_operand" "")
17680    (match_operand 1 "comparison_operator" "")
17681    (match_operand:HI 2 "register_operand" "")
17682    (match_operand:HI 3 "const_int_operand" "")]
17683   ""
17684   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17685
17686 (define_expand "addsicc"
17687   [(match_operand:SI 0 "register_operand" "")
17688    (match_operand 1 "comparison_operator" "")
17689    (match_operand:SI 2 "register_operand" "")
17690    (match_operand:SI 3 "const_int_operand" "")]
17691   ""
17692   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17693
17694 (define_expand "adddicc"
17695   [(match_operand:DI 0 "register_operand" "")
17696    (match_operand 1 "comparison_operator" "")
17697    (match_operand:DI 2 "register_operand" "")
17698    (match_operand:DI 3 "const_int_operand" "")]
17699   "TARGET_64BIT"
17700   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17701
17702 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17703
17704 (define_split
17705   [(set (match_operand:SF 0 "fp_register_operand" "")
17706         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17707                              (match_operand:SF 2 "register_operand" ""))
17708                          (match_operand:SF 3 "register_operand" "")
17709                          (match_operand:SF 4 "register_operand" "")))
17710    (clobber (reg:CC FLAGS_REG))]
17711   "reload_completed
17712    && ((operands_match_p (operands[1], operands[3])
17713         && operands_match_p (operands[2], operands[4]))
17714        || (operands_match_p (operands[1], operands[4])
17715            && operands_match_p (operands[2], operands[3])))"
17716   [(set (reg:CCFP FLAGS_REG)
17717         (compare:CCFP (match_dup 2)
17718                       (match_dup 1)))
17719    (set (match_dup 0)
17720         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17721                          (match_dup 1)
17722                          (match_dup 2)))])
17723
17724 (define_insn "*minsf_sse"
17725   [(set (match_operand:SF 0 "register_operand" "=x")
17726         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17727                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17728                          (match_dup 1)
17729                          (match_dup 2)))]
17730   "TARGET_SSE && reload_completed"
17731   "minss\t{%2, %0|%0, %2}"
17732   [(set_attr "type" "sse")
17733    (set_attr "mode" "SF")])
17734
17735 (define_expand "mindf3"
17736   [(parallel [
17737      (set (match_operand:DF 0 "register_operand" "")
17738           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17739                                (match_operand:DF 2 "nonimmediate_operand" ""))
17740                            (match_dup 1)
17741                            (match_dup 2)))
17742      (clobber (reg:CC FLAGS_REG))])]
17743   "TARGET_SSE2 && TARGET_SSE_MATH"
17744   "#")
17745
17746 (define_insn "*mindf"
17747   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17748         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17749                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17750                          (match_dup 1)
17751                          (match_dup 2)))
17752    (clobber (reg:CC FLAGS_REG))]
17753   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17754   "#")
17755
17756 (define_insn "*mindf_nonieee"
17757   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17758         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17759                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17760                          (match_dup 1)
17761                          (match_dup 2)))
17762    (clobber (reg:CC FLAGS_REG))]
17763   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17764    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17765   "#")
17766
17767 (define_split
17768   [(set (match_operand:DF 0 "register_operand" "")
17769         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17770                              (match_operand:DF 2 "nonimmediate_operand" ""))
17771                          (match_operand:DF 3 "register_operand" "")
17772                          (match_operand:DF 4 "nonimmediate_operand" "")))
17773    (clobber (reg:CC FLAGS_REG))]
17774   "SSE_REG_P (operands[0]) && reload_completed
17775    && ((operands_match_p (operands[1], operands[3])
17776         && operands_match_p (operands[2], operands[4]))
17777        || (operands_match_p (operands[1], operands[4])
17778            && operands_match_p (operands[2], operands[3])))"
17779   [(set (match_dup 0)
17780         (if_then_else:DF (lt (match_dup 1)
17781                              (match_dup 2))
17782                          (match_dup 1)
17783                          (match_dup 2)))])
17784
17785 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17786 (define_split
17787   [(set (match_operand:DF 0 "fp_register_operand" "")
17788         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17789                              (match_operand:DF 2 "register_operand" ""))
17790                          (match_operand:DF 3 "register_operand" "")
17791                          (match_operand:DF 4 "register_operand" "")))
17792    (clobber (reg:CC FLAGS_REG))]
17793   "reload_completed
17794    && ((operands_match_p (operands[1], operands[3])
17795         && operands_match_p (operands[2], operands[4]))
17796        || (operands_match_p (operands[1], operands[4])
17797            && operands_match_p (operands[2], operands[3])))"
17798   [(set (reg:CCFP FLAGS_REG)
17799         (compare:CCFP (match_dup 2)
17800                       (match_dup 1)))
17801    (set (match_dup 0)
17802         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17803                          (match_dup 1)
17804                          (match_dup 2)))])
17805
17806 (define_insn "*mindf_sse"
17807   [(set (match_operand:DF 0 "register_operand" "=Y")
17808         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17809                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17810                          (match_dup 1)
17811                          (match_dup 2)))]
17812   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17813   "minsd\t{%2, %0|%0, %2}"
17814   [(set_attr "type" "sse")
17815    (set_attr "mode" "DF")])
17816
17817 (define_expand "maxsf3"
17818   [(parallel [
17819      (set (match_operand:SF 0 "register_operand" "")
17820           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17821                                (match_operand:SF 2 "nonimmediate_operand" ""))
17822                            (match_dup 1)
17823                            (match_dup 2)))
17824      (clobber (reg:CC FLAGS_REG))])]
17825   "TARGET_SSE"
17826   "#")
17827
17828 (define_insn "*maxsf"
17829   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17830         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17831                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17832                          (match_dup 1)
17833                          (match_dup 2)))
17834    (clobber (reg:CC FLAGS_REG))]
17835   "TARGET_SSE && TARGET_IEEE_FP"
17836   "#")
17837
17838 (define_insn "*maxsf_nonieee"
17839   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17840         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17841                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17842                          (match_dup 1)
17843                          (match_dup 2)))
17844    (clobber (reg:CC FLAGS_REG))]
17845   "TARGET_SSE && !TARGET_IEEE_FP
17846    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17847   "#")
17848
17849 (define_split
17850   [(set (match_operand:SF 0 "register_operand" "")
17851         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17852                              (match_operand:SF 2 "nonimmediate_operand" ""))
17853                          (match_operand:SF 3 "register_operand" "")
17854                          (match_operand:SF 4 "nonimmediate_operand" "")))
17855    (clobber (reg:CC FLAGS_REG))]
17856   "SSE_REG_P (operands[0]) && reload_completed
17857    && ((operands_match_p (operands[1], operands[3])
17858         && operands_match_p (operands[2], operands[4]))
17859        || (operands_match_p (operands[1], operands[4])
17860            && operands_match_p (operands[2], operands[3])))"
17861   [(set (match_dup 0)
17862         (if_then_else:SF (gt (match_dup 1)
17863                              (match_dup 2))
17864                          (match_dup 1)
17865                          (match_dup 2)))])
17866
17867 (define_split
17868   [(set (match_operand:SF 0 "fp_register_operand" "")
17869         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17870                              (match_operand:SF 2 "register_operand" ""))
17871                          (match_operand:SF 3 "register_operand" "")
17872                          (match_operand:SF 4 "register_operand" "")))
17873    (clobber (reg:CC FLAGS_REG))]
17874   "reload_completed
17875    && ((operands_match_p (operands[1], operands[3])
17876         && operands_match_p (operands[2], operands[4]))
17877        || (operands_match_p (operands[1], operands[4])
17878            && operands_match_p (operands[2], operands[3])))"
17879   [(set (reg:CCFP FLAGS_REG)
17880         (compare:CCFP (match_dup 1)
17881                       (match_dup 2)))
17882    (set (match_dup 0)
17883         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17884                          (match_dup 1)
17885                          (match_dup 2)))])
17886
17887 (define_insn "*maxsf_sse"
17888   [(set (match_operand:SF 0 "register_operand" "=x")
17889         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17890                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17891                          (match_dup 1)
17892                          (match_dup 2)))]
17893   "TARGET_SSE && reload_completed"
17894   "maxss\t{%2, %0|%0, %2}"
17895   [(set_attr "type" "sse")
17896    (set_attr "mode" "SF")])
17897
17898 (define_expand "maxdf3"
17899   [(parallel [
17900      (set (match_operand:DF 0 "register_operand" "")
17901           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17902                                (match_operand:DF 2 "nonimmediate_operand" ""))
17903                            (match_dup 1)
17904                            (match_dup 2)))
17905      (clobber (reg:CC FLAGS_REG))])]
17906   "TARGET_SSE2 && TARGET_SSE_MATH"
17907   "#")
17908
17909 (define_insn "*maxdf"
17910   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17911         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17912                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17913                          (match_dup 1)
17914                          (match_dup 2)))
17915    (clobber (reg:CC FLAGS_REG))]
17916   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17917   "#")
17918
17919 (define_insn "*maxdf_nonieee"
17920   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17921         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17922                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17923                          (match_dup 1)
17924                          (match_dup 2)))
17925    (clobber (reg:CC FLAGS_REG))]
17926   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17927    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17928   "#")
17929
17930 (define_split
17931   [(set (match_operand:DF 0 "register_operand" "")
17932         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17933                              (match_operand:DF 2 "nonimmediate_operand" ""))
17934                          (match_operand:DF 3 "register_operand" "")
17935                          (match_operand:DF 4 "nonimmediate_operand" "")))
17936    (clobber (reg:CC FLAGS_REG))]
17937   "SSE_REG_P (operands[0]) && reload_completed
17938    && ((operands_match_p (operands[1], operands[3])
17939         && operands_match_p (operands[2], operands[4]))
17940        || (operands_match_p (operands[1], operands[4])
17941            && operands_match_p (operands[2], operands[3])))"
17942   [(set (match_dup 0)
17943         (if_then_else:DF (gt (match_dup 1)
17944                              (match_dup 2))
17945                          (match_dup 1)
17946                          (match_dup 2)))])
17947
17948 (define_split
17949   [(set (match_operand:DF 0 "fp_register_operand" "")
17950         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17951                              (match_operand:DF 2 "register_operand" ""))
17952                          (match_operand:DF 3 "register_operand" "")
17953                          (match_operand:DF 4 "register_operand" "")))
17954    (clobber (reg:CC FLAGS_REG))]
17955   "reload_completed
17956    && ((operands_match_p (operands[1], operands[3])
17957         && operands_match_p (operands[2], operands[4]))
17958        || (operands_match_p (operands[1], operands[4])
17959            && operands_match_p (operands[2], operands[3])))"
17960   [(set (reg:CCFP FLAGS_REG)
17961         (compare:CCFP (match_dup 1)
17962                       (match_dup 2)))
17963    (set (match_dup 0)
17964         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17965                          (match_dup 1)
17966                          (match_dup 2)))])
17967
17968 (define_insn "*maxdf_sse"
17969   [(set (match_operand:DF 0 "register_operand" "=Y")
17970         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17971                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17972                          (match_dup 1)
17973                          (match_dup 2)))]
17974   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17975   "maxsd\t{%2, %0|%0, %2}"
17976   [(set_attr "type" "sse")
17977    (set_attr "mode" "DF")])
17978 \f
17979 ;; Misc patterns (?)
17980
17981 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17982 ;; Otherwise there will be nothing to keep
17983 ;; 
17984 ;; [(set (reg ebp) (reg esp))]
17985 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17986 ;;  (clobber (eflags)]
17987 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17988 ;;
17989 ;; in proper program order.
17990 (define_insn "pro_epilogue_adjust_stack_1"
17991   [(set (match_operand:SI 0 "register_operand" "=r,r")
17992         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17993                  (match_operand:SI 2 "immediate_operand" "i,i")))
17994    (clobber (reg:CC FLAGS_REG))
17995    (clobber (mem:BLK (scratch)))]
17996   "!TARGET_64BIT"
17997 {
17998   switch (get_attr_type (insn))
17999     {
18000     case TYPE_IMOV:
18001       return "mov{l}\t{%1, %0|%0, %1}";
18002
18003     case TYPE_ALU:
18004       if (GET_CODE (operands[2]) == CONST_INT
18005           && (INTVAL (operands[2]) == 128
18006               || (INTVAL (operands[2]) < 0
18007                   && INTVAL (operands[2]) != -128)))
18008         {
18009           operands[2] = GEN_INT (-INTVAL (operands[2]));
18010           return "sub{l}\t{%2, %0|%0, %2}";
18011         }
18012       return "add{l}\t{%2, %0|%0, %2}";
18013
18014     case TYPE_LEA:
18015       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18016       return "lea{l}\t{%a2, %0|%0, %a2}";
18017
18018     default:
18019       abort ();
18020     }
18021 }
18022   [(set (attr "type")
18023         (cond [(eq_attr "alternative" "0")
18024                  (const_string "alu")
18025                (match_operand:SI 2 "const0_operand" "")
18026                  (const_string "imov")
18027               ]
18028               (const_string "lea")))
18029    (set_attr "mode" "SI")])
18030
18031 (define_insn "pro_epilogue_adjust_stack_rex64"
18032   [(set (match_operand:DI 0 "register_operand" "=r,r")
18033         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18034                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18035    (clobber (reg:CC FLAGS_REG))
18036    (clobber (mem:BLK (scratch)))]
18037   "TARGET_64BIT"
18038 {
18039   switch (get_attr_type (insn))
18040     {
18041     case TYPE_IMOV:
18042       return "mov{q}\t{%1, %0|%0, %1}";
18043
18044     case TYPE_ALU:
18045       if (GET_CODE (operands[2]) == CONST_INT
18046           /* Avoid overflows.  */
18047           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18048           && (INTVAL (operands[2]) == 128
18049               || (INTVAL (operands[2]) < 0
18050                   && INTVAL (operands[2]) != -128)))
18051         {
18052           operands[2] = GEN_INT (-INTVAL (operands[2]));
18053           return "sub{q}\t{%2, %0|%0, %2}";
18054         }
18055       return "add{q}\t{%2, %0|%0, %2}";
18056
18057     case TYPE_LEA:
18058       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18059       return "lea{q}\t{%a2, %0|%0, %a2}";
18060
18061     default:
18062       abort ();
18063     }
18064 }
18065   [(set (attr "type")
18066         (cond [(eq_attr "alternative" "0")
18067                  (const_string "alu")
18068                (match_operand:DI 2 "const0_operand" "")
18069                  (const_string "imov")
18070               ]
18071               (const_string "lea")))
18072    (set_attr "mode" "DI")])
18073
18074 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18075   [(set (match_operand:DI 0 "register_operand" "=r,r")
18076         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18077                  (match_operand:DI 3 "immediate_operand" "i,i")))
18078    (use (match_operand:DI 2 "register_operand" "r,r"))
18079    (clobber (reg:CC FLAGS_REG))
18080    (clobber (mem:BLK (scratch)))]
18081   "TARGET_64BIT"
18082 {
18083   switch (get_attr_type (insn))
18084     {
18085     case TYPE_ALU:
18086       return "add{q}\t{%2, %0|%0, %2}";
18087
18088     case TYPE_LEA:
18089       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18090       return "lea{q}\t{%a2, %0|%0, %a2}";
18091
18092     default:
18093       abort ();
18094     }
18095 }
18096   [(set_attr "type" "alu,lea")
18097    (set_attr "mode" "DI")])
18098
18099 ;; Placeholder for the conditional moves.  This one is split either to SSE
18100 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18101 ;; fact is that compares supported by the cmp??ss instructions are exactly
18102 ;; swapped of those supported by cmove sequence.
18103 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18104 ;; supported by i387 comparisons and we do need to emit two conditional moves
18105 ;; in tandem.
18106
18107 (define_insn "sse_movsfcc"
18108   [(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")
18109         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18110                         [(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")
18111                          (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")])
18112                       (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")
18113                       (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")))
18114    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18115    (clobber (reg:CC FLAGS_REG))]
18116   "TARGET_SSE
18117    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18118    /* Avoid combine from being smart and converting min/max
18119       instruction patterns into conditional moves.  */
18120    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18121         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18122        || !rtx_equal_p (operands[4], operands[2])
18123        || !rtx_equal_p (operands[5], operands[3]))
18124    && (!TARGET_IEEE_FP
18125        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18126   "#")
18127
18128 (define_insn "sse_movsfcc_eq"
18129   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18130         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18131                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18132                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18133                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18134    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18135    (clobber (reg:CC FLAGS_REG))]
18136   "TARGET_SSE
18137    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18138   "#")
18139
18140 (define_insn "sse_movdfcc"
18141   [(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")
18142         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18143                         [(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")
18144                          (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")])
18145                       (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")
18146                       (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")))
18147    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18148    (clobber (reg:CC FLAGS_REG))]
18149   "TARGET_SSE2
18150    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18151    /* Avoid combine from being smart and converting min/max
18152       instruction patterns into conditional moves.  */
18153    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18154         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18155        || !rtx_equal_p (operands[4], operands[2])
18156        || !rtx_equal_p (operands[5], operands[3]))
18157    && (!TARGET_IEEE_FP
18158        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18159   "#")
18160
18161 (define_insn "sse_movdfcc_eq"
18162   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18163         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18164                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18165                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18166                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18167    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18168    (clobber (reg:CC FLAGS_REG))]
18169   "TARGET_SSE
18170    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18171   "#")
18172
18173 ;; For non-sse moves just expand the usual cmove sequence.
18174 (define_split
18175   [(set (match_operand 0 "register_operand" "")
18176         (if_then_else (match_operator 1 "comparison_operator"
18177                         [(match_operand 4 "nonimmediate_operand" "")
18178                          (match_operand 5 "register_operand" "")])
18179                       (match_operand 2 "nonimmediate_operand" "")
18180                       (match_operand 3 "nonimmediate_operand" "")))
18181    (clobber (match_operand 6 "" ""))
18182    (clobber (reg:CC FLAGS_REG))]
18183   "!SSE_REG_P (operands[0]) && reload_completed
18184    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18185   [(const_int 0)]
18186 {
18187    ix86_compare_op0 = operands[5];
18188    ix86_compare_op1 = operands[4];
18189    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18190                                  VOIDmode, operands[5], operands[4]);
18191    ix86_expand_fp_movcc (operands);
18192    DONE;
18193 })
18194
18195 ;; Split SSE based conditional move into sequence:
18196 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18197 ;; and   op2, op0   -  zero op2 if comparison was false
18198 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18199 ;; or    op2, op0   -  get the nonzero one into the result.
18200 (define_split
18201   [(set (match_operand:SF 0 "register_operand" "")
18202         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18203                         [(match_operand:SF 4 "register_operand" "")
18204                          (match_operand:SF 5 "nonimmediate_operand" "")])
18205                       (match_operand:SF 2 "register_operand" "")
18206                       (match_operand:SF 3 "register_operand" "")))
18207    (clobber (match_operand 6 "" ""))
18208    (clobber (reg:CC FLAGS_REG))]
18209   "SSE_REG_P (operands[0]) && reload_completed"
18210   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18211    (set (match_dup 2) (and:V4SF (match_dup 2)
18212                                 (match_dup 8)))
18213    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18214                                           (match_dup 3)))
18215    (set (match_dup 0) (ior:V4SF (match_dup 6)
18216                                 (match_dup 7)))]
18217 {
18218   /* If op2 == op3, op3 would be clobbered before it is used.  */
18219   if (operands_match_p (operands[2], operands[3]))
18220     {
18221       emit_move_insn (operands[0], operands[2]);
18222       DONE;
18223     }
18224
18225   PUT_MODE (operands[1], GET_MODE (operands[0]));
18226   if (operands_match_p (operands[0], operands[4]))
18227     operands[6] = operands[4], operands[7] = operands[2];
18228   else
18229     operands[6] = operands[2], operands[7] = operands[4];
18230   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18231   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18232   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18233   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18234   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18235   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18236 })
18237
18238 (define_split
18239   [(set (match_operand:DF 0 "register_operand" "")
18240         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18241                         [(match_operand:DF 4 "register_operand" "")
18242                          (match_operand:DF 5 "nonimmediate_operand" "")])
18243                       (match_operand:DF 2 "register_operand" "")
18244                       (match_operand:DF 3 "register_operand" "")))
18245    (clobber (match_operand 6 "" ""))
18246    (clobber (reg:CC FLAGS_REG))]
18247   "SSE_REG_P (operands[0]) && reload_completed"
18248   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18249    (set (match_dup 2) (and:V2DF (match_dup 2)
18250                                 (match_dup 8)))
18251    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18252                                           (match_dup 3)))
18253    (set (match_dup 0) (ior:V2DF (match_dup 6)
18254                                 (match_dup 7)))]
18255 {
18256   if (GET_MODE (operands[2]) == DFmode
18257       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18258     {
18259       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18260       emit_insn (gen_sse2_unpcklpd (op, op, op));
18261       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18262       emit_insn (gen_sse2_unpcklpd (op, op, op));
18263     }
18264
18265   /* If op2 == op3, op3 would be clobbered before it is used.  */
18266   if (operands_match_p (operands[2], operands[3]))
18267     {
18268       emit_move_insn (operands[0], operands[2]);
18269       DONE;
18270     }
18271
18272   PUT_MODE (operands[1], GET_MODE (operands[0]));
18273   if (operands_match_p (operands[0], operands[4]))
18274     operands[6] = operands[4], operands[7] = operands[2];
18275   else
18276     operands[6] = operands[2], operands[7] = operands[4];
18277   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18278   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18279   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18280   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18281   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18282   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18283 })
18284
18285 ;; Special case of conditional move we can handle effectively.
18286 ;; Do not brother with the integer/floating point case, since these are
18287 ;; bot considerably slower, unlike in the generic case.
18288 (define_insn "*sse_movsfcc_const0_1"
18289   [(set (match_operand:SF 0 "register_operand" "=&x")
18290         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18291                         [(match_operand:SF 4 "register_operand" "0")
18292                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18293                       (match_operand:SF 2 "register_operand" "x")
18294                       (match_operand:SF 3 "const0_operand" "X")))]
18295   "TARGET_SSE"
18296   "#")
18297
18298 (define_insn "*sse_movsfcc_const0_2"
18299   [(set (match_operand:SF 0 "register_operand" "=&x")
18300         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18301                         [(match_operand:SF 4 "register_operand" "0")
18302                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18303                       (match_operand:SF 2 "const0_operand" "X")
18304                       (match_operand:SF 3 "register_operand" "x")))]
18305   "TARGET_SSE"
18306   "#")
18307
18308 (define_insn "*sse_movsfcc_const0_3"
18309   [(set (match_operand:SF 0 "register_operand" "=&x")
18310         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18311                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18312                          (match_operand:SF 5 "register_operand" "0")])
18313                       (match_operand:SF 2 "register_operand" "x")
18314                       (match_operand:SF 3 "const0_operand" "X")))]
18315   "TARGET_SSE"
18316   "#")
18317
18318 (define_insn "*sse_movsfcc_const0_4"
18319   [(set (match_operand:SF 0 "register_operand" "=&x")
18320         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18321                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18322                          (match_operand:SF 5 "register_operand" "0")])
18323                       (match_operand:SF 2 "const0_operand" "X")
18324                       (match_operand:SF 3 "register_operand" "x")))]
18325   "TARGET_SSE"
18326   "#")
18327
18328 (define_insn "*sse_movdfcc_const0_1"
18329   [(set (match_operand:DF 0 "register_operand" "=&Y")
18330         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18331                         [(match_operand:DF 4 "register_operand" "0")
18332                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18333                       (match_operand:DF 2 "register_operand" "Y")
18334                       (match_operand:DF 3 "const0_operand" "X")))]
18335   "TARGET_SSE2"
18336   "#")
18337
18338 (define_insn "*sse_movdfcc_const0_2"
18339   [(set (match_operand:DF 0 "register_operand" "=&Y")
18340         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18341                         [(match_operand:DF 4 "register_operand" "0")
18342                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18343                       (match_operand:DF 2 "const0_operand" "X")
18344                       (match_operand:DF 3 "register_operand" "Y")))]
18345   "TARGET_SSE2"
18346   "#")
18347
18348 (define_insn "*sse_movdfcc_const0_3"
18349   [(set (match_operand:DF 0 "register_operand" "=&Y")
18350         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18351                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18352                          (match_operand:DF 5 "register_operand" "0")])
18353                       (match_operand:DF 2 "register_operand" "Y")
18354                       (match_operand:DF 3 "const0_operand" "X")))]
18355   "TARGET_SSE2"
18356   "#")
18357
18358 (define_insn "*sse_movdfcc_const0_4"
18359   [(set (match_operand:DF 0 "register_operand" "=&Y")
18360         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18361                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18362                          (match_operand:DF 5 "register_operand" "0")])
18363                       (match_operand:DF 2 "const0_operand" "X")
18364                       (match_operand:DF 3 "register_operand" "Y")))]
18365   "TARGET_SSE2"
18366   "#")
18367
18368 (define_split
18369   [(set (match_operand:SF 0 "register_operand" "")
18370         (if_then_else (match_operator 1 "comparison_operator"
18371                         [(match_operand:SF 4 "nonimmediate_operand" "")
18372                          (match_operand:SF 5 "nonimmediate_operand" "")])
18373                       (match_operand:SF 2 "nonmemory_operand" "")
18374                       (match_operand:SF 3 "nonmemory_operand" "")))]
18375   "SSE_REG_P (operands[0]) && reload_completed
18376    && (const0_operand (operands[2], GET_MODE (operands[0]))
18377        || const0_operand (operands[3], GET_MODE (operands[0])))"
18378   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18379    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18380 {
18381   PUT_MODE (operands[1], GET_MODE (operands[0]));
18382   if (!sse_comparison_operator (operands[1], VOIDmode)
18383       || !rtx_equal_p (operands[0], operands[4]))
18384     {
18385       rtx tmp = operands[5];
18386       operands[5] = operands[4];
18387       operands[4] = tmp;
18388       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18389     }
18390   if (!rtx_equal_p (operands[0], operands[4]))
18391     abort ();
18392   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18393   if (const0_operand (operands[2], GET_MODE (operands[2])))
18394     {
18395       operands[7] = operands[3];
18396       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18397     }
18398   else
18399     {
18400       operands[7] = operands[2];
18401       operands[6] = operands[8];
18402     }
18403   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18404 })
18405
18406 (define_split
18407   [(set (match_operand:DF 0 "register_operand" "")
18408         (if_then_else (match_operator 1 "comparison_operator"
18409                         [(match_operand:DF 4 "nonimmediate_operand" "")
18410                          (match_operand:DF 5 "nonimmediate_operand" "")])
18411                       (match_operand:DF 2 "nonmemory_operand" "")
18412                       (match_operand:DF 3 "nonmemory_operand" "")))]
18413   "SSE_REG_P (operands[0]) && reload_completed
18414    && (const0_operand (operands[2], GET_MODE (operands[0]))
18415        || const0_operand (operands[3], GET_MODE (operands[0])))"
18416   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18417    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18418 {
18419   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18420       && GET_MODE (operands[2]) == DFmode)
18421     {
18422       if (REG_P (operands[2]))
18423         {
18424           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18425           emit_insn (gen_sse2_unpcklpd (op, op, op));
18426         }
18427       if (REG_P (operands[3]))
18428         {
18429           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18430           emit_insn (gen_sse2_unpcklpd (op, op, op));
18431         }
18432     }
18433   PUT_MODE (operands[1], GET_MODE (operands[0]));
18434   if (!sse_comparison_operator (operands[1], VOIDmode)
18435       || !rtx_equal_p (operands[0], operands[4]))
18436     {
18437       rtx tmp = operands[5];
18438       operands[5] = operands[4];
18439       operands[4] = tmp;
18440       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18441     }
18442   if (!rtx_equal_p (operands[0], operands[4]))
18443     abort ();
18444   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18445   if (const0_operand (operands[2], GET_MODE (operands[2])))
18446     {
18447       operands[7] = operands[3];
18448       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18449     }
18450   else
18451     {
18452       operands[7] = operands[2];
18453       operands[6] = operands[8];
18454     }
18455   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18456 })
18457
18458 (define_expand "allocate_stack_worker"
18459   [(match_operand:SI 0 "register_operand" "")]
18460   "TARGET_STACK_PROBE"
18461 {
18462   if (reload_completed)
18463     {
18464       if (TARGET_64BIT)
18465         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18466       else
18467         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18468     }
18469   else
18470     {
18471       if (TARGET_64BIT)
18472         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18473       else
18474         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18475     }
18476   DONE;
18477 })
18478
18479 (define_insn "allocate_stack_worker_1"
18480   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18481     UNSPECV_STACK_PROBE)
18482    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18483    (clobber (match_scratch:SI 1 "=0"))
18484    (clobber (reg:CC FLAGS_REG))]
18485   "!TARGET_64BIT && TARGET_STACK_PROBE"
18486   "call\t__alloca"
18487   [(set_attr "type" "multi")
18488    (set_attr "length" "5")])
18489
18490 (define_expand "allocate_stack_worker_postreload"
18491   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18492                                     UNSPECV_STACK_PROBE)
18493               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18494               (clobber (match_dup 0))
18495               (clobber (reg:CC FLAGS_REG))])]
18496   ""
18497   "")
18498
18499 (define_insn "allocate_stack_worker_rex64"
18500   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18501     UNSPECV_STACK_PROBE)
18502    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18503    (clobber (match_scratch:DI 1 "=0"))
18504    (clobber (reg:CC FLAGS_REG))]
18505   "TARGET_64BIT && TARGET_STACK_PROBE"
18506   "call\t__alloca"
18507   [(set_attr "type" "multi")
18508    (set_attr "length" "5")])
18509
18510 (define_expand "allocate_stack_worker_rex64_postreload"
18511   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18512                                     UNSPECV_STACK_PROBE)
18513               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18514               (clobber (match_dup 0))
18515               (clobber (reg:CC FLAGS_REG))])]
18516   ""
18517   "")
18518
18519 (define_expand "allocate_stack"
18520   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18521                    (minus:SI (reg:SI SP_REG)
18522                              (match_operand:SI 1 "general_operand" "")))
18523               (clobber (reg:CC FLAGS_REG))])
18524    (parallel [(set (reg:SI SP_REG)
18525                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18526               (clobber (reg:CC FLAGS_REG))])]
18527   "TARGET_STACK_PROBE"
18528 {
18529 #ifdef CHECK_STACK_LIMIT
18530   if (GET_CODE (operands[1]) == CONST_INT
18531       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18532     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18533                            operands[1]));
18534   else 
18535 #endif
18536     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18537                                                             operands[1])));
18538
18539   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18540   DONE;
18541 })
18542
18543 (define_expand "builtin_setjmp_receiver"
18544   [(label_ref (match_operand 0 "" ""))]
18545   "!TARGET_64BIT && flag_pic"
18546 {
18547   emit_insn (gen_set_got (pic_offset_table_rtx));
18548   DONE;
18549 })
18550 \f
18551 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18552
18553 (define_split
18554   [(set (match_operand 0 "register_operand" "")
18555         (match_operator 3 "promotable_binary_operator"
18556            [(match_operand 1 "register_operand" "")
18557             (match_operand 2 "aligned_operand" "")]))
18558    (clobber (reg:CC FLAGS_REG))]
18559   "! TARGET_PARTIAL_REG_STALL && reload_completed
18560    && ((GET_MODE (operands[0]) == HImode 
18561         && ((!optimize_size && !TARGET_FAST_PREFIX)
18562             || GET_CODE (operands[2]) != CONST_INT
18563             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18564        || (GET_MODE (operands[0]) == QImode 
18565            && (TARGET_PROMOTE_QImode || optimize_size)))"
18566   [(parallel [(set (match_dup 0)
18567                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18568               (clobber (reg:CC FLAGS_REG))])]
18569   "operands[0] = gen_lowpart (SImode, operands[0]);
18570    operands[1] = gen_lowpart (SImode, operands[1]);
18571    if (GET_CODE (operands[3]) != ASHIFT)
18572      operands[2] = gen_lowpart (SImode, operands[2]);
18573    PUT_MODE (operands[3], SImode);")
18574
18575 ; Promote the QImode tests, as i386 has encoding of the AND
18576 ; instruction with 32-bit sign-extended immediate and thus the
18577 ; instruction size is unchanged, except in the %eax case for
18578 ; which it is increased by one byte, hence the ! optimize_size.
18579 (define_split
18580   [(set (match_operand 0 "flags_reg_operand" "")
18581         (match_operator 2 "compare_operator"
18582           [(and (match_operand 3 "aligned_operand" "")
18583                 (match_operand 4 "const_int_operand" ""))
18584            (const_int 0)]))
18585    (set (match_operand 1 "register_operand" "")
18586         (and (match_dup 3) (match_dup 4)))]
18587   "! TARGET_PARTIAL_REG_STALL && reload_completed
18588    /* Ensure that the operand will remain sign-extended immediate.  */
18589    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18590    && ! optimize_size
18591    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18592        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18593   [(parallel [(set (match_dup 0)
18594                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18595                                     (const_int 0)]))
18596               (set (match_dup 1)
18597                    (and:SI (match_dup 3) (match_dup 4)))])]
18598 {
18599   operands[4]
18600     = gen_int_mode (INTVAL (operands[4])
18601                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18602   operands[1] = gen_lowpart (SImode, operands[1]);
18603   operands[3] = gen_lowpart (SImode, operands[3]);
18604 })
18605
18606 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18607 ; the TEST instruction with 32-bit sign-extended immediate and thus
18608 ; the instruction size would at least double, which is not what we
18609 ; want even with ! optimize_size.
18610 (define_split
18611   [(set (match_operand 0 "flags_reg_operand" "")
18612         (match_operator 1 "compare_operator"
18613           [(and (match_operand:HI 2 "aligned_operand" "")
18614                 (match_operand:HI 3 "const_int_operand" ""))
18615            (const_int 0)]))]
18616   "! TARGET_PARTIAL_REG_STALL && reload_completed
18617    /* Ensure that the operand will remain sign-extended immediate.  */
18618    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18619    && ! TARGET_FAST_PREFIX
18620    && ! optimize_size"
18621   [(set (match_dup 0)
18622         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18623                          (const_int 0)]))]
18624 {
18625   operands[3]
18626     = gen_int_mode (INTVAL (operands[3])
18627                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18628   operands[2] = gen_lowpart (SImode, operands[2]);
18629 })
18630
18631 (define_split
18632   [(set (match_operand 0 "register_operand" "")
18633         (neg (match_operand 1 "register_operand" "")))
18634    (clobber (reg:CC FLAGS_REG))]
18635   "! TARGET_PARTIAL_REG_STALL && reload_completed
18636    && (GET_MODE (operands[0]) == HImode
18637        || (GET_MODE (operands[0]) == QImode 
18638            && (TARGET_PROMOTE_QImode || optimize_size)))"
18639   [(parallel [(set (match_dup 0)
18640                    (neg:SI (match_dup 1)))
18641               (clobber (reg:CC FLAGS_REG))])]
18642   "operands[0] = gen_lowpart (SImode, operands[0]);
18643    operands[1] = gen_lowpart (SImode, operands[1]);")
18644
18645 (define_split
18646   [(set (match_operand 0 "register_operand" "")
18647         (not (match_operand 1 "register_operand" "")))]
18648   "! TARGET_PARTIAL_REG_STALL && reload_completed
18649    && (GET_MODE (operands[0]) == HImode
18650        || (GET_MODE (operands[0]) == QImode 
18651            && (TARGET_PROMOTE_QImode || optimize_size)))"
18652   [(set (match_dup 0)
18653         (not:SI (match_dup 1)))]
18654   "operands[0] = gen_lowpart (SImode, operands[0]);
18655    operands[1] = gen_lowpart (SImode, operands[1]);")
18656
18657 (define_split 
18658   [(set (match_operand 0 "register_operand" "")
18659         (if_then_else (match_operator 1 "comparison_operator" 
18660                                 [(reg FLAGS_REG) (const_int 0)])
18661                       (match_operand 2 "register_operand" "")
18662                       (match_operand 3 "register_operand" "")))]
18663   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18664    && (GET_MODE (operands[0]) == HImode
18665        || (GET_MODE (operands[0]) == QImode 
18666            && (TARGET_PROMOTE_QImode || optimize_size)))"
18667   [(set (match_dup 0)
18668         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18669   "operands[0] = gen_lowpart (SImode, operands[0]);
18670    operands[2] = gen_lowpart (SImode, operands[2]);
18671    operands[3] = gen_lowpart (SImode, operands[3]);")
18672                         
18673 \f
18674 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18675 ;; transform a complex memory operation into two memory to register operations.
18676
18677 ;; Don't push memory operands
18678 (define_peephole2
18679   [(set (match_operand:SI 0 "push_operand" "")
18680         (match_operand:SI 1 "memory_operand" ""))
18681    (match_scratch:SI 2 "r")]
18682   "! optimize_size && ! TARGET_PUSH_MEMORY"
18683   [(set (match_dup 2) (match_dup 1))
18684    (set (match_dup 0) (match_dup 2))]
18685   "")
18686
18687 (define_peephole2
18688   [(set (match_operand:DI 0 "push_operand" "")
18689         (match_operand:DI 1 "memory_operand" ""))
18690    (match_scratch:DI 2 "r")]
18691   "! optimize_size && ! TARGET_PUSH_MEMORY"
18692   [(set (match_dup 2) (match_dup 1))
18693    (set (match_dup 0) (match_dup 2))]
18694   "")
18695
18696 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18697 ;; SImode pushes.
18698 (define_peephole2
18699   [(set (match_operand:SF 0 "push_operand" "")
18700         (match_operand:SF 1 "memory_operand" ""))
18701    (match_scratch:SF 2 "r")]
18702   "! optimize_size && ! TARGET_PUSH_MEMORY"
18703   [(set (match_dup 2) (match_dup 1))
18704    (set (match_dup 0) (match_dup 2))]
18705   "")
18706
18707 (define_peephole2
18708   [(set (match_operand:HI 0 "push_operand" "")
18709         (match_operand:HI 1 "memory_operand" ""))
18710    (match_scratch:HI 2 "r")]
18711   "! optimize_size && ! TARGET_PUSH_MEMORY"
18712   [(set (match_dup 2) (match_dup 1))
18713    (set (match_dup 0) (match_dup 2))]
18714   "")
18715
18716 (define_peephole2
18717   [(set (match_operand:QI 0 "push_operand" "")
18718         (match_operand:QI 1 "memory_operand" ""))
18719    (match_scratch:QI 2 "q")]
18720   "! optimize_size && ! TARGET_PUSH_MEMORY"
18721   [(set (match_dup 2) (match_dup 1))
18722    (set (match_dup 0) (match_dup 2))]
18723   "")
18724
18725 ;; Don't move an immediate directly to memory when the instruction
18726 ;; gets too big.
18727 (define_peephole2
18728   [(match_scratch:SI 1 "r")
18729    (set (match_operand:SI 0 "memory_operand" "")
18730         (const_int 0))]
18731   "! optimize_size
18732    && ! TARGET_USE_MOV0
18733    && TARGET_SPLIT_LONG_MOVES
18734    && get_attr_length (insn) >= ix86_cost->large_insn
18735    && peep2_regno_dead_p (0, FLAGS_REG)"
18736   [(parallel [(set (match_dup 1) (const_int 0))
18737               (clobber (reg:CC FLAGS_REG))])
18738    (set (match_dup 0) (match_dup 1))]
18739   "")
18740
18741 (define_peephole2
18742   [(match_scratch:HI 1 "r")
18743    (set (match_operand:HI 0 "memory_operand" "")
18744         (const_int 0))]
18745   "! optimize_size
18746    && ! TARGET_USE_MOV0
18747    && TARGET_SPLIT_LONG_MOVES
18748    && get_attr_length (insn) >= ix86_cost->large_insn
18749    && peep2_regno_dead_p (0, FLAGS_REG)"
18750   [(parallel [(set (match_dup 2) (const_int 0))
18751               (clobber (reg:CC FLAGS_REG))])
18752    (set (match_dup 0) (match_dup 1))]
18753   "operands[2] = gen_lowpart (SImode, operands[1]);")
18754
18755 (define_peephole2
18756   [(match_scratch:QI 1 "q")
18757    (set (match_operand:QI 0 "memory_operand" "")
18758         (const_int 0))]
18759   "! optimize_size
18760    && ! TARGET_USE_MOV0
18761    && TARGET_SPLIT_LONG_MOVES
18762    && get_attr_length (insn) >= ix86_cost->large_insn
18763    && peep2_regno_dead_p (0, FLAGS_REG)"
18764   [(parallel [(set (match_dup 2) (const_int 0))
18765               (clobber (reg:CC FLAGS_REG))])
18766    (set (match_dup 0) (match_dup 1))]
18767   "operands[2] = gen_lowpart (SImode, operands[1]);")
18768
18769 (define_peephole2
18770   [(match_scratch:SI 2 "r")
18771    (set (match_operand:SI 0 "memory_operand" "")
18772         (match_operand:SI 1 "immediate_operand" ""))]
18773   "! optimize_size
18774    && get_attr_length (insn) >= ix86_cost->large_insn
18775    && TARGET_SPLIT_LONG_MOVES"
18776   [(set (match_dup 2) (match_dup 1))
18777    (set (match_dup 0) (match_dup 2))]
18778   "")
18779
18780 (define_peephole2
18781   [(match_scratch:HI 2 "r")
18782    (set (match_operand:HI 0 "memory_operand" "")
18783         (match_operand:HI 1 "immediate_operand" ""))]
18784   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18785   && TARGET_SPLIT_LONG_MOVES"
18786   [(set (match_dup 2) (match_dup 1))
18787    (set (match_dup 0) (match_dup 2))]
18788   "")
18789
18790 (define_peephole2
18791   [(match_scratch:QI 2 "q")
18792    (set (match_operand:QI 0 "memory_operand" "")
18793         (match_operand:QI 1 "immediate_operand" ""))]
18794   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18795   && TARGET_SPLIT_LONG_MOVES"
18796   [(set (match_dup 2) (match_dup 1))
18797    (set (match_dup 0) (match_dup 2))]
18798   "")
18799
18800 ;; Don't compare memory with zero, load and use a test instead.
18801 (define_peephole2
18802   [(set (match_operand 0 "flags_reg_operand" "")
18803         (match_operator 1 "compare_operator"
18804           [(match_operand:SI 2 "memory_operand" "")
18805            (const_int 0)]))
18806    (match_scratch:SI 3 "r")]
18807   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18808   [(set (match_dup 3) (match_dup 2))
18809    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18810   "")
18811
18812 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18813 ;; Don't split NOTs with a displacement operand, because resulting XOR
18814 ;; will not be pairable anyway.
18815 ;;
18816 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18817 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18818 ;; so this split helps here as well.
18819 ;;
18820 ;; Note: Can't do this as a regular split because we can't get proper
18821 ;; lifetime information then.
18822
18823 (define_peephole2
18824   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18825         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18826   "!optimize_size
18827    && peep2_regno_dead_p (0, FLAGS_REG)
18828    && ((TARGET_PENTIUM 
18829         && (GET_CODE (operands[0]) != MEM
18830             || !memory_displacement_operand (operands[0], SImode)))
18831        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18832   [(parallel [(set (match_dup 0)
18833                    (xor:SI (match_dup 1) (const_int -1)))
18834               (clobber (reg:CC FLAGS_REG))])]
18835   "")
18836
18837 (define_peephole2
18838   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18839         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18840   "!optimize_size
18841    && peep2_regno_dead_p (0, FLAGS_REG)
18842    && ((TARGET_PENTIUM 
18843         && (GET_CODE (operands[0]) != MEM
18844             || !memory_displacement_operand (operands[0], HImode)))
18845        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18846   [(parallel [(set (match_dup 0)
18847                    (xor:HI (match_dup 1) (const_int -1)))
18848               (clobber (reg:CC FLAGS_REG))])]
18849   "")
18850
18851 (define_peephole2
18852   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18853         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18854   "!optimize_size
18855    && peep2_regno_dead_p (0, FLAGS_REG)
18856    && ((TARGET_PENTIUM 
18857         && (GET_CODE (operands[0]) != MEM
18858             || !memory_displacement_operand (operands[0], QImode)))
18859        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18860   [(parallel [(set (match_dup 0)
18861                    (xor:QI (match_dup 1) (const_int -1)))
18862               (clobber (reg:CC FLAGS_REG))])]
18863   "")
18864
18865 ;; Non pairable "test imm, reg" instructions can be translated to
18866 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18867 ;; byte opcode instead of two, have a short form for byte operands),
18868 ;; so do it for other CPUs as well.  Given that the value was dead,
18869 ;; this should not create any new dependencies.  Pass on the sub-word
18870 ;; versions if we're concerned about partial register stalls.
18871
18872 (define_peephole2
18873   [(set (match_operand 0 "flags_reg_operand" "")
18874         (match_operator 1 "compare_operator"
18875           [(and:SI (match_operand:SI 2 "register_operand" "")
18876                    (match_operand:SI 3 "immediate_operand" ""))
18877            (const_int 0)]))]
18878   "ix86_match_ccmode (insn, CCNOmode)
18879    && (true_regnum (operands[2]) != 0
18880        || (GET_CODE (operands[3]) == CONST_INT
18881            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18882    && peep2_reg_dead_p (1, operands[2])"
18883   [(parallel
18884      [(set (match_dup 0)
18885            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18886                             (const_int 0)]))
18887       (set (match_dup 2)
18888            (and:SI (match_dup 2) (match_dup 3)))])]
18889   "")
18890
18891 ;; We don't need to handle HImode case, because it will be promoted to SImode
18892 ;; on ! TARGET_PARTIAL_REG_STALL
18893
18894 (define_peephole2
18895   [(set (match_operand 0 "flags_reg_operand" "")
18896         (match_operator 1 "compare_operator"
18897           [(and:QI (match_operand:QI 2 "register_operand" "")
18898                    (match_operand:QI 3 "immediate_operand" ""))
18899            (const_int 0)]))]
18900   "! TARGET_PARTIAL_REG_STALL
18901    && ix86_match_ccmode (insn, CCNOmode)
18902    && true_regnum (operands[2]) != 0
18903    && peep2_reg_dead_p (1, operands[2])"
18904   [(parallel
18905      [(set (match_dup 0)
18906            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18907                             (const_int 0)]))
18908       (set (match_dup 2)
18909            (and:QI (match_dup 2) (match_dup 3)))])]
18910   "")
18911
18912 (define_peephole2
18913   [(set (match_operand 0 "flags_reg_operand" "")
18914         (match_operator 1 "compare_operator"
18915           [(and:SI
18916              (zero_extract:SI
18917                (match_operand 2 "ext_register_operand" "")
18918                (const_int 8)
18919                (const_int 8))
18920              (match_operand 3 "const_int_operand" ""))
18921            (const_int 0)]))]
18922   "! TARGET_PARTIAL_REG_STALL
18923    && ix86_match_ccmode (insn, CCNOmode)
18924    && true_regnum (operands[2]) != 0
18925    && peep2_reg_dead_p (1, operands[2])"
18926   [(parallel [(set (match_dup 0)
18927                    (match_op_dup 1
18928                      [(and:SI
18929                         (zero_extract:SI
18930                           (match_dup 2)
18931                           (const_int 8)
18932                           (const_int 8))
18933                         (match_dup 3))
18934                       (const_int 0)]))
18935               (set (zero_extract:SI (match_dup 2)
18936                                     (const_int 8)
18937                                     (const_int 8))
18938                    (and:SI 
18939                      (zero_extract:SI
18940                        (match_dup 2)
18941                        (const_int 8)
18942                        (const_int 8))
18943                      (match_dup 3)))])]
18944   "")
18945
18946 ;; Don't do logical operations with memory inputs.
18947 (define_peephole2
18948   [(match_scratch:SI 2 "r")
18949    (parallel [(set (match_operand:SI 0 "register_operand" "")
18950                    (match_operator:SI 3 "arith_or_logical_operator"
18951                      [(match_dup 0)
18952                       (match_operand:SI 1 "memory_operand" "")]))
18953               (clobber (reg:CC FLAGS_REG))])]
18954   "! optimize_size && ! TARGET_READ_MODIFY"
18955   [(set (match_dup 2) (match_dup 1))
18956    (parallel [(set (match_dup 0)
18957                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18958               (clobber (reg:CC FLAGS_REG))])]
18959   "")
18960
18961 (define_peephole2
18962   [(match_scratch:SI 2 "r")
18963    (parallel [(set (match_operand:SI 0 "register_operand" "")
18964                    (match_operator:SI 3 "arith_or_logical_operator"
18965                      [(match_operand:SI 1 "memory_operand" "")
18966                       (match_dup 0)]))
18967               (clobber (reg:CC FLAGS_REG))])]
18968   "! optimize_size && ! TARGET_READ_MODIFY"
18969   [(set (match_dup 2) (match_dup 1))
18970    (parallel [(set (match_dup 0)
18971                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18972               (clobber (reg:CC FLAGS_REG))])]
18973   "")
18974
18975 ; Don't do logical operations with memory outputs
18976 ;
18977 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18978 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18979 ; the same decoder scheduling characteristics as the original.
18980
18981 (define_peephole2
18982   [(match_scratch:SI 2 "r")
18983    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18984                    (match_operator:SI 3 "arith_or_logical_operator"
18985                      [(match_dup 0)
18986                       (match_operand:SI 1 "nonmemory_operand" "")]))
18987               (clobber (reg:CC FLAGS_REG))])]
18988   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18989   [(set (match_dup 2) (match_dup 0))
18990    (parallel [(set (match_dup 2)
18991                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18992               (clobber (reg:CC FLAGS_REG))])
18993    (set (match_dup 0) (match_dup 2))]
18994   "")
18995
18996 (define_peephole2
18997   [(match_scratch:SI 2 "r")
18998    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18999                    (match_operator:SI 3 "arith_or_logical_operator"
19000                      [(match_operand:SI 1 "nonmemory_operand" "")
19001                       (match_dup 0)]))
19002               (clobber (reg:CC FLAGS_REG))])]
19003   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19004   [(set (match_dup 2) (match_dup 0))
19005    (parallel [(set (match_dup 2)
19006                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19007               (clobber (reg:CC FLAGS_REG))])
19008    (set (match_dup 0) (match_dup 2))]
19009   "")
19010
19011 ;; Attempt to always use XOR for zeroing registers.
19012 (define_peephole2
19013   [(set (match_operand 0 "register_operand" "")
19014         (const_int 0))]
19015   "(GET_MODE (operands[0]) == QImode
19016     || GET_MODE (operands[0]) == HImode
19017     || GET_MODE (operands[0]) == SImode
19018     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19019    && (! TARGET_USE_MOV0 || optimize_size)
19020    && peep2_regno_dead_p (0, FLAGS_REG)"
19021   [(parallel [(set (match_dup 0) (const_int 0))
19022               (clobber (reg:CC FLAGS_REG))])]
19023   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19024                               operands[0]);")
19025
19026 (define_peephole2
19027   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19028         (const_int 0))]
19029   "(GET_MODE (operands[0]) == QImode
19030     || GET_MODE (operands[0]) == HImode)
19031    && (! TARGET_USE_MOV0 || optimize_size)
19032    && peep2_regno_dead_p (0, FLAGS_REG)"
19033   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19034               (clobber (reg:CC FLAGS_REG))])])
19035
19036 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19037 (define_peephole2
19038   [(set (match_operand 0 "register_operand" "")
19039         (const_int -1))]
19040   "(GET_MODE (operands[0]) == HImode
19041     || GET_MODE (operands[0]) == SImode 
19042     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19043    && (optimize_size || TARGET_PENTIUM)
19044    && peep2_regno_dead_p (0, FLAGS_REG)"
19045   [(parallel [(set (match_dup 0) (const_int -1))
19046               (clobber (reg:CC FLAGS_REG))])]
19047   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19048                               operands[0]);")
19049
19050 ;; Attempt to convert simple leas to adds. These can be created by
19051 ;; move expanders.
19052 (define_peephole2
19053   [(set (match_operand:SI 0 "register_operand" "")
19054         (plus:SI (match_dup 0)
19055                  (match_operand:SI 1 "nonmemory_operand" "")))]
19056   "peep2_regno_dead_p (0, FLAGS_REG)"
19057   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19058               (clobber (reg:CC FLAGS_REG))])]
19059   "")
19060
19061 (define_peephole2
19062   [(set (match_operand:SI 0 "register_operand" "")
19063         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19064                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19065   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19066   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19067               (clobber (reg:CC FLAGS_REG))])]
19068   "operands[2] = gen_lowpart (SImode, operands[2]);")
19069
19070 (define_peephole2
19071   [(set (match_operand:DI 0 "register_operand" "")
19072         (plus:DI (match_dup 0)
19073                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19074   "peep2_regno_dead_p (0, FLAGS_REG)"
19075   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19076               (clobber (reg:CC FLAGS_REG))])]
19077   "")
19078
19079 (define_peephole2
19080   [(set (match_operand:SI 0 "register_operand" "")
19081         (mult:SI (match_dup 0)
19082                  (match_operand:SI 1 "const_int_operand" "")))]
19083   "exact_log2 (INTVAL (operands[1])) >= 0
19084    && peep2_regno_dead_p (0, FLAGS_REG)"
19085   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19086               (clobber (reg:CC FLAGS_REG))])]
19087   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19088
19089 (define_peephole2
19090   [(set (match_operand:DI 0 "register_operand" "")
19091         (mult:DI (match_dup 0)
19092                  (match_operand:DI 1 "const_int_operand" "")))]
19093   "exact_log2 (INTVAL (operands[1])) >= 0
19094    && peep2_regno_dead_p (0, FLAGS_REG)"
19095   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19096               (clobber (reg:CC FLAGS_REG))])]
19097   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19098
19099 (define_peephole2
19100   [(set (match_operand:SI 0 "register_operand" "")
19101         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19102                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19103   "exact_log2 (INTVAL (operands[2])) >= 0
19104    && REGNO (operands[0]) == REGNO (operands[1])
19105    && peep2_regno_dead_p (0, FLAGS_REG)"
19106   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19107               (clobber (reg:CC FLAGS_REG))])]
19108   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19109
19110 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19111 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19112 ;; many CPUs it is also faster, since special hardware to avoid esp
19113 ;; dependencies is present.
19114
19115 ;; While some of these conversions may be done using splitters, we use peepholes
19116 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19117
19118 ;; Convert prologue esp subtractions to push.
19119 ;; We need register to push.  In order to keep verify_flow_info happy we have
19120 ;; two choices
19121 ;; - use scratch and clobber it in order to avoid dependencies
19122 ;; - use already live register
19123 ;; We can't use the second way right now, since there is no reliable way how to
19124 ;; verify that given register is live.  First choice will also most likely in
19125 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19126 ;; call clobbered registers are dead.  We may want to use base pointer as an
19127 ;; alternative when no register is available later.
19128
19129 (define_peephole2
19130   [(match_scratch:SI 0 "r")
19131    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19132               (clobber (reg:CC FLAGS_REG))
19133               (clobber (mem:BLK (scratch)))])]
19134   "optimize_size || !TARGET_SUB_ESP_4"
19135   [(clobber (match_dup 0))
19136    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19137               (clobber (mem:BLK (scratch)))])])
19138
19139 (define_peephole2
19140   [(match_scratch:SI 0 "r")
19141    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19142               (clobber (reg:CC FLAGS_REG))
19143               (clobber (mem:BLK (scratch)))])]
19144   "optimize_size || !TARGET_SUB_ESP_8"
19145   [(clobber (match_dup 0))
19146    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19147    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19148               (clobber (mem:BLK (scratch)))])])
19149
19150 ;; Convert esp subtractions to push.
19151 (define_peephole2
19152   [(match_scratch:SI 0 "r")
19153    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19154               (clobber (reg:CC FLAGS_REG))])]
19155   "optimize_size || !TARGET_SUB_ESP_4"
19156   [(clobber (match_dup 0))
19157    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19158
19159 (define_peephole2
19160   [(match_scratch:SI 0 "r")
19161    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19162               (clobber (reg:CC FLAGS_REG))])]
19163   "optimize_size || !TARGET_SUB_ESP_8"
19164   [(clobber (match_dup 0))
19165    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19166    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19167
19168 ;; Convert epilogue deallocator to pop.
19169 (define_peephole2
19170   [(match_scratch:SI 0 "r")
19171    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19172               (clobber (reg:CC FLAGS_REG))
19173               (clobber (mem:BLK (scratch)))])]
19174   "optimize_size || !TARGET_ADD_ESP_4"
19175   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19176               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19177               (clobber (mem:BLK (scratch)))])]
19178   "")
19179
19180 ;; Two pops case is tricky, since pop causes dependency on destination register.
19181 ;; We use two registers if available.
19182 (define_peephole2
19183   [(match_scratch:SI 0 "r")
19184    (match_scratch:SI 1 "r")
19185    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19186               (clobber (reg:CC FLAGS_REG))
19187               (clobber (mem:BLK (scratch)))])]
19188   "optimize_size || !TARGET_ADD_ESP_8"
19189   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19190               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19191               (clobber (mem:BLK (scratch)))])
19192    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19193               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19194   "")
19195
19196 (define_peephole2
19197   [(match_scratch:SI 0 "r")
19198    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19199               (clobber (reg:CC FLAGS_REG))
19200               (clobber (mem:BLK (scratch)))])]
19201   "optimize_size"
19202   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19203               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19204               (clobber (mem:BLK (scratch)))])
19205    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19206               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19207   "")
19208
19209 ;; Convert esp additions to pop.
19210 (define_peephole2
19211   [(match_scratch:SI 0 "r")
19212    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19213               (clobber (reg:CC FLAGS_REG))])]
19214   ""
19215   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19216               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19217   "")
19218
19219 ;; Two pops case is tricky, since pop causes dependency on destination register.
19220 ;; We use two registers if available.
19221 (define_peephole2
19222   [(match_scratch:SI 0 "r")
19223    (match_scratch:SI 1 "r")
19224    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19225               (clobber (reg:CC FLAGS_REG))])]
19226   ""
19227   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19228               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19229    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19230               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19231   "")
19232
19233 (define_peephole2
19234   [(match_scratch:SI 0 "r")
19235    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19236               (clobber (reg:CC FLAGS_REG))])]
19237   "optimize_size"
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    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19241               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19242   "")
19243 \f
19244 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19245 ;; required and register dies.  Similarly for 128 to plus -128.
19246 (define_peephole2
19247   [(set (match_operand 0 "flags_reg_operand" "")
19248         (match_operator 1 "compare_operator"
19249           [(match_operand 2 "register_operand" "")
19250            (match_operand 3 "const_int_operand" "")]))]
19251   "(INTVAL (operands[3]) == -1
19252     || INTVAL (operands[3]) == 1
19253     || INTVAL (operands[3]) == 128)
19254    && ix86_match_ccmode (insn, CCGCmode)
19255    && peep2_reg_dead_p (1, operands[2])"
19256   [(parallel [(set (match_dup 0)
19257                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19258               (clobber (match_dup 2))])]
19259   "")
19260 \f
19261 (define_peephole2
19262   [(match_scratch:DI 0 "r")
19263    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19264               (clobber (reg:CC FLAGS_REG))
19265               (clobber (mem:BLK (scratch)))])]
19266   "optimize_size || !TARGET_SUB_ESP_4"
19267   [(clobber (match_dup 0))
19268    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19269               (clobber (mem:BLK (scratch)))])])
19270
19271 (define_peephole2
19272   [(match_scratch:DI 0 "r")
19273    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19274               (clobber (reg:CC FLAGS_REG))
19275               (clobber (mem:BLK (scratch)))])]
19276   "optimize_size || !TARGET_SUB_ESP_8"
19277   [(clobber (match_dup 0))
19278    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19279    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19280               (clobber (mem:BLK (scratch)))])])
19281
19282 ;; Convert esp subtractions to push.
19283 (define_peephole2
19284   [(match_scratch:DI 0 "r")
19285    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19286               (clobber (reg:CC FLAGS_REG))])]
19287   "optimize_size || !TARGET_SUB_ESP_4"
19288   [(clobber (match_dup 0))
19289    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19290
19291 (define_peephole2
19292   [(match_scratch:DI 0 "r")
19293    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19294               (clobber (reg:CC FLAGS_REG))])]
19295   "optimize_size || !TARGET_SUB_ESP_8"
19296   [(clobber (match_dup 0))
19297    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19298    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19299
19300 ;; Convert epilogue deallocator to pop.
19301 (define_peephole2
19302   [(match_scratch:DI 0 "r")
19303    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19304               (clobber (reg:CC FLAGS_REG))
19305               (clobber (mem:BLK (scratch)))])]
19306   "optimize_size || !TARGET_ADD_ESP_4"
19307   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19308               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19309               (clobber (mem:BLK (scratch)))])]
19310   "")
19311
19312 ;; Two pops case is tricky, since pop causes dependency on destination register.
19313 ;; We use two registers if available.
19314 (define_peephole2
19315   [(match_scratch:DI 0 "r")
19316    (match_scratch:DI 1 "r")
19317    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19318               (clobber (reg:CC FLAGS_REG))
19319               (clobber (mem:BLK (scratch)))])]
19320   "optimize_size || !TARGET_ADD_ESP_8"
19321   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19322               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19323               (clobber (mem:BLK (scratch)))])
19324    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19325               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19326   "")
19327
19328 (define_peephole2
19329   [(match_scratch:DI 0 "r")
19330    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19331               (clobber (reg:CC FLAGS_REG))
19332               (clobber (mem:BLK (scratch)))])]
19333   "optimize_size"
19334   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19335               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19336               (clobber (mem:BLK (scratch)))])
19337    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19338               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19339   "")
19340
19341 ;; Convert esp additions to pop.
19342 (define_peephole2
19343   [(match_scratch:DI 0 "r")
19344    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19345               (clobber (reg:CC FLAGS_REG))])]
19346   ""
19347   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19348               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19349   "")
19350
19351 ;; Two pops case is tricky, since pop causes dependency on destination register.
19352 ;; We use two registers if available.
19353 (define_peephole2
19354   [(match_scratch:DI 0 "r")
19355    (match_scratch:DI 1 "r")
19356    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19357               (clobber (reg:CC FLAGS_REG))])]
19358   ""
19359   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19360               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19361    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19362               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19363   "")
19364
19365 (define_peephole2
19366   [(match_scratch:DI 0 "r")
19367    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19368               (clobber (reg:CC FLAGS_REG))])]
19369   "optimize_size"
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    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19373               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19374   "")
19375 \f
19376 ;; Convert imul by three, five and nine into lea
19377 (define_peephole2
19378   [(parallel
19379     [(set (match_operand:SI 0 "register_operand" "")
19380           (mult:SI (match_operand:SI 1 "register_operand" "")
19381                    (match_operand:SI 2 "const_int_operand" "")))
19382      (clobber (reg:CC FLAGS_REG))])]
19383   "INTVAL (operands[2]) == 3
19384    || INTVAL (operands[2]) == 5
19385    || INTVAL (operands[2]) == 9"
19386   [(set (match_dup 0)
19387         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19388                  (match_dup 1)))]
19389   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19390
19391 (define_peephole2
19392   [(parallel
19393     [(set (match_operand:SI 0 "register_operand" "")
19394           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19395                    (match_operand:SI 2 "const_int_operand" "")))
19396      (clobber (reg:CC FLAGS_REG))])]
19397   "!optimize_size 
19398    && (INTVAL (operands[2]) == 3
19399        || INTVAL (operands[2]) == 5
19400        || INTVAL (operands[2]) == 9)"
19401   [(set (match_dup 0) (match_dup 1))
19402    (set (match_dup 0)
19403         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19404                  (match_dup 0)))]
19405   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19406
19407 (define_peephole2
19408   [(parallel
19409     [(set (match_operand:DI 0 "register_operand" "")
19410           (mult:DI (match_operand:DI 1 "register_operand" "")
19411                    (match_operand:DI 2 "const_int_operand" "")))
19412      (clobber (reg:CC FLAGS_REG))])]
19413   "TARGET_64BIT
19414    && (INTVAL (operands[2]) == 3
19415        || INTVAL (operands[2]) == 5
19416        || INTVAL (operands[2]) == 9)"
19417   [(set (match_dup 0)
19418         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19419                  (match_dup 1)))]
19420   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19421
19422 (define_peephole2
19423   [(parallel
19424     [(set (match_operand:DI 0 "register_operand" "")
19425           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19426                    (match_operand:DI 2 "const_int_operand" "")))
19427      (clobber (reg:CC FLAGS_REG))])]
19428   "TARGET_64BIT
19429    && !optimize_size 
19430    && (INTVAL (operands[2]) == 3
19431        || INTVAL (operands[2]) == 5
19432        || INTVAL (operands[2]) == 9)"
19433   [(set (match_dup 0) (match_dup 1))
19434    (set (match_dup 0)
19435         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19436                  (match_dup 0)))]
19437   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19438
19439 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19440 ;; imul $32bit_imm, reg, reg is direct decoded.
19441 (define_peephole2
19442   [(match_scratch:DI 3 "r")
19443    (parallel [(set (match_operand:DI 0 "register_operand" "")
19444                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19445                             (match_operand:DI 2 "immediate_operand" "")))
19446               (clobber (reg:CC FLAGS_REG))])]
19447   "TARGET_K8 && !optimize_size
19448    && (GET_CODE (operands[2]) != CONST_INT
19449        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19450   [(set (match_dup 3) (match_dup 1))
19451    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19452               (clobber (reg:CC FLAGS_REG))])]
19453 "")
19454
19455 (define_peephole2
19456   [(match_scratch:SI 3 "r")
19457    (parallel [(set (match_operand:SI 0 "register_operand" "")
19458                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19459                             (match_operand:SI 2 "immediate_operand" "")))
19460               (clobber (reg:CC FLAGS_REG))])]
19461   "TARGET_K8 && !optimize_size
19462    && (GET_CODE (operands[2]) != CONST_INT
19463        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19464   [(set (match_dup 3) (match_dup 1))
19465    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19466               (clobber (reg:CC FLAGS_REG))])]
19467 "")
19468
19469 (define_peephole2
19470   [(match_scratch:SI 3 "r")
19471    (parallel [(set (match_operand:DI 0 "register_operand" "")
19472                    (zero_extend:DI
19473                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19474                               (match_operand:SI 2 "immediate_operand" ""))))
19475               (clobber (reg:CC FLAGS_REG))])]
19476   "TARGET_K8 && !optimize_size
19477    && (GET_CODE (operands[2]) != CONST_INT
19478        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19479   [(set (match_dup 3) (match_dup 1))
19480    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19481               (clobber (reg:CC FLAGS_REG))])]
19482 "")
19483
19484 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19485 ;; Convert it into imul reg, reg
19486 ;; It would be better to force assembler to encode instruction using long
19487 ;; immediate, but there is apparently no way to do so.
19488 (define_peephole2
19489   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19490                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19491                             (match_operand:DI 2 "const_int_operand" "")))
19492               (clobber (reg:CC FLAGS_REG))])
19493    (match_scratch:DI 3 "r")]
19494   "TARGET_K8 && !optimize_size
19495    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19496   [(set (match_dup 3) (match_dup 2))
19497    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19498               (clobber (reg:CC FLAGS_REG))])]
19499 {
19500   if (!rtx_equal_p (operands[0], operands[1]))
19501     emit_move_insn (operands[0], operands[1]);
19502 })
19503
19504 (define_peephole2
19505   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19506                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19507                             (match_operand:SI 2 "const_int_operand" "")))
19508               (clobber (reg:CC FLAGS_REG))])
19509    (match_scratch:SI 3 "r")]
19510   "TARGET_K8 && !optimize_size
19511    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19512   [(set (match_dup 3) (match_dup 2))
19513    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19514               (clobber (reg:CC FLAGS_REG))])]
19515 {
19516   if (!rtx_equal_p (operands[0], operands[1]))
19517     emit_move_insn (operands[0], operands[1]);
19518 })
19519
19520 (define_peephole2
19521   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19522                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19523                             (match_operand:HI 2 "immediate_operand" "")))
19524               (clobber (reg:CC FLAGS_REG))])
19525    (match_scratch:HI 3 "r")]
19526   "TARGET_K8 && !optimize_size"
19527   [(set (match_dup 3) (match_dup 2))
19528    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19529               (clobber (reg:CC FLAGS_REG))])]
19530 {
19531   if (!rtx_equal_p (operands[0], operands[1]))
19532     emit_move_insn (operands[0], operands[1]);
19533 })
19534 \f
19535 ;; Call-value patterns last so that the wildcard operand does not
19536 ;; disrupt insn-recog's switch tables.
19537
19538 (define_insn "*call_value_pop_0"
19539   [(set (match_operand 0 "" "")
19540         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19541               (match_operand:SI 2 "" "")))
19542    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19543                             (match_operand:SI 3 "immediate_operand" "")))]
19544   "!TARGET_64BIT"
19545 {
19546   if (SIBLING_CALL_P (insn))
19547     return "jmp\t%P1";
19548   else
19549     return "call\t%P1";
19550 }
19551   [(set_attr "type" "callv")])
19552
19553 (define_insn "*call_value_pop_1"
19554   [(set (match_operand 0 "" "")
19555         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19556               (match_operand:SI 2 "" "")))
19557    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19558                             (match_operand:SI 3 "immediate_operand" "i")))]
19559   "!TARGET_64BIT"
19560 {
19561   if (constant_call_address_operand (operands[1], Pmode))
19562     {
19563       if (SIBLING_CALL_P (insn))
19564         return "jmp\t%P1";
19565       else
19566         return "call\t%P1";
19567     }
19568   if (SIBLING_CALL_P (insn))
19569     return "jmp\t%A1";
19570   else
19571     return "call\t%A1";
19572 }
19573   [(set_attr "type" "callv")])
19574
19575 (define_insn "*call_value_0"
19576   [(set (match_operand 0 "" "")
19577         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19578               (match_operand:SI 2 "" "")))]
19579   "!TARGET_64BIT"
19580 {
19581   if (SIBLING_CALL_P (insn))
19582     return "jmp\t%P1";
19583   else
19584     return "call\t%P1";
19585 }
19586   [(set_attr "type" "callv")])
19587
19588 (define_insn "*call_value_0_rex64"
19589   [(set (match_operand 0 "" "")
19590         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19591               (match_operand:DI 2 "const_int_operand" "")))]
19592   "TARGET_64BIT"
19593 {
19594   if (SIBLING_CALL_P (insn))
19595     return "jmp\t%P1";
19596   else
19597     return "call\t%P1";
19598 }
19599   [(set_attr "type" "callv")])
19600
19601 (define_insn "*call_value_1"
19602   [(set (match_operand 0 "" "")
19603         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19604               (match_operand:SI 2 "" "")))]
19605   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19606 {
19607   if (constant_call_address_operand (operands[1], Pmode))
19608     return "call\t%P1";
19609   return "call\t%A1";
19610 }
19611   [(set_attr "type" "callv")])
19612
19613 (define_insn "*sibcall_value_1"
19614   [(set (match_operand 0 "" "")
19615         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19616               (match_operand:SI 2 "" "")))]
19617   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19618 {
19619   if (constant_call_address_operand (operands[1], Pmode))
19620     return "jmp\t%P1";
19621   return "jmp\t%A1";
19622 }
19623   [(set_attr "type" "callv")])
19624
19625 (define_insn "*call_value_1_rex64"
19626   [(set (match_operand 0 "" "")
19627         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19628               (match_operand:DI 2 "" "")))]
19629   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19630 {
19631   if (constant_call_address_operand (operands[1], Pmode))
19632     return "call\t%P1";
19633   return "call\t%A1";
19634 }
19635   [(set_attr "type" "callv")])
19636
19637 (define_insn "*sibcall_value_1_rex64"
19638   [(set (match_operand 0 "" "")
19639         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19640               (match_operand:DI 2 "" "")))]
19641   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19642   "jmp\t%P1"
19643   [(set_attr "type" "callv")])
19644
19645 (define_insn "*sibcall_value_1_rex64_v"
19646   [(set (match_operand 0 "" "")
19647         (call (mem:QI (reg:DI 40))
19648               (match_operand:DI 1 "" "")))]
19649   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19650   "jmp\t*%%r11"
19651   [(set_attr "type" "callv")])
19652 \f
19653 (define_insn "trap"
19654   [(trap_if (const_int 1) (const_int 5))]
19655   ""
19656   "int\t$5")
19657
19658 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19659 ;;; for the sake of bounds checking.  By emitting bounds checks as
19660 ;;; conditional traps rather than as conditional jumps around
19661 ;;; unconditional traps we avoid introducing spurious basic-block
19662 ;;; boundaries and facilitate elimination of redundant checks.  In
19663 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19664 ;;; interrupt 5.
19665 ;;; 
19666 ;;; FIXME: Static branch prediction rules for ix86 are such that
19667 ;;; forward conditional branches predict as untaken.  As implemented
19668 ;;; below, pseudo conditional traps violate that rule.  We should use
19669 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19670 ;;; section loaded at the end of the text segment and branch forward
19671 ;;; there on bounds-failure, and then jump back immediately (in case
19672 ;;; the system chooses to ignore bounds violations, or to report
19673 ;;; violations and continue execution).
19674
19675 (define_expand "conditional_trap"
19676   [(trap_if (match_operator 0 "comparison_operator"
19677              [(match_dup 2) (const_int 0)])
19678             (match_operand 1 "const_int_operand" ""))]
19679   ""
19680 {
19681   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19682                               ix86_expand_compare (GET_CODE (operands[0]),
19683                                                    NULL, NULL),
19684                               operands[1]));
19685   DONE;
19686 })
19687
19688 (define_insn "*conditional_trap_1"
19689   [(trap_if (match_operator 0 "comparison_operator"
19690              [(reg FLAGS_REG) (const_int 0)])
19691             (match_operand 1 "const_int_operand" ""))]
19692   ""
19693 {
19694   operands[2] = gen_label_rtx ();
19695   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19696   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19697                              CODE_LABEL_NUMBER (operands[2]));
19698   RET;
19699 })
19700
19701         ;; Pentium III SIMD instructions.
19702
19703 ;; Moves for SSE/MMX regs.
19704
19705 (define_insn "movv4sf_internal"
19706   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19707         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19708   "TARGET_SSE"
19709   "@
19710     xorps\t%0, %0
19711     movaps\t{%1, %0|%0, %1}
19712     movaps\t{%1, %0|%0, %1}"
19713   [(set_attr "type" "ssemov")
19714    (set_attr "mode" "V4SF")])
19715
19716 (define_split
19717   [(set (match_operand:V4SF 0 "register_operand" "")
19718         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19719   "TARGET_SSE && reload_completed"
19720   [(set (match_dup 0)
19721         (vec_merge:V4SF
19722          (vec_duplicate:V4SF (match_dup 1))
19723          (match_dup 2)
19724          (const_int 1)))]
19725 {
19726   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19727   operands[2] = CONST0_RTX (V4SFmode);
19728 })
19729
19730 (define_insn "movv4si_internal"
19731   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19732         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19733   "TARGET_SSE"
19734 {
19735   switch (which_alternative)
19736     {
19737     case 0:
19738       if (get_attr_mode (insn) == MODE_V4SF)
19739         return "xorps\t%0, %0";
19740       else
19741         return "pxor\t%0, %0";
19742     case 1:
19743     case 2:
19744       if (get_attr_mode (insn) == MODE_V4SF)
19745         return "movaps\t{%1, %0|%0, %1}";
19746       else
19747         return "movdqa\t{%1, %0|%0, %1}";
19748     default:
19749       abort ();
19750     }
19751 }
19752   [(set_attr "type" "ssemov")
19753    (set (attr "mode")
19754         (cond [(eq_attr "alternative" "0,1")
19755                  (if_then_else
19756                    (ne (symbol_ref "optimize_size")
19757                        (const_int 0))
19758                    (const_string "V4SF")
19759                    (const_string "TI"))
19760                (eq_attr "alternative" "2")
19761                  (if_then_else
19762                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19763                             (const_int 0))
19764                         (ne (symbol_ref "optimize_size")
19765                             (const_int 0)))
19766                    (const_string "V4SF")
19767                    (const_string "TI"))]
19768                (const_string "TI")))])
19769
19770 (define_insn "movv2di_internal"
19771   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19772         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19773   "TARGET_SSE"
19774 {
19775   switch (which_alternative)
19776     {
19777     case 0:
19778       if (get_attr_mode (insn) == MODE_V4SF)
19779         return "xorps\t%0, %0";
19780       else
19781         return "pxor\t%0, %0";
19782     case 1:
19783     case 2:
19784       if (get_attr_mode (insn) == MODE_V4SF)
19785         return "movaps\t{%1, %0|%0, %1}";
19786       else
19787         return "movdqa\t{%1, %0|%0, %1}";
19788     default:
19789       abort ();
19790     }
19791 }
19792   [(set_attr "type" "ssemov")
19793    (set (attr "mode")
19794         (cond [(eq_attr "alternative" "0,1")
19795                  (if_then_else
19796                    (ne (symbol_ref "optimize_size")
19797                        (const_int 0))
19798                    (const_string "V4SF")
19799                    (const_string "TI"))
19800                (eq_attr "alternative" "2")
19801                  (if_then_else
19802                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19803                             (const_int 0))
19804                         (ne (symbol_ref "optimize_size")
19805                             (const_int 0)))
19806                    (const_string "V4SF")
19807                    (const_string "TI"))]
19808                (const_string "TI")))])
19809
19810 (define_split
19811   [(set (match_operand:V2DF 0 "register_operand" "")
19812         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19813   "TARGET_SSE2 && reload_completed"
19814   [(set (match_dup 0)
19815         (vec_merge:V2DF
19816          (vec_duplicate:V2DF (match_dup 1))
19817          (match_dup 2)
19818          (const_int 1)))]
19819 {
19820   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19821   operands[2] = CONST0_RTX (V2DFmode);
19822 })
19823
19824 (define_insn "movv8qi_internal"
19825   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19826         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19827   "TARGET_MMX
19828    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19829   "@
19830     pxor\t%0, %0
19831     movq\t{%1, %0|%0, %1}
19832     movq\t{%1, %0|%0, %1}
19833     movdq2q\t{%1, %0|%0, %1}
19834     movq2dq\t{%1, %0|%0, %1}
19835     movq\t{%1, %0|%0, %1}
19836     movq\t{%1, %0|%0, %1}"
19837   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19838    (set_attr "mode" "DI")])
19839
19840 (define_insn "movv4hi_internal"
19841   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19842         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19843   "TARGET_MMX
19844    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19845   "@
19846     pxor\t%0, %0
19847     movq\t{%1, %0|%0, %1}
19848     movq\t{%1, %0|%0, %1}
19849     movdq2q\t{%1, %0|%0, %1}
19850     movq2dq\t{%1, %0|%0, %1}
19851     movq\t{%1, %0|%0, %1}
19852     movq\t{%1, %0|%0, %1}"
19853   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19854    (set_attr "mode" "DI")])
19855
19856 (define_insn "*movv2si_internal"
19857   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19858         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19859   "TARGET_MMX
19860    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19861   "@
19862     pxor\t%0, %0
19863     movq\t{%1, %0|%0, %1}
19864     movq\t{%1, %0|%0, %1}
19865     movdq2q\t{%1, %0|%0, %1}
19866     movq2dq\t{%1, %0|%0, %1}
19867     movq\t{%1, %0|%0, %1}
19868     movq\t{%1, %0|%0, %1}"
19869   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19870    (set_attr "mode" "DI")])
19871
19872 (define_insn "movv2sf_internal"
19873   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19874         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
19875   "TARGET_3DNOW
19876    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19877   "@
19878     pxor\t%0, %0
19879     movq\t{%1, %0|%0, %1}
19880     movq\t{%1, %0|%0, %1}
19881     movdq2q\t{%1, %0|%0, %1}
19882     movq2dq\t{%1, %0|%0, %1}
19883     movlps\t{%1, %0|%0, %1}
19884     movlps\t{%1, %0|%0, %1}"
19885   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19886    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
19887
19888 (define_expand "movti"
19889   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19890         (match_operand:TI 1 "nonimmediate_operand" ""))]
19891   "TARGET_SSE || TARGET_64BIT"
19892 {
19893   if (TARGET_64BIT)
19894     ix86_expand_move (TImode, operands);
19895   else
19896     ix86_expand_vector_move (TImode, operands);
19897   DONE;
19898 })
19899
19900 (define_expand "movtf"
19901   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19902         (match_operand:TF 1 "nonimmediate_operand" ""))]
19903   "TARGET_64BIT"
19904 {
19905   if (TARGET_64BIT)
19906     ix86_expand_move (TFmode, operands);
19907   else
19908     ix86_expand_vector_move (TFmode, operands);
19909   DONE;
19910 })
19911
19912 (define_insn "movv2df_internal"
19913   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19914         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19915   "TARGET_SSE2
19916    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19917 {
19918   switch (which_alternative)
19919     {
19920     case 0:
19921       if (get_attr_mode (insn) == MODE_V4SF)
19922         return "xorps\t%0, %0";
19923       else
19924         return "xorpd\t%0, %0";
19925     case 1:
19926     case 2:
19927       if (get_attr_mode (insn) == MODE_V4SF)
19928         return "movaps\t{%1, %0|%0, %1}";
19929       else
19930         return "movapd\t{%1, %0|%0, %1}";
19931     default:
19932       abort ();
19933     }
19934 }
19935   [(set_attr "type" "ssemov")
19936    (set (attr "mode")
19937         (cond [(eq_attr "alternative" "0,1")
19938                  (if_then_else
19939                    (ne (symbol_ref "optimize_size")
19940                        (const_int 0))
19941                    (const_string "V4SF")
19942                    (const_string "V2DF"))
19943                (eq_attr "alternative" "2")
19944                  (if_then_else
19945                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19946                             (const_int 0))
19947                         (ne (symbol_ref "optimize_size")
19948                             (const_int 0)))
19949                    (const_string "V4SF")
19950                    (const_string "V2DF"))]
19951                (const_string "V2DF")))])
19952
19953 (define_insn "movv8hi_internal"
19954   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19955         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19956   "TARGET_SSE2
19957    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19958 {
19959   switch (which_alternative)
19960     {
19961     case 0:
19962       if (get_attr_mode (insn) == MODE_V4SF)
19963         return "xorps\t%0, %0";
19964       else
19965         return "pxor\t%0, %0";
19966     case 1:
19967     case 2:
19968       if (get_attr_mode (insn) == MODE_V4SF)
19969         return "movaps\t{%1, %0|%0, %1}";
19970       else
19971         return "movdqa\t{%1, %0|%0, %1}";
19972     default:
19973       abort ();
19974     }
19975 }
19976   [(set_attr "type" "ssemov")
19977    (set (attr "mode")
19978         (cond [(eq_attr "alternative" "0,1")
19979                  (if_then_else
19980                    (ne (symbol_ref "optimize_size")
19981                        (const_int 0))
19982                    (const_string "V4SF")
19983                    (const_string "TI"))
19984                (eq_attr "alternative" "2")
19985                  (if_then_else
19986                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19987                             (const_int 0))
19988                         (ne (symbol_ref "optimize_size")
19989                             (const_int 0)))
19990                    (const_string "V4SF")
19991                    (const_string "TI"))]
19992                (const_string "TI")))])
19993
19994 (define_insn "movv16qi_internal"
19995   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19996         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
19997   "TARGET_SSE2
19998    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19999 {
20000   switch (which_alternative)
20001     {
20002     case 0:
20003       if (get_attr_mode (insn) == MODE_V4SF)
20004         return "xorps\t%0, %0";
20005       else
20006         return "pxor\t%0, %0";
20007     case 1:
20008     case 2:
20009       if (get_attr_mode (insn) == MODE_V4SF)
20010         return "movaps\t{%1, %0|%0, %1}";
20011       else
20012         return "movdqa\t{%1, %0|%0, %1}";
20013     default:
20014       abort ();
20015     }
20016 }
20017   [(set_attr "type" "ssemov")
20018    (set (attr "mode")
20019         (cond [(eq_attr "alternative" "0,1")
20020                  (if_then_else
20021                    (ne (symbol_ref "optimize_size")
20022                        (const_int 0))
20023                    (const_string "V4SF")
20024                    (const_string "TI"))
20025                (eq_attr "alternative" "2")
20026                  (if_then_else
20027                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20028                             (const_int 0))
20029                         (ne (symbol_ref "optimize_size")
20030                             (const_int 0)))
20031                    (const_string "V4SF")
20032                    (const_string "TI"))]
20033                (const_string "TI")))])
20034
20035 (define_expand "movv2df"
20036   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20037         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20038   "TARGET_SSE2"
20039 {
20040   ix86_expand_vector_move (V2DFmode, operands);
20041   DONE;
20042 })
20043
20044 (define_expand "movv8hi"
20045   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20046         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20047   "TARGET_SSE2"
20048 {
20049   ix86_expand_vector_move (V8HImode, operands);
20050   DONE;
20051 })
20052
20053 (define_expand "movv16qi"
20054   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20055         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20056   "TARGET_SSE2"
20057 {
20058   ix86_expand_vector_move (V16QImode, operands);
20059   DONE;
20060 })
20061
20062 (define_expand "movv4sf"
20063   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20064         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20065   "TARGET_SSE"
20066 {
20067   ix86_expand_vector_move (V4SFmode, operands);
20068   DONE;
20069 })
20070
20071 (define_expand "movv4si"
20072   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20073         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20074   "TARGET_SSE"
20075 {
20076   ix86_expand_vector_move (V4SImode, operands);
20077   DONE;
20078 })
20079
20080 (define_expand "movv2di"
20081   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20082         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20083   "TARGET_SSE"
20084 {
20085   ix86_expand_vector_move (V2DImode, operands);
20086   DONE;
20087 })
20088
20089 (define_expand "movv2si"
20090   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20091         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20092   "TARGET_MMX"
20093 {
20094   ix86_expand_vector_move (V2SImode, operands);
20095   DONE;
20096 })
20097
20098 (define_expand "movv4hi"
20099   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20100         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20101   "TARGET_MMX"
20102 {
20103   ix86_expand_vector_move (V4HImode, operands);
20104   DONE;
20105 })
20106
20107 (define_expand "movv8qi"
20108   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20109         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20110   "TARGET_MMX"
20111 {
20112   ix86_expand_vector_move (V8QImode, operands);
20113   DONE;
20114 })
20115
20116 (define_expand "movv2sf"
20117   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20118         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20119    "TARGET_3DNOW"
20120 {
20121   ix86_expand_vector_move (V2SFmode, operands);
20122   DONE;
20123 })
20124
20125 (define_insn "*pushti"
20126   [(set (match_operand:TI 0 "push_operand" "=<")
20127         (match_operand:TI 1 "register_operand" "x"))]
20128   "TARGET_SSE"
20129   "#")
20130
20131 (define_insn "*pushv2df"
20132   [(set (match_operand:V2DF 0 "push_operand" "=<")
20133         (match_operand:V2DF 1 "register_operand" "x"))]
20134   "TARGET_SSE"
20135   "#")
20136
20137 (define_insn "*pushv2di"
20138   [(set (match_operand:V2DI 0 "push_operand" "=<")
20139         (match_operand:V2DI 1 "register_operand" "x"))]
20140   "TARGET_SSE2"
20141   "#")
20142
20143 (define_insn "*pushv8hi"
20144   [(set (match_operand:V8HI 0 "push_operand" "=<")
20145         (match_operand:V8HI 1 "register_operand" "x"))]
20146   "TARGET_SSE2"
20147   "#")
20148
20149 (define_insn "*pushv16qi"
20150   [(set (match_operand:V16QI 0 "push_operand" "=<")
20151         (match_operand:V16QI 1 "register_operand" "x"))]
20152   "TARGET_SSE2"
20153   "#")
20154
20155 (define_insn "*pushv4sf"
20156   [(set (match_operand:V4SF 0 "push_operand" "=<")
20157         (match_operand:V4SF 1 "register_operand" "x"))]
20158   "TARGET_SSE"
20159   "#")
20160
20161 (define_insn "*pushv4si"
20162   [(set (match_operand:V4SI 0 "push_operand" "=<")
20163         (match_operand:V4SI 1 "register_operand" "x"))]
20164   "TARGET_SSE2"
20165   "#")
20166
20167 (define_insn "*pushv2si"
20168   [(set (match_operand:V2SI 0 "push_operand" "=<")
20169         (match_operand:V2SI 1 "register_operand" "y"))]
20170   "TARGET_MMX"
20171   "#")
20172
20173 (define_insn "*pushv4hi"
20174   [(set (match_operand:V4HI 0 "push_operand" "=<")
20175         (match_operand:V4HI 1 "register_operand" "y"))]
20176   "TARGET_MMX"
20177   "#")
20178
20179 (define_insn "*pushv8qi"
20180   [(set (match_operand:V8QI 0 "push_operand" "=<")
20181         (match_operand:V8QI 1 "register_operand" "y"))]
20182   "TARGET_MMX"
20183   "#")
20184
20185 (define_insn "*pushv2sf"
20186   [(set (match_operand:V2SF 0 "push_operand" "=<")
20187         (match_operand:V2SF 1 "register_operand" "y"))]
20188   "TARGET_3DNOW"
20189   "#")
20190
20191 (define_split
20192   [(set (match_operand 0 "push_operand" "")
20193         (match_operand 1 "register_operand" ""))]
20194   "!TARGET_64BIT && reload_completed
20195    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20196   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20197    (set (match_dup 2) (match_dup 1))]
20198   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20199                                  stack_pointer_rtx);
20200    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20201
20202 (define_split
20203   [(set (match_operand 0 "push_operand" "")
20204         (match_operand 1 "register_operand" ""))]
20205   "TARGET_64BIT && reload_completed
20206    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20207   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20208    (set (match_dup 2) (match_dup 1))]
20209   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20210                                  stack_pointer_rtx);
20211    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20212
20213
20214 (define_insn "movti_internal"
20215   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20216         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20217   "TARGET_SSE && !TARGET_64BIT
20218    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20219 {
20220   switch (which_alternative)
20221     {
20222     case 0:
20223       if (get_attr_mode (insn) == MODE_V4SF)
20224         return "xorps\t%0, %0";
20225       else
20226         return "pxor\t%0, %0";
20227     case 1:
20228     case 2:
20229       if (get_attr_mode (insn) == MODE_V4SF)
20230         return "movaps\t{%1, %0|%0, %1}";
20231       else
20232         return "movdqa\t{%1, %0|%0, %1}";
20233     default:
20234       abort ();
20235     }
20236 }
20237   [(set_attr "type" "ssemov,ssemov,ssemov")
20238    (set (attr "mode")
20239         (cond [(eq_attr "alternative" "0,1")
20240                  (if_then_else
20241                    (ne (symbol_ref "optimize_size")
20242                        (const_int 0))
20243                    (const_string "V4SF")
20244                    (const_string "TI"))
20245                (eq_attr "alternative" "2")
20246                  (if_then_else
20247                    (ne (symbol_ref "optimize_size")
20248                        (const_int 0))
20249                    (const_string "V4SF")
20250                    (const_string "TI"))]
20251                (const_string "TI")))])
20252
20253 (define_insn "*movti_rex64"
20254   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20255         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20256   "TARGET_64BIT
20257    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20258 {
20259   switch (which_alternative)
20260     {
20261     case 0:
20262     case 1:
20263       return "#";
20264     case 2:
20265       if (get_attr_mode (insn) == MODE_V4SF)
20266         return "xorps\t%0, %0";
20267       else
20268         return "pxor\t%0, %0";
20269     case 3:
20270     case 4:
20271       if (get_attr_mode (insn) == MODE_V4SF)
20272         return "movaps\t{%1, %0|%0, %1}";
20273       else
20274         return "movdqa\t{%1, %0|%0, %1}";
20275     default:
20276       abort ();
20277     }
20278 }
20279   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20280    (set (attr "mode")
20281         (cond [(eq_attr "alternative" "2,3")
20282                  (if_then_else
20283                    (ne (symbol_ref "optimize_size")
20284                        (const_int 0))
20285                    (const_string "V4SF")
20286                    (const_string "TI"))
20287                (eq_attr "alternative" "4")
20288                  (if_then_else
20289                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20290                             (const_int 0))
20291                         (ne (symbol_ref "optimize_size")
20292                             (const_int 0)))
20293                    (const_string "V4SF")
20294                    (const_string "TI"))]
20295                (const_string "DI")))])
20296
20297 (define_insn "*movtf_rex64"
20298   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20299         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20300   "TARGET_64BIT
20301    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20302 {
20303   switch (which_alternative)
20304     {
20305     case 0:
20306     case 1:
20307       return "#";
20308     case 2:
20309       if (get_attr_mode (insn) == MODE_V4SF)
20310         return "xorps\t%0, %0";
20311       else
20312         return "pxor\t%0, %0";
20313     case 3:
20314     case 4:
20315       if (get_attr_mode (insn) == MODE_V4SF)
20316         return "movaps\t{%1, %0|%0, %1}";
20317       else
20318         return "movdqa\t{%1, %0|%0, %1}";
20319     default:
20320       abort ();
20321     }
20322 }
20323   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20324    (set (attr "mode")
20325         (cond [(eq_attr "alternative" "2,3")
20326                  (if_then_else
20327                    (ne (symbol_ref "optimize_size")
20328                        (const_int 0))
20329                    (const_string "V4SF")
20330                    (const_string "TI"))
20331                (eq_attr "alternative" "4")
20332                  (if_then_else
20333                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20334                             (const_int 0))
20335                         (ne (symbol_ref "optimize_size")
20336                             (const_int 0)))
20337                    (const_string "V4SF")
20338                    (const_string "TI"))]
20339                (const_string "DI")))])
20340
20341 (define_split
20342   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20343         (match_operand:TI 1 "general_operand" ""))]
20344   "reload_completed && !SSE_REG_P (operands[0])
20345    && !SSE_REG_P (operands[1])"
20346   [(const_int 0)]
20347   "ix86_split_long_move (operands); DONE;")
20348
20349 (define_split
20350   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20351         (match_operand:TF 1 "general_operand" ""))]
20352   "reload_completed && !SSE_REG_P (operands[0])
20353    && !SSE_REG_P (operands[1])"
20354   [(const_int 0)]
20355   "ix86_split_long_move (operands); DONE;")
20356
20357 ;; These two patterns are useful for specifying exactly whether to use
20358 ;; movaps or movups
20359 (define_expand "sse_movaps"
20360   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20361         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20362                      UNSPEC_MOVA))]
20363   "TARGET_SSE"
20364 {
20365   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20366     {
20367       rtx tmp = gen_reg_rtx (V4SFmode);
20368       emit_insn (gen_sse_movaps (tmp, operands[1]));
20369       emit_move_insn (operands[0], tmp);
20370       DONE;
20371     }
20372 })
20373
20374 (define_insn "*sse_movaps_1"
20375   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20376         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20377                      UNSPEC_MOVA))]
20378   "TARGET_SSE
20379    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20380   "movaps\t{%1, %0|%0, %1}"
20381   [(set_attr "type" "ssemov,ssemov")
20382    (set_attr "mode" "V4SF")])
20383
20384 (define_expand "sse_movups"
20385   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20386         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20387                      UNSPEC_MOVU))]
20388   "TARGET_SSE"
20389 {
20390   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20391     {
20392       rtx tmp = gen_reg_rtx (V4SFmode);
20393       emit_insn (gen_sse_movups (tmp, operands[1]));
20394       emit_move_insn (operands[0], tmp);
20395       DONE;
20396     }
20397 })
20398
20399 (define_insn "*sse_movups_1"
20400   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20401         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20402                      UNSPEC_MOVU))]
20403   "TARGET_SSE
20404    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20405   "movups\t{%1, %0|%0, %1}"
20406   [(set_attr "type" "ssecvt,ssecvt")
20407    (set_attr "mode" "V4SF")])
20408
20409 ;; SSE Strange Moves.
20410
20411 (define_insn "sse_movmskps"
20412   [(set (match_operand:SI 0 "register_operand" "=r")
20413         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20414                    UNSPEC_MOVMSK))]
20415   "TARGET_SSE"
20416   "movmskps\t{%1, %0|%0, %1}"
20417   [(set_attr "type" "ssecvt")
20418    (set_attr "mode" "V4SF")])
20419
20420 (define_insn "mmx_pmovmskb"
20421   [(set (match_operand:SI 0 "register_operand" "=r")
20422         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20423                    UNSPEC_MOVMSK))]
20424   "TARGET_SSE || TARGET_3DNOW_A"
20425   "pmovmskb\t{%1, %0|%0, %1}"
20426   [(set_attr "type" "ssecvt")
20427    (set_attr "mode" "V4SF")])
20428
20429
20430 (define_insn "mmx_maskmovq"
20431   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20432         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20433                       (match_operand:V8QI 2 "register_operand" "y")]
20434                      UNSPEC_MASKMOV))]
20435   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20436   ;; @@@ check ordering of operands in intel/nonintel syntax
20437   "maskmovq\t{%2, %1|%1, %2}"
20438   [(set_attr "type" "mmxcvt")
20439    (set_attr "mode" "DI")])
20440
20441 (define_insn "mmx_maskmovq_rex"
20442   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20443         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20444                       (match_operand:V8QI 2 "register_operand" "y")]
20445                      UNSPEC_MASKMOV))]
20446   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20447   ;; @@@ check ordering of operands in intel/nonintel syntax
20448   "maskmovq\t{%2, %1|%1, %2}"
20449   [(set_attr "type" "mmxcvt")
20450    (set_attr "mode" "DI")])
20451
20452 (define_insn "sse_movntv4sf"
20453   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20454         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20455                      UNSPEC_MOVNT))]
20456   "TARGET_SSE"
20457   "movntps\t{%1, %0|%0, %1}"
20458   [(set_attr "type" "ssemov")
20459    (set_attr "mode" "V4SF")])
20460
20461 (define_insn "sse_movntdi"
20462   [(set (match_operand:DI 0 "memory_operand" "=m")
20463         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20464                    UNSPEC_MOVNT))]
20465   "TARGET_SSE || TARGET_3DNOW_A"
20466   "movntq\t{%1, %0|%0, %1}"
20467   [(set_attr "type" "mmxmov")
20468    (set_attr "mode" "DI")])
20469
20470 (define_insn "sse_movhlps"
20471   [(set (match_operand:V4SF 0 "register_operand" "=x")
20472         (vec_merge:V4SF
20473          (match_operand:V4SF 1 "register_operand" "0")
20474          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20475                           (parallel [(const_int 2)
20476                                      (const_int 3)
20477                                      (const_int 0)
20478                                      (const_int 1)]))
20479          (const_int 3)))]
20480   "TARGET_SSE"
20481   "movhlps\t{%2, %0|%0, %2}"
20482   [(set_attr "type" "ssecvt")
20483    (set_attr "mode" "V4SF")])
20484
20485 (define_insn "sse_movlhps"
20486   [(set (match_operand:V4SF 0 "register_operand" "=x")
20487         (vec_merge:V4SF
20488          (match_operand:V4SF 1 "register_operand" "0")
20489          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20490                           (parallel [(const_int 2)
20491                                      (const_int 3)
20492                                      (const_int 0)
20493                                      (const_int 1)]))
20494          (const_int 12)))]
20495   "TARGET_SSE"
20496   "movlhps\t{%2, %0|%0, %2}"
20497   [(set_attr "type" "ssecvt")
20498    (set_attr "mode" "V4SF")])
20499
20500 (define_insn "sse_movhps"
20501   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20502         (vec_merge:V4SF
20503          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20504          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20505          (const_int 12)))]
20506   "TARGET_SSE
20507    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20508   "movhps\t{%2, %0|%0, %2}"
20509   [(set_attr "type" "ssecvt")
20510    (set_attr "mode" "V4SF")])
20511
20512 (define_insn "sse_movlps"
20513   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20514         (vec_merge:V4SF
20515          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20516          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20517          (const_int 3)))]
20518   "TARGET_SSE
20519    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20520   "movlps\t{%2, %0|%0, %2}"
20521   [(set_attr "type" "ssecvt")
20522    (set_attr "mode" "V4SF")])
20523
20524 (define_expand "sse_loadss"
20525   [(match_operand:V4SF 0 "register_operand" "")
20526    (match_operand:SF 1 "memory_operand" "")]
20527   "TARGET_SSE"
20528 {
20529   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20530                                CONST0_RTX (V4SFmode)));
20531   DONE;
20532 })
20533
20534 (define_insn "sse_loadss_1"
20535   [(set (match_operand:V4SF 0 "register_operand" "=x")
20536         (vec_merge:V4SF
20537          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20538          (match_operand:V4SF 2 "const0_operand" "X")
20539          (const_int 1)))]
20540   "TARGET_SSE"
20541   "movss\t{%1, %0|%0, %1}"
20542   [(set_attr "type" "ssemov")
20543    (set_attr "mode" "SF")])
20544
20545 (define_insn "sse_movss"
20546   [(set (match_operand:V4SF 0 "register_operand" "=x")
20547         (vec_merge:V4SF
20548          (match_operand:V4SF 1 "register_operand" "0")
20549          (match_operand:V4SF 2 "register_operand" "x")
20550          (const_int 14)))]
20551   "TARGET_SSE"
20552   "movss\t{%2, %0|%0, %2}"
20553   [(set_attr "type" "ssemov")
20554    (set_attr "mode" "SF")])
20555
20556 (define_insn "sse_storess"
20557   [(set (match_operand:SF 0 "memory_operand" "=m")
20558         (vec_select:SF
20559          (match_operand:V4SF 1 "register_operand" "x")
20560          (parallel [(const_int 0)])))]
20561   "TARGET_SSE"
20562   "movss\t{%1, %0|%0, %1}"
20563   [(set_attr "type" "ssemov")
20564    (set_attr "mode" "SF")])
20565
20566 (define_insn "sse_shufps"
20567   [(set (match_operand:V4SF 0 "register_operand" "=x")
20568         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20569                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20570                       (match_operand:SI 3 "immediate_operand" "i")]
20571                      UNSPEC_SHUFFLE))]
20572   "TARGET_SSE"
20573   ;; @@@ check operand order for intel/nonintel syntax
20574   "shufps\t{%3, %2, %0|%0, %2, %3}"
20575   [(set_attr "type" "ssecvt")
20576    (set_attr "mode" "V4SF")])
20577
20578
20579 ;; SSE arithmetic
20580
20581 (define_insn "addv4sf3"
20582   [(set (match_operand:V4SF 0 "register_operand" "=x")
20583         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20584                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20585   "TARGET_SSE"
20586   "addps\t{%2, %0|%0, %2}"
20587   [(set_attr "type" "sseadd")
20588    (set_attr "mode" "V4SF")])
20589
20590 (define_insn "vmaddv4sf3"
20591   [(set (match_operand:V4SF 0 "register_operand" "=x")
20592         (vec_merge:V4SF
20593          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20594                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20595          (match_dup 1)
20596          (const_int 1)))]
20597   "TARGET_SSE"
20598   "addss\t{%2, %0|%0, %2}"
20599   [(set_attr "type" "sseadd")
20600    (set_attr "mode" "SF")])
20601
20602 (define_insn "subv4sf3"
20603   [(set (match_operand:V4SF 0 "register_operand" "=x")
20604         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20605                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20606   "TARGET_SSE"
20607   "subps\t{%2, %0|%0, %2}"
20608   [(set_attr "type" "sseadd")
20609    (set_attr "mode" "V4SF")])
20610
20611 (define_insn "vmsubv4sf3"
20612   [(set (match_operand:V4SF 0 "register_operand" "=x")
20613         (vec_merge:V4SF
20614          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20615                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20616          (match_dup 1)
20617          (const_int 1)))]
20618   "TARGET_SSE"
20619   "subss\t{%2, %0|%0, %2}"
20620   [(set_attr "type" "sseadd")
20621    (set_attr "mode" "SF")])
20622
20623 ;; ??? Should probably be done by generic code instead.
20624 (define_expand "negv4sf2"
20625   [(set (match_operand:V4SF 0 "register_operand" "")
20626         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20627                   (match_dup 2)))]
20628   "TARGET_SSE"
20629 {
20630   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20631   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20632   operands[2] = force_reg (V4SFmode, vm0);
20633 })
20634
20635 (define_insn "mulv4sf3"
20636   [(set (match_operand:V4SF 0 "register_operand" "=x")
20637         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20638                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20639   "TARGET_SSE"
20640   "mulps\t{%2, %0|%0, %2}"
20641   [(set_attr "type" "ssemul")
20642    (set_attr "mode" "V4SF")])
20643
20644 (define_insn "vmmulv4sf3"
20645   [(set (match_operand:V4SF 0 "register_operand" "=x")
20646         (vec_merge:V4SF
20647          (mult: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   "mulss\t{%2, %0|%0, %2}"
20653   [(set_attr "type" "ssemul")
20654    (set_attr "mode" "SF")])
20655
20656 (define_insn "divv4sf3"
20657   [(set (match_operand:V4SF 0 "register_operand" "=x")
20658         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20659                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20660   "TARGET_SSE"
20661   "divps\t{%2, %0|%0, %2}"
20662   [(set_attr "type" "ssediv")
20663    (set_attr "mode" "V4SF")])
20664
20665 (define_insn "vmdivv4sf3"
20666   [(set (match_operand:V4SF 0 "register_operand" "=x")
20667         (vec_merge:V4SF
20668          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20669                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20670          (match_dup 1)
20671          (const_int 1)))]
20672   "TARGET_SSE"
20673   "divss\t{%2, %0|%0, %2}"
20674   [(set_attr "type" "ssediv")
20675    (set_attr "mode" "SF")])
20676
20677
20678 ;; SSE square root/reciprocal
20679
20680 (define_insn "rcpv4sf2"
20681   [(set (match_operand:V4SF 0 "register_operand" "=x")
20682         (unspec:V4SF
20683          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20684   "TARGET_SSE"
20685   "rcpps\t{%1, %0|%0, %1}"
20686   [(set_attr "type" "sse")
20687    (set_attr "mode" "V4SF")])
20688
20689 (define_insn "vmrcpv4sf2"
20690   [(set (match_operand:V4SF 0 "register_operand" "=x")
20691         (vec_merge:V4SF
20692          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20693                       UNSPEC_RCP)
20694          (match_operand:V4SF 2 "register_operand" "0")
20695          (const_int 1)))]
20696   "TARGET_SSE"
20697   "rcpss\t{%1, %0|%0, %1}"
20698   [(set_attr "type" "sse")
20699    (set_attr "mode" "SF")])
20700
20701 (define_insn "rsqrtv4sf2"
20702   [(set (match_operand:V4SF 0 "register_operand" "=x")
20703         (unspec:V4SF
20704          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20705   "TARGET_SSE"
20706   "rsqrtps\t{%1, %0|%0, %1}"
20707   [(set_attr "type" "sse")
20708    (set_attr "mode" "V4SF")])
20709
20710 (define_insn "vmrsqrtv4sf2"
20711   [(set (match_operand:V4SF 0 "register_operand" "=x")
20712         (vec_merge:V4SF
20713          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20714                       UNSPEC_RSQRT)
20715          (match_operand:V4SF 2 "register_operand" "0")
20716          (const_int 1)))]
20717   "TARGET_SSE"
20718   "rsqrtss\t{%1, %0|%0, %1}"
20719   [(set_attr "type" "sse")
20720    (set_attr "mode" "SF")])
20721
20722 (define_insn "sqrtv4sf2"
20723   [(set (match_operand:V4SF 0 "register_operand" "=x")
20724         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20725   "TARGET_SSE"
20726   "sqrtps\t{%1, %0|%0, %1}"
20727   [(set_attr "type" "sse")
20728    (set_attr "mode" "V4SF")])
20729
20730 (define_insn "vmsqrtv4sf2"
20731   [(set (match_operand:V4SF 0 "register_operand" "=x")
20732         (vec_merge:V4SF
20733          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20734          (match_operand:V4SF 2 "register_operand" "0")
20735          (const_int 1)))]
20736   "TARGET_SSE"
20737   "sqrtss\t{%1, %0|%0, %1}"
20738   [(set_attr "type" "sse")
20739    (set_attr "mode" "SF")])
20740
20741 ;; SSE logical operations.
20742
20743 ;; SSE defines logical operations on floating point values.  This brings
20744 ;; interesting challenge to RTL representation where logicals are only valid
20745 ;; on integral types.  We deal with this by representing the floating point
20746 ;; logical as logical on arguments casted to TImode as this is what hardware
20747 ;; really does.  Unfortunately hardware requires the type information to be
20748 ;; present and thus we must avoid subregs from being simplified and eliminated
20749 ;; in later compilation phases.
20750 ;;
20751 ;; We have following variants from each instruction:
20752 ;; sse_andsf3 - the operation taking V4SF vector operands
20753 ;;              and doing TImode cast on them
20754 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20755 ;;                      TImode, since backend insist on eliminating casts
20756 ;;                      on memory operands
20757 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20758 ;;                   We cannot accept memory operand here as instruction reads
20759 ;;                   whole scalar.  This is generated only post reload by GCC
20760 ;;                   scalar float operations that expands to logicals (fabs)
20761 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20762 ;;                   memory operand.  Eventually combine can be able
20763 ;;                   to synthesize these using splitter.
20764 ;; sse2_anddf3, *sse2_anddf3_memory
20765 ;;              
20766 ;; 
20767 ;; These are not called andti3 etc. because we really really don't want
20768 ;; the compiler to widen DImode ands to TImode ands and then try to move
20769 ;; into DImode subregs of SSE registers, and them together, and move out
20770 ;; of DImode subregs again!
20771 ;; SSE1 single precision floating point logical operation
20772 (define_expand "sse_andv4sf3"
20773   [(set (match_operand:V4SF 0 "register_operand" "")
20774         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20775                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20776   "TARGET_SSE"
20777   "")
20778
20779 (define_insn "*sse_andv4sf3"
20780   [(set (match_operand:V4SF 0 "register_operand" "=x")
20781         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20782                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20783   "TARGET_SSE
20784    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20785   "andps\t{%2, %0|%0, %2}"
20786   [(set_attr "type" "sselog")
20787    (set_attr "mode" "V4SF")])
20788
20789 (define_expand "sse_nandv4sf3"
20790   [(set (match_operand:V4SF 0 "register_operand" "")
20791         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20792                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20793   "TARGET_SSE"
20794   "")
20795
20796 (define_insn "*sse_nandv4sf3"
20797   [(set (match_operand:V4SF 0 "register_operand" "=x")
20798         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20799                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20800   "TARGET_SSE"
20801   "andnps\t{%2, %0|%0, %2}"
20802   [(set_attr "type" "sselog")
20803    (set_attr "mode" "V4SF")])
20804
20805 (define_expand "sse_iorv4sf3"
20806   [(set (match_operand:V4SF 0 "register_operand" "")
20807         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20808                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20809   "TARGET_SSE"
20810   "")
20811
20812 (define_insn "*sse_iorv4sf3"
20813   [(set (match_operand:V4SF 0 "register_operand" "=x")
20814         (ior: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   "orps\t{%2, %0|%0, %2}"
20819   [(set_attr "type" "sselog")
20820    (set_attr "mode" "V4SF")])
20821
20822 (define_expand "sse_xorv4sf3"
20823   [(set (match_operand:V4SF 0 "register_operand" "")
20824         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20825                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20826   "TARGET_SSE"
20827   "")
20828
20829 (define_insn "*sse_xorv4sf3"
20830   [(set (match_operand:V4SF 0 "register_operand" "=x")
20831         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20832                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20833   "TARGET_SSE
20834    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20835   "xorps\t{%2, %0|%0, %2}"
20836   [(set_attr "type" "sselog")
20837    (set_attr "mode" "V4SF")])
20838
20839 ;; SSE2 double precision floating point logical operation
20840
20841 (define_expand "sse2_andv2df3"
20842   [(set (match_operand:V2DF 0 "register_operand" "")
20843         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20844                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20845   "TARGET_SSE2"
20846   "")
20847
20848 (define_insn "*sse2_andv2df3"
20849   [(set (match_operand:V2DF 0 "register_operand" "=x")
20850         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20851                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20852   "TARGET_SSE2
20853    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20854   "andpd\t{%2, %0|%0, %2}"
20855   [(set_attr "type" "sselog")
20856    (set_attr "mode" "V2DF")])
20857
20858 (define_expand "sse2_nandv2df3"
20859   [(set (match_operand:V2DF 0 "register_operand" "")
20860         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20861                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20862   "TARGET_SSE2"
20863   "")
20864
20865 (define_insn "*sse2_nandv2df3"
20866   [(set (match_operand:V2DF 0 "register_operand" "=x")
20867         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20868                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20869   "TARGET_SSE2"
20870   "andnpd\t{%2, %0|%0, %2}"
20871   [(set_attr "type" "sselog")
20872    (set_attr "mode" "V2DF")])
20873
20874 (define_expand "sse2_iorv2df3"
20875   [(set (match_operand:V2DF 0 "register_operand" "")
20876         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20877                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20878   "TARGET_SSE2"
20879   "")
20880
20881 (define_insn "*sse2_iorv2df3"
20882   [(set (match_operand:V2DF 0 "register_operand" "=x")
20883         (ior: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   "orpd\t{%2, %0|%0, %2}"
20888   [(set_attr "type" "sselog")
20889    (set_attr "mode" "V2DF")])
20890
20891 (define_expand "sse2_xorv2df3"
20892   [(set (match_operand:V2DF 0 "register_operand" "")
20893         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20894                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20895   "TARGET_SSE2"
20896   "")
20897
20898 (define_insn "*sse2_xorv2df3"
20899   [(set (match_operand:V2DF 0 "register_operand" "=x")
20900         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20901                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20902   "TARGET_SSE2
20903    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20904   "xorpd\t{%2, %0|%0, %2}"
20905   [(set_attr "type" "sselog")
20906    (set_attr "mode" "V2DF")])
20907
20908 ;; SSE2 integral logicals.  These patterns must always come after floating
20909 ;; point ones since we don't want compiler to use integer opcodes on floating
20910 ;; point SSE values to avoid matching of subregs in the match_operand.
20911 (define_insn "*sse2_andti3"
20912   [(set (match_operand:TI 0 "register_operand" "=x")
20913         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20914                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20915   "TARGET_SSE2
20916    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20917   "pand\t{%2, %0|%0, %2}"
20918   [(set_attr "type" "sselog")
20919    (set_attr "mode" "TI")])
20920
20921 (define_insn "sse2_andv2di3"
20922   [(set (match_operand:V2DI 0 "register_operand" "=x")
20923         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20924                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20925   "TARGET_SSE2
20926    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20927   "pand\t{%2, %0|%0, %2}"
20928   [(set_attr "type" "sselog")
20929    (set_attr "mode" "TI")])
20930
20931 (define_insn "*sse2_nandti3"
20932   [(set (match_operand:TI 0 "register_operand" "=x")
20933         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20934                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20935   "TARGET_SSE2"
20936   "pandn\t{%2, %0|%0, %2}"
20937   [(set_attr "type" "sselog")
20938    (set_attr "mode" "TI")])
20939
20940 (define_insn "sse2_nandv2di3"
20941   [(set (match_operand:V2DI 0 "register_operand" "=x")
20942         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20943                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20944   "TARGET_SSE2
20945    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20946   "pandn\t{%2, %0|%0, %2}"
20947   [(set_attr "type" "sselog")
20948    (set_attr "mode" "TI")])
20949
20950 (define_insn "*sse2_iorti3"
20951   [(set (match_operand:TI 0 "register_operand" "=x")
20952         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20953                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20954   "TARGET_SSE2
20955    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20956   "por\t{%2, %0|%0, %2}"
20957   [(set_attr "type" "sselog")
20958    (set_attr "mode" "TI")])
20959
20960 (define_insn "sse2_iorv2di3"
20961   [(set (match_operand:V2DI 0 "register_operand" "=x")
20962         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20963                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20964   "TARGET_SSE2
20965    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20966   "por\t{%2, %0|%0, %2}"
20967   [(set_attr "type" "sselog")
20968    (set_attr "mode" "TI")])
20969
20970 (define_insn "*sse2_xorti3"
20971   [(set (match_operand:TI 0 "register_operand" "=x")
20972         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20973                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20974   "TARGET_SSE2
20975    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20976   "pxor\t{%2, %0|%0, %2}"
20977   [(set_attr "type" "sselog")
20978    (set_attr "mode" "TI")])
20979
20980 (define_insn "sse2_xorv2di3"
20981   [(set (match_operand:V2DI 0 "register_operand" "=x")
20982         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20983                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20984   "TARGET_SSE2
20985    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20986   "pxor\t{%2, %0|%0, %2}"
20987   [(set_attr "type" "sselog")
20988    (set_attr "mode" "TI")])
20989
20990 ;; Use xor, but don't show input operands so they aren't live before
20991 ;; this insn.
20992 (define_insn "sse_clrv4sf"
20993   [(set (match_operand:V4SF 0 "register_operand" "=x")
20994         (match_operand:V4SF 1 "const0_operand" "X"))]
20995   "TARGET_SSE"
20996 {
20997   if (get_attr_mode (insn) == MODE_TI)
20998     return "pxor\t{%0, %0|%0, %0}";
20999   else
21000     return "xorps\t{%0, %0|%0, %0}";
21001 }
21002   [(set_attr "type" "sselog")
21003    (set_attr "memory" "none")
21004    (set (attr "mode")
21005         (if_then_else
21006            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21007                          (const_int 0))
21008                      (ne (symbol_ref "TARGET_SSE2")
21009                          (const_int 0)))
21010                 (eq (symbol_ref "optimize_size")
21011                     (const_int 0)))
21012          (const_string "TI")
21013          (const_string "V4SF")))])
21014
21015 ;; Use xor, but don't show input operands so they aren't live before
21016 ;; this insn.
21017 (define_insn "sse_clrv2df"
21018   [(set (match_operand:V2DF 0 "register_operand" "=x")
21019         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21020   "TARGET_SSE2"
21021   "xorpd\t{%0, %0|%0, %0}"
21022   [(set_attr "type" "sselog")
21023    (set_attr "memory" "none")
21024    (set_attr "mode" "V4SF")])
21025
21026 ;; SSE mask-generating compares
21027
21028 (define_insn "maskcmpv4sf3"
21029   [(set (match_operand:V4SI 0 "register_operand" "=x")
21030         (match_operator:V4SI 3 "sse_comparison_operator"
21031                 [(match_operand:V4SF 1 "register_operand" "0")
21032                  (match_operand:V4SF 2 "register_operand" "x")]))]
21033   "TARGET_SSE"
21034   "cmp%D3ps\t{%2, %0|%0, %2}"
21035   [(set_attr "type" "ssecmp")
21036    (set_attr "mode" "V4SF")])
21037
21038 (define_insn "maskncmpv4sf3"
21039   [(set (match_operand:V4SI 0 "register_operand" "=x")
21040         (not:V4SI
21041          (match_operator:V4SI 3 "sse_comparison_operator"
21042                 [(match_operand:V4SF 1 "register_operand" "0")
21043                  (match_operand:V4SF 2 "register_operand" "x")])))]
21044   "TARGET_SSE"
21045 {
21046   if (GET_CODE (operands[3]) == UNORDERED)
21047     return "cmpordps\t{%2, %0|%0, %2}";
21048   else
21049     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21050 }
21051   [(set_attr "type" "ssecmp")
21052    (set_attr "mode" "V4SF")])
21053
21054 (define_insn "vmmaskcmpv4sf3"
21055   [(set (match_operand:V4SI 0 "register_operand" "=x")
21056         (vec_merge:V4SI
21057          (match_operator:V4SI 3 "sse_comparison_operator"
21058                 [(match_operand:V4SF 1 "register_operand" "0")
21059                  (match_operand:V4SF 2 "register_operand" "x")])
21060          (subreg:V4SI (match_dup 1) 0)
21061          (const_int 1)))]
21062   "TARGET_SSE"
21063   "cmp%D3ss\t{%2, %0|%0, %2}"
21064   [(set_attr "type" "ssecmp")
21065    (set_attr "mode" "SF")])
21066
21067 (define_insn "vmmaskncmpv4sf3"
21068   [(set (match_operand:V4SI 0 "register_operand" "=x")
21069         (vec_merge:V4SI
21070          (not:V4SI
21071           (match_operator:V4SI 3 "sse_comparison_operator"
21072                 [(match_operand:V4SF 1 "register_operand" "0")
21073                  (match_operand:V4SF 2 "register_operand" "x")]))
21074          (subreg:V4SI (match_dup 1) 0)
21075          (const_int 1)))]
21076   "TARGET_SSE"
21077 {
21078   if (GET_CODE (operands[3]) == UNORDERED)
21079     return "cmpordss\t{%2, %0|%0, %2}";
21080   else
21081     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21082 }
21083   [(set_attr "type" "ssecmp")
21084    (set_attr "mode" "SF")])
21085
21086 (define_insn "sse_comi"
21087   [(set (reg:CCFP FLAGS_REG)
21088         (compare:CCFP (vec_select:SF
21089                        (match_operand:V4SF 0 "register_operand" "x")
21090                        (parallel [(const_int 0)]))
21091                       (vec_select:SF
21092                        (match_operand:V4SF 1 "register_operand" "x")
21093                        (parallel [(const_int 0)]))))]
21094   "TARGET_SSE"
21095   "comiss\t{%1, %0|%0, %1}"
21096   [(set_attr "type" "ssecomi")
21097    (set_attr "mode" "SF")])
21098
21099 (define_insn "sse_ucomi"
21100   [(set (reg:CCFPU FLAGS_REG)
21101         (compare:CCFPU (vec_select:SF
21102                         (match_operand:V4SF 0 "register_operand" "x")
21103                         (parallel [(const_int 0)]))
21104                        (vec_select:SF
21105                         (match_operand:V4SF 1 "register_operand" "x")
21106                         (parallel [(const_int 0)]))))]
21107   "TARGET_SSE"
21108   "ucomiss\t{%1, %0|%0, %1}"
21109   [(set_attr "type" "ssecomi")
21110    (set_attr "mode" "SF")])
21111
21112
21113 ;; SSE unpack
21114
21115 (define_insn "sse_unpckhps"
21116   [(set (match_operand:V4SF 0 "register_operand" "=x")
21117         (vec_merge:V4SF
21118          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21119                           (parallel [(const_int 2)
21120                                      (const_int 0)
21121                                      (const_int 3)
21122                                      (const_int 1)]))
21123          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21124                           (parallel [(const_int 0)
21125                                      (const_int 2)
21126                                      (const_int 1)
21127                                      (const_int 3)]))
21128          (const_int 5)))]
21129   "TARGET_SSE"
21130   "unpckhps\t{%2, %0|%0, %2}"
21131   [(set_attr "type" "ssecvt")
21132    (set_attr "mode" "V4SF")])
21133
21134 (define_insn "sse_unpcklps"
21135   [(set (match_operand:V4SF 0 "register_operand" "=x")
21136         (vec_merge:V4SF
21137          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21138                           (parallel [(const_int 0)
21139                                      (const_int 2)
21140                                      (const_int 1)
21141                                      (const_int 3)]))
21142          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21143                           (parallel [(const_int 2)
21144                                      (const_int 0)
21145                                      (const_int 3)
21146                                      (const_int 1)]))
21147          (const_int 5)))]
21148   "TARGET_SSE"
21149   "unpcklps\t{%2, %0|%0, %2}"
21150   [(set_attr "type" "ssecvt")
21151    (set_attr "mode" "V4SF")])
21152
21153
21154 ;; SSE min/max
21155
21156 (define_insn "smaxv4sf3"
21157   [(set (match_operand:V4SF 0 "register_operand" "=x")
21158         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21159                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21160   "TARGET_SSE"
21161   "maxps\t{%2, %0|%0, %2}"
21162   [(set_attr "type" "sse")
21163    (set_attr "mode" "V4SF")])
21164
21165 (define_insn "vmsmaxv4sf3"
21166   [(set (match_operand:V4SF 0 "register_operand" "=x")
21167         (vec_merge:V4SF
21168          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21169                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21170          (match_dup 1)
21171          (const_int 1)))]
21172   "TARGET_SSE"
21173   "maxss\t{%2, %0|%0, %2}"
21174   [(set_attr "type" "sse")
21175    (set_attr "mode" "SF")])
21176
21177 (define_insn "sminv4sf3"
21178   [(set (match_operand:V4SF 0 "register_operand" "=x")
21179         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21180                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21181   "TARGET_SSE"
21182   "minps\t{%2, %0|%0, %2}"
21183   [(set_attr "type" "sse")
21184    (set_attr "mode" "V4SF")])
21185
21186 (define_insn "vmsminv4sf3"
21187   [(set (match_operand:V4SF 0 "register_operand" "=x")
21188         (vec_merge:V4SF
21189          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21190                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21191          (match_dup 1)
21192          (const_int 1)))]
21193   "TARGET_SSE"
21194   "minss\t{%2, %0|%0, %2}"
21195   [(set_attr "type" "sse")
21196    (set_attr "mode" "SF")])
21197
21198 ;; SSE <-> integer/MMX conversions
21199
21200 (define_insn "cvtpi2ps"
21201   [(set (match_operand:V4SF 0 "register_operand" "=x")
21202         (vec_merge:V4SF
21203          (match_operand:V4SF 1 "register_operand" "0")
21204          (vec_duplicate:V4SF
21205           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21206          (const_int 12)))]
21207   "TARGET_SSE"
21208   "cvtpi2ps\t{%2, %0|%0, %2}"
21209   [(set_attr "type" "ssecvt")
21210    (set_attr "mode" "V4SF")])
21211
21212 (define_insn "cvtps2pi"
21213   [(set (match_operand:V2SI 0 "register_operand" "=y")
21214         (vec_select:V2SI
21215          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21216          (parallel [(const_int 0) (const_int 1)])))]
21217   "TARGET_SSE"
21218   "cvtps2pi\t{%1, %0|%0, %1}"
21219   [(set_attr "type" "ssecvt")
21220    (set_attr "mode" "V4SF")])
21221
21222 (define_insn "cvttps2pi"
21223   [(set (match_operand:V2SI 0 "register_operand" "=y")
21224         (vec_select:V2SI
21225          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21226                       UNSPEC_FIX)
21227          (parallel [(const_int 0) (const_int 1)])))]
21228   "TARGET_SSE"
21229   "cvttps2pi\t{%1, %0|%0, %1}"
21230   [(set_attr "type" "ssecvt")
21231    (set_attr "mode" "SF")])
21232
21233 (define_insn "cvtsi2ss"
21234   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21235         (vec_merge:V4SF
21236          (match_operand:V4SF 1 "register_operand" "0,0")
21237          (vec_duplicate:V4SF
21238           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21239          (const_int 14)))]
21240   "TARGET_SSE"
21241   "cvtsi2ss\t{%2, %0|%0, %2}"
21242   [(set_attr "type" "sseicvt")
21243    (set_attr "athlon_decode" "vector,double")
21244    (set_attr "mode" "SF")])
21245
21246 (define_insn "cvtsi2ssq"
21247   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21248         (vec_merge:V4SF
21249          (match_operand:V4SF 1 "register_operand" "0,0")
21250          (vec_duplicate:V4SF
21251           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21252          (const_int 14)))]
21253   "TARGET_SSE && TARGET_64BIT"
21254   "cvtsi2ssq\t{%2, %0|%0, %2}"
21255   [(set_attr "type" "sseicvt")
21256    (set_attr "athlon_decode" "vector,double")
21257    (set_attr "mode" "SF")])
21258
21259 (define_insn "cvtss2si"
21260   [(set (match_operand:SI 0 "register_operand" "=r,r")
21261         (vec_select:SI
21262          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21263          (parallel [(const_int 0)])))]
21264   "TARGET_SSE"
21265   "cvtss2si\t{%1, %0|%0, %1}"
21266   [(set_attr "type" "sseicvt")
21267    (set_attr "athlon_decode" "double,vector")
21268    (set_attr "mode" "SI")])
21269
21270 (define_insn "cvtss2siq"
21271   [(set (match_operand:DI 0 "register_operand" "=r,r")
21272         (vec_select:DI
21273          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21274          (parallel [(const_int 0)])))]
21275   "TARGET_SSE"
21276   "cvtss2siq\t{%1, %0|%0, %1}"
21277   [(set_attr "type" "sseicvt")
21278    (set_attr "athlon_decode" "double,vector")
21279    (set_attr "mode" "DI")])
21280
21281 (define_insn "cvttss2si"
21282   [(set (match_operand:SI 0 "register_operand" "=r,r")
21283         (vec_select:SI
21284          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21285                       UNSPEC_FIX)
21286          (parallel [(const_int 0)])))]
21287   "TARGET_SSE"
21288   "cvttss2si\t{%1, %0|%0, %1}"
21289   [(set_attr "type" "sseicvt")
21290    (set_attr "mode" "SF")
21291    (set_attr "athlon_decode" "double,vector")])
21292
21293 (define_insn "cvttss2siq"
21294   [(set (match_operand:DI 0 "register_operand" "=r,r")
21295         (vec_select:DI
21296          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21297                       UNSPEC_FIX)
21298          (parallel [(const_int 0)])))]
21299   "TARGET_SSE && TARGET_64BIT"
21300   "cvttss2siq\t{%1, %0|%0, %1}"
21301   [(set_attr "type" "sseicvt")
21302    (set_attr "mode" "SF")
21303    (set_attr "athlon_decode" "double,vector")])
21304
21305
21306 ;; MMX insns
21307
21308 ;; MMX arithmetic
21309
21310 (define_insn "addv8qi3"
21311   [(set (match_operand:V8QI 0 "register_operand" "=y")
21312         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21313                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21314   "TARGET_MMX"
21315   "paddb\t{%2, %0|%0, %2}"
21316   [(set_attr "type" "mmxadd")
21317    (set_attr "mode" "DI")])
21318
21319 (define_insn "addv4hi3"
21320   [(set (match_operand:V4HI 0 "register_operand" "=y")
21321         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21322                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21323   "TARGET_MMX"
21324   "paddw\t{%2, %0|%0, %2}"
21325   [(set_attr "type" "mmxadd")
21326    (set_attr "mode" "DI")])
21327
21328 (define_insn "addv2si3"
21329   [(set (match_operand:V2SI 0 "register_operand" "=y")
21330         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21331                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21332   "TARGET_MMX"
21333   "paddd\t{%2, %0|%0, %2}"
21334   [(set_attr "type" "mmxadd")
21335    (set_attr "mode" "DI")])
21336
21337 (define_insn "mmx_adddi3"
21338   [(set (match_operand:DI 0 "register_operand" "=y")
21339         (unspec:DI
21340          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21341                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21342          UNSPEC_NOP))]
21343   "TARGET_MMX"
21344   "paddq\t{%2, %0|%0, %2}"
21345   [(set_attr "type" "mmxadd")
21346    (set_attr "mode" "DI")])
21347
21348 (define_insn "ssaddv8qi3"
21349   [(set (match_operand:V8QI 0 "register_operand" "=y")
21350         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21351                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21352   "TARGET_MMX"
21353   "paddsb\t{%2, %0|%0, %2}"
21354   [(set_attr "type" "mmxadd")
21355    (set_attr "mode" "DI")])
21356
21357 (define_insn "ssaddv4hi3"
21358   [(set (match_operand:V4HI 0 "register_operand" "=y")
21359         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21360                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21361   "TARGET_MMX"
21362   "paddsw\t{%2, %0|%0, %2}"
21363   [(set_attr "type" "mmxadd")
21364    (set_attr "mode" "DI")])
21365
21366 (define_insn "usaddv8qi3"
21367   [(set (match_operand:V8QI 0 "register_operand" "=y")
21368         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21369                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21370   "TARGET_MMX"
21371   "paddusb\t{%2, %0|%0, %2}"
21372   [(set_attr "type" "mmxadd")
21373    (set_attr "mode" "DI")])
21374
21375 (define_insn "usaddv4hi3"
21376   [(set (match_operand:V4HI 0 "register_operand" "=y")
21377         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21378                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21379   "TARGET_MMX"
21380   "paddusw\t{%2, %0|%0, %2}"
21381   [(set_attr "type" "mmxadd")
21382    (set_attr "mode" "DI")])
21383
21384 (define_insn "subv8qi3"
21385   [(set (match_operand:V8QI 0 "register_operand" "=y")
21386         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21387                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21388   "TARGET_MMX"
21389   "psubb\t{%2, %0|%0, %2}"
21390   [(set_attr "type" "mmxadd")
21391    (set_attr "mode" "DI")])
21392
21393 (define_insn "subv4hi3"
21394   [(set (match_operand:V4HI 0 "register_operand" "=y")
21395         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21396                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21397   "TARGET_MMX"
21398   "psubw\t{%2, %0|%0, %2}"
21399   [(set_attr "type" "mmxadd")
21400    (set_attr "mode" "DI")])
21401
21402 (define_insn "subv2si3"
21403   [(set (match_operand:V2SI 0 "register_operand" "=y")
21404         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21405                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21406   "TARGET_MMX"
21407   "psubd\t{%2, %0|%0, %2}"
21408   [(set_attr "type" "mmxadd")
21409    (set_attr "mode" "DI")])
21410
21411 (define_insn "mmx_subdi3"
21412   [(set (match_operand:DI 0 "register_operand" "=y")
21413         (unspec:DI
21414          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21415                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21416          UNSPEC_NOP))]
21417   "TARGET_MMX"
21418   "psubq\t{%2, %0|%0, %2}"
21419   [(set_attr "type" "mmxadd")
21420    (set_attr "mode" "DI")])
21421
21422 (define_insn "sssubv8qi3"
21423   [(set (match_operand:V8QI 0 "register_operand" "=y")
21424         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21425                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21426   "TARGET_MMX"
21427   "psubsb\t{%2, %0|%0, %2}"
21428   [(set_attr "type" "mmxadd")
21429    (set_attr "mode" "DI")])
21430
21431 (define_insn "sssubv4hi3"
21432   [(set (match_operand:V4HI 0 "register_operand" "=y")
21433         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21434                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21435   "TARGET_MMX"
21436   "psubsw\t{%2, %0|%0, %2}"
21437   [(set_attr "type" "mmxadd")
21438    (set_attr "mode" "DI")])
21439
21440 (define_insn "ussubv8qi3"
21441   [(set (match_operand:V8QI 0 "register_operand" "=y")
21442         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21443                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21444   "TARGET_MMX"
21445   "psubusb\t{%2, %0|%0, %2}"
21446   [(set_attr "type" "mmxadd")
21447    (set_attr "mode" "DI")])
21448
21449 (define_insn "ussubv4hi3"
21450   [(set (match_operand:V4HI 0 "register_operand" "=y")
21451         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21452                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21453   "TARGET_MMX"
21454   "psubusw\t{%2, %0|%0, %2}"
21455   [(set_attr "type" "mmxadd")
21456    (set_attr "mode" "DI")])
21457
21458 (define_insn "mulv4hi3"
21459   [(set (match_operand:V4HI 0 "register_operand" "=y")
21460         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21461                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21462   "TARGET_MMX"
21463   "pmullw\t{%2, %0|%0, %2}"
21464   [(set_attr "type" "mmxmul")
21465    (set_attr "mode" "DI")])
21466
21467 (define_insn "smulv4hi3_highpart"
21468   [(set (match_operand:V4HI 0 "register_operand" "=y")
21469         (truncate:V4HI
21470          (lshiftrt:V4SI
21471           (mult:V4SI (sign_extend:V4SI
21472                       (match_operand:V4HI 1 "register_operand" "0"))
21473                      (sign_extend:V4SI
21474                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21475           (const_int 16))))]
21476   "TARGET_MMX"
21477   "pmulhw\t{%2, %0|%0, %2}"
21478   [(set_attr "type" "mmxmul")
21479    (set_attr "mode" "DI")])
21480
21481 (define_insn "umulv4hi3_highpart"
21482   [(set (match_operand:V4HI 0 "register_operand" "=y")
21483         (truncate:V4HI
21484          (lshiftrt:V4SI
21485           (mult:V4SI (zero_extend:V4SI
21486                       (match_operand:V4HI 1 "register_operand" "0"))
21487                      (zero_extend:V4SI
21488                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21489           (const_int 16))))]
21490   "TARGET_SSE || TARGET_3DNOW_A"
21491   "pmulhuw\t{%2, %0|%0, %2}"
21492   [(set_attr "type" "mmxmul")
21493    (set_attr "mode" "DI")])
21494
21495 (define_insn "mmx_pmaddwd"
21496   [(set (match_operand:V2SI 0 "register_operand" "=y")
21497         (plus:V2SI
21498          (mult:V2SI
21499           (sign_extend:V2SI
21500            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21501                             (parallel [(const_int 0) (const_int 2)])))
21502           (sign_extend:V2SI
21503            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21504                             (parallel [(const_int 0) (const_int 2)]))))
21505          (mult:V2SI
21506           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21507                                              (parallel [(const_int 1)
21508                                                         (const_int 3)])))
21509           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21510                                              (parallel [(const_int 1)
21511                                                         (const_int 3)]))))))]
21512   "TARGET_MMX"
21513   "pmaddwd\t{%2, %0|%0, %2}"
21514   [(set_attr "type" "mmxmul")
21515    (set_attr "mode" "DI")])
21516
21517
21518 ;; MMX logical operations
21519 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21520 ;; normal code that also wants to use the FPU from getting broken.
21521 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21522 (define_insn "mmx_iordi3"
21523   [(set (match_operand:DI 0 "register_operand" "=y")
21524         (unspec:DI
21525          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21526                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21527          UNSPEC_NOP))]
21528   "TARGET_MMX"
21529   "por\t{%2, %0|%0, %2}"
21530   [(set_attr "type" "mmxadd")
21531    (set_attr "mode" "DI")])
21532
21533 (define_insn "mmx_xordi3"
21534   [(set (match_operand:DI 0 "register_operand" "=y")
21535         (unspec:DI
21536          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21537                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21538          UNSPEC_NOP))]
21539   "TARGET_MMX"
21540   "pxor\t{%2, %0|%0, %2}"
21541   [(set_attr "type" "mmxadd")
21542    (set_attr "mode" "DI")
21543    (set_attr "memory" "none")])
21544
21545 ;; Same as pxor, but don't show input operands so that we don't think
21546 ;; they are live.
21547 (define_insn "mmx_clrdi"
21548   [(set (match_operand:DI 0 "register_operand" "=y")
21549         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21550   "TARGET_MMX"
21551   "pxor\t{%0, %0|%0, %0}"
21552   [(set_attr "type" "mmxadd")
21553    (set_attr "mode" "DI")
21554    (set_attr "memory" "none")])
21555
21556 (define_insn "mmx_anddi3"
21557   [(set (match_operand:DI 0 "register_operand" "=y")
21558         (unspec:DI
21559          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21560                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21561          UNSPEC_NOP))]
21562   "TARGET_MMX"
21563   "pand\t{%2, %0|%0, %2}"
21564   [(set_attr "type" "mmxadd")
21565    (set_attr "mode" "DI")])
21566
21567 (define_insn "mmx_nanddi3"
21568   [(set (match_operand:DI 0 "register_operand" "=y")
21569         (unspec:DI
21570          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21571                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21572          UNSPEC_NOP))]
21573   "TARGET_MMX"
21574   "pandn\t{%2, %0|%0, %2}"
21575   [(set_attr "type" "mmxadd")
21576    (set_attr "mode" "DI")])
21577
21578
21579 ;; MMX unsigned averages/sum of absolute differences
21580
21581 (define_insn "mmx_uavgv8qi3"
21582   [(set (match_operand:V8QI 0 "register_operand" "=y")
21583         (ashiftrt:V8QI
21584          (plus:V8QI (plus:V8QI
21585                      (match_operand:V8QI 1 "register_operand" "0")
21586                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21587                     (const_vector:V8QI [(const_int 1)
21588                                         (const_int 1)
21589                                         (const_int 1)
21590                                         (const_int 1)
21591                                         (const_int 1)
21592                                         (const_int 1)
21593                                         (const_int 1)
21594                                         (const_int 1)]))
21595          (const_int 1)))]
21596   "TARGET_SSE || TARGET_3DNOW_A"
21597   "pavgb\t{%2, %0|%0, %2}"
21598   [(set_attr "type" "mmxshft")
21599    (set_attr "mode" "DI")])
21600
21601 (define_insn "mmx_uavgv4hi3"
21602   [(set (match_operand:V4HI 0 "register_operand" "=y")
21603         (ashiftrt:V4HI
21604          (plus:V4HI (plus:V4HI
21605                      (match_operand:V4HI 1 "register_operand" "0")
21606                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21607                     (const_vector:V4HI [(const_int 1)
21608                                         (const_int 1)
21609                                         (const_int 1)
21610                                         (const_int 1)]))
21611          (const_int 1)))]
21612   "TARGET_SSE || TARGET_3DNOW_A"
21613   "pavgw\t{%2, %0|%0, %2}"
21614   [(set_attr "type" "mmxshft")
21615    (set_attr "mode" "DI")])
21616
21617 (define_insn "mmx_psadbw"
21618   [(set (match_operand:DI 0 "register_operand" "=y")
21619         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21620                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21621                    UNSPEC_PSADBW))]
21622   "TARGET_SSE || TARGET_3DNOW_A"
21623   "psadbw\t{%2, %0|%0, %2}"
21624   [(set_attr "type" "mmxshft")
21625    (set_attr "mode" "DI")])
21626
21627
21628 ;; MMX insert/extract/shuffle
21629
21630 (define_insn "mmx_pinsrw"
21631   [(set (match_operand:V4HI 0 "register_operand" "=y")
21632         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21633                         (vec_duplicate:V4HI
21634                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21635                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21636   "TARGET_SSE || TARGET_3DNOW_A"
21637   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21638   [(set_attr "type" "mmxcvt")
21639    (set_attr "mode" "DI")])
21640
21641 (define_insn "mmx_pextrw"
21642   [(set (match_operand:SI 0 "register_operand" "=r")
21643         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21644                                        (parallel
21645                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21646   "TARGET_SSE || TARGET_3DNOW_A"
21647   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21648   [(set_attr "type" "mmxcvt")
21649    (set_attr "mode" "DI")])
21650
21651 (define_insn "mmx_pshufw"
21652   [(set (match_operand:V4HI 0 "register_operand" "=y")
21653         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21654                       (match_operand:SI 2 "immediate_operand" "i")]
21655                      UNSPEC_SHUFFLE))]
21656   "TARGET_SSE || TARGET_3DNOW_A"
21657   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21658   [(set_attr "type" "mmxcvt")
21659    (set_attr "mode" "DI")])
21660
21661
21662 ;; MMX mask-generating comparisons
21663
21664 (define_insn "eqv8qi3"
21665   [(set (match_operand:V8QI 0 "register_operand" "=y")
21666         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21667                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21668   "TARGET_MMX"
21669   "pcmpeqb\t{%2, %0|%0, %2}"
21670   [(set_attr "type" "mmxcmp")
21671    (set_attr "mode" "DI")])
21672
21673 (define_insn "eqv4hi3"
21674   [(set (match_operand:V4HI 0 "register_operand" "=y")
21675         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21676                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21677   "TARGET_MMX"
21678   "pcmpeqw\t{%2, %0|%0, %2}"
21679   [(set_attr "type" "mmxcmp")
21680    (set_attr "mode" "DI")])
21681
21682 (define_insn "eqv2si3"
21683   [(set (match_operand:V2SI 0 "register_operand" "=y")
21684         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21685                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21686   "TARGET_MMX"
21687   "pcmpeqd\t{%2, %0|%0, %2}"
21688   [(set_attr "type" "mmxcmp")
21689    (set_attr "mode" "DI")])
21690
21691 (define_insn "gtv8qi3"
21692   [(set (match_operand:V8QI 0 "register_operand" "=y")
21693         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21694                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21695   "TARGET_MMX"
21696   "pcmpgtb\t{%2, %0|%0, %2}"
21697   [(set_attr "type" "mmxcmp")
21698    (set_attr "mode" "DI")])
21699
21700 (define_insn "gtv4hi3"
21701   [(set (match_operand:V4HI 0 "register_operand" "=y")
21702         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21703                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21704   "TARGET_MMX"
21705   "pcmpgtw\t{%2, %0|%0, %2}"
21706   [(set_attr "type" "mmxcmp")
21707    (set_attr "mode" "DI")])
21708
21709 (define_insn "gtv2si3"
21710   [(set (match_operand:V2SI 0 "register_operand" "=y")
21711         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21712                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21713   "TARGET_MMX"
21714   "pcmpgtd\t{%2, %0|%0, %2}"
21715   [(set_attr "type" "mmxcmp")
21716    (set_attr "mode" "DI")])
21717
21718
21719 ;; MMX max/min insns
21720
21721 (define_insn "umaxv8qi3"
21722   [(set (match_operand:V8QI 0 "register_operand" "=y")
21723         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21724                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21725   "TARGET_SSE || TARGET_3DNOW_A"
21726   "pmaxub\t{%2, %0|%0, %2}"
21727   [(set_attr "type" "mmxadd")
21728    (set_attr "mode" "DI")])
21729
21730 (define_insn "smaxv4hi3"
21731   [(set (match_operand:V4HI 0 "register_operand" "=y")
21732         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21733                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21734   "TARGET_SSE || TARGET_3DNOW_A"
21735   "pmaxsw\t{%2, %0|%0, %2}"
21736   [(set_attr "type" "mmxadd")
21737    (set_attr "mode" "DI")])
21738
21739 (define_insn "uminv8qi3"
21740   [(set (match_operand:V8QI 0 "register_operand" "=y")
21741         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21742                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21743   "TARGET_SSE || TARGET_3DNOW_A"
21744   "pminub\t{%2, %0|%0, %2}"
21745   [(set_attr "type" "mmxadd")
21746    (set_attr "mode" "DI")])
21747
21748 (define_insn "sminv4hi3"
21749   [(set (match_operand:V4HI 0 "register_operand" "=y")
21750         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21751                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21752   "TARGET_SSE || TARGET_3DNOW_A"
21753   "pminsw\t{%2, %0|%0, %2}"
21754   [(set_attr "type" "mmxadd")
21755    (set_attr "mode" "DI")])
21756
21757
21758 ;; MMX shifts
21759
21760 (define_insn "ashrv4hi3"
21761   [(set (match_operand:V4HI 0 "register_operand" "=y")
21762         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21763                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21764   "TARGET_MMX"
21765   "psraw\t{%2, %0|%0, %2}"
21766   [(set_attr "type" "mmxshft")
21767    (set_attr "mode" "DI")])
21768
21769 (define_insn "ashrv2si3"
21770   [(set (match_operand:V2SI 0 "register_operand" "=y")
21771         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21772                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21773   "TARGET_MMX"
21774   "psrad\t{%2, %0|%0, %2}"
21775   [(set_attr "type" "mmxshft")
21776    (set_attr "mode" "DI")])
21777
21778 (define_insn "lshrv4hi3"
21779   [(set (match_operand:V4HI 0 "register_operand" "=y")
21780         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21781                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21782   "TARGET_MMX"
21783   "psrlw\t{%2, %0|%0, %2}"
21784   [(set_attr "type" "mmxshft")
21785    (set_attr "mode" "DI")])
21786
21787 (define_insn "lshrv2si3"
21788   [(set (match_operand:V2SI 0 "register_operand" "=y")
21789         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21790                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21791   "TARGET_MMX"
21792   "psrld\t{%2, %0|%0, %2}"
21793   [(set_attr "type" "mmxshft")
21794    (set_attr "mode" "DI")])
21795
21796 ;; See logical MMX insns.
21797 (define_insn "mmx_lshrdi3"
21798   [(set (match_operand:DI 0 "register_operand" "=y")
21799         (unspec:DI
21800           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21801                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21802           UNSPEC_NOP))]
21803   "TARGET_MMX"
21804   "psrlq\t{%2, %0|%0, %2}"
21805   [(set_attr "type" "mmxshft")
21806    (set_attr "mode" "DI")])
21807
21808 (define_insn "ashlv4hi3"
21809   [(set (match_operand:V4HI 0 "register_operand" "=y")
21810         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21811                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21812   "TARGET_MMX"
21813   "psllw\t{%2, %0|%0, %2}"
21814   [(set_attr "type" "mmxshft")
21815    (set_attr "mode" "DI")])
21816
21817 (define_insn "ashlv2si3"
21818   [(set (match_operand:V2SI 0 "register_operand" "=y")
21819         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21820                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21821   "TARGET_MMX"
21822   "pslld\t{%2, %0|%0, %2}"
21823   [(set_attr "type" "mmxshft")
21824    (set_attr "mode" "DI")])
21825
21826 ;; See logical MMX insns.
21827 (define_insn "mmx_ashldi3"
21828   [(set (match_operand:DI 0 "register_operand" "=y")
21829         (unspec:DI
21830          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21831                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21832          UNSPEC_NOP))]
21833   "TARGET_MMX"
21834   "psllq\t{%2, %0|%0, %2}"
21835   [(set_attr "type" "mmxshft")
21836    (set_attr "mode" "DI")])
21837
21838
21839 ;; MMX pack/unpack insns.
21840
21841 (define_insn "mmx_packsswb"
21842   [(set (match_operand:V8QI 0 "register_operand" "=y")
21843         (vec_concat:V8QI
21844          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21845          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21846   "TARGET_MMX"
21847   "packsswb\t{%2, %0|%0, %2}"
21848   [(set_attr "type" "mmxshft")
21849    (set_attr "mode" "DI")])
21850
21851 (define_insn "mmx_packssdw"
21852   [(set (match_operand:V4HI 0 "register_operand" "=y")
21853         (vec_concat:V4HI
21854          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21855          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21856   "TARGET_MMX"
21857   "packssdw\t{%2, %0|%0, %2}"
21858   [(set_attr "type" "mmxshft")
21859    (set_attr "mode" "DI")])
21860
21861 (define_insn "mmx_packuswb"
21862   [(set (match_operand:V8QI 0 "register_operand" "=y")
21863         (vec_concat:V8QI
21864          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21865          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21866   "TARGET_MMX"
21867   "packuswb\t{%2, %0|%0, %2}"
21868   [(set_attr "type" "mmxshft")
21869    (set_attr "mode" "DI")])
21870
21871 (define_insn "mmx_punpckhbw"
21872   [(set (match_operand:V8QI 0 "register_operand" "=y")
21873         (vec_merge:V8QI
21874          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21875                           (parallel [(const_int 4)
21876                                      (const_int 0)
21877                                      (const_int 5)
21878                                      (const_int 1)
21879                                      (const_int 6)
21880                                      (const_int 2)
21881                                      (const_int 7)
21882                                      (const_int 3)]))
21883          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21884                           (parallel [(const_int 0)
21885                                      (const_int 4)
21886                                      (const_int 1)
21887                                      (const_int 5)
21888                                      (const_int 2)
21889                                      (const_int 6)
21890                                      (const_int 3)
21891                                      (const_int 7)]))
21892          (const_int 85)))]
21893   "TARGET_MMX"
21894   "punpckhbw\t{%2, %0|%0, %2}"
21895   [(set_attr "type" "mmxcvt")
21896    (set_attr "mode" "DI")])
21897
21898 (define_insn "mmx_punpckhwd"
21899   [(set (match_operand:V4HI 0 "register_operand" "=y")
21900         (vec_merge:V4HI
21901          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21902                           (parallel [(const_int 0)
21903                                      (const_int 2)
21904                                      (const_int 1)
21905                                      (const_int 3)]))
21906          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21907                           (parallel [(const_int 2)
21908                                      (const_int 0)
21909                                      (const_int 3)
21910                                      (const_int 1)]))
21911          (const_int 5)))]
21912   "TARGET_MMX"
21913   "punpckhwd\t{%2, %0|%0, %2}"
21914   [(set_attr "type" "mmxcvt")
21915    (set_attr "mode" "DI")])
21916
21917 (define_insn "mmx_punpckhdq"
21918   [(set (match_operand:V2SI 0 "register_operand" "=y")
21919         (vec_merge:V2SI
21920          (match_operand:V2SI 1 "register_operand" "0")
21921          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21922                           (parallel [(const_int 1)
21923                                      (const_int 0)]))
21924          (const_int 1)))]
21925   "TARGET_MMX"
21926   "punpckhdq\t{%2, %0|%0, %2}"
21927   [(set_attr "type" "mmxcvt")
21928    (set_attr "mode" "DI")])
21929
21930 (define_insn "mmx_punpcklbw"
21931   [(set (match_operand:V8QI 0 "register_operand" "=y")
21932         (vec_merge:V8QI
21933          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21934                           (parallel [(const_int 0)
21935                                      (const_int 4)
21936                                      (const_int 1)
21937                                      (const_int 5)
21938                                      (const_int 2)
21939                                      (const_int 6)
21940                                      (const_int 3)
21941                                      (const_int 7)]))
21942          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21943                           (parallel [(const_int 4)
21944                                      (const_int 0)
21945                                      (const_int 5)
21946                                      (const_int 1)
21947                                      (const_int 6)
21948                                      (const_int 2)
21949                                      (const_int 7)
21950                                      (const_int 3)]))
21951          (const_int 85)))]
21952   "TARGET_MMX"
21953   "punpcklbw\t{%2, %0|%0, %2}"
21954   [(set_attr "type" "mmxcvt")
21955    (set_attr "mode" "DI")])
21956
21957 (define_insn "mmx_punpcklwd"
21958   [(set (match_operand:V4HI 0 "register_operand" "=y")
21959         (vec_merge:V4HI
21960          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21961                           (parallel [(const_int 2)
21962                                      (const_int 0)
21963                                      (const_int 3)
21964                                      (const_int 1)]))
21965          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21966                           (parallel [(const_int 0)
21967                                      (const_int 2)
21968                                      (const_int 1)
21969                                      (const_int 3)]))
21970          (const_int 5)))]
21971   "TARGET_MMX"
21972   "punpcklwd\t{%2, %0|%0, %2}"
21973   [(set_attr "type" "mmxcvt")
21974    (set_attr "mode" "DI")])
21975
21976 (define_insn "mmx_punpckldq"
21977   [(set (match_operand:V2SI 0 "register_operand" "=y")
21978         (vec_merge:V2SI
21979          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21980                            (parallel [(const_int 1)
21981                                       (const_int 0)]))
21982          (match_operand:V2SI 2 "register_operand" "y")
21983          (const_int 1)))]
21984   "TARGET_MMX"
21985   "punpckldq\t{%2, %0|%0, %2}"
21986   [(set_attr "type" "mmxcvt")
21987    (set_attr "mode" "DI")])
21988
21989
21990 ;; Miscellaneous stuff
21991
21992 (define_insn "emms"
21993   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21994    (clobber (reg:XF 8))
21995    (clobber (reg:XF 9))
21996    (clobber (reg:XF 10))
21997    (clobber (reg:XF 11))
21998    (clobber (reg:XF 12))
21999    (clobber (reg:XF 13))
22000    (clobber (reg:XF 14))
22001    (clobber (reg:XF 15))
22002    (clobber (reg:DI 29))
22003    (clobber (reg:DI 30))
22004    (clobber (reg:DI 31))
22005    (clobber (reg:DI 32))
22006    (clobber (reg:DI 33))
22007    (clobber (reg:DI 34))
22008    (clobber (reg:DI 35))
22009    (clobber (reg:DI 36))]
22010   "TARGET_MMX"
22011   "emms"
22012   [(set_attr "type" "mmx")
22013    (set_attr "memory" "unknown")])
22014
22015 (define_insn "ldmxcsr"
22016   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22017                     UNSPECV_LDMXCSR)]
22018   "TARGET_SSE"
22019   "ldmxcsr\t%0"
22020   [(set_attr "type" "sse")
22021    (set_attr "memory" "load")])
22022
22023 (define_insn "stmxcsr"
22024   [(set (match_operand:SI 0 "memory_operand" "=m")
22025         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22026   "TARGET_SSE"
22027   "stmxcsr\t%0"
22028   [(set_attr "type" "sse")
22029    (set_attr "memory" "store")])
22030
22031 (define_expand "sfence"
22032   [(set (match_dup 0)
22033         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22034   "TARGET_SSE || TARGET_3DNOW_A"
22035 {
22036   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22037   MEM_VOLATILE_P (operands[0]) = 1;
22038 })
22039
22040 (define_insn "*sfence_insn"
22041   [(set (match_operand:BLK 0 "" "")
22042         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22043   "TARGET_SSE || TARGET_3DNOW_A"
22044   "sfence"
22045   [(set_attr "type" "sse")
22046    (set_attr "memory" "unknown")])
22047
22048 (define_expand "sse_prologue_save"
22049   [(parallel [(set (match_operand:BLK 0 "" "")
22050                    (unspec:BLK [(reg:DI 21)
22051                                 (reg:DI 22)
22052                                 (reg:DI 23)
22053                                 (reg:DI 24)
22054                                 (reg:DI 25)
22055                                 (reg:DI 26)
22056                                 (reg:DI 27)
22057                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22058               (use (match_operand:DI 1 "register_operand" ""))
22059               (use (match_operand:DI 2 "immediate_operand" ""))
22060               (use (label_ref:DI (match_operand 3 "" "")))])]
22061   "TARGET_64BIT"
22062   "")
22063
22064 (define_insn "*sse_prologue_save_insn"
22065   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22066                           (match_operand:DI 4 "const_int_operand" "n")))
22067         (unspec:BLK [(reg:DI 21)
22068                      (reg:DI 22)
22069                      (reg:DI 23)
22070                      (reg:DI 24)
22071                      (reg:DI 25)
22072                      (reg:DI 26)
22073                      (reg:DI 27)
22074                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22075    (use (match_operand:DI 1 "register_operand" "r"))
22076    (use (match_operand:DI 2 "const_int_operand" "i"))
22077    (use (label_ref:DI (match_operand 3 "" "X")))]
22078   "TARGET_64BIT
22079    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22080    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22081   "*
22082 {
22083   int i;
22084   operands[0] = gen_rtx_MEM (Pmode,
22085                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22086   output_asm_insn (\"jmp\\t%A1\", operands);
22087   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22088     {
22089       operands[4] = adjust_address (operands[0], DImode, i*16);
22090       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22091       PUT_MODE (operands[4], TImode);
22092       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22093         output_asm_insn (\"rex\", operands);
22094       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22095     }
22096   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22097                              CODE_LABEL_NUMBER (operands[3]));
22098   RET;
22099 }
22100   "
22101   [(set_attr "type" "other")
22102    (set_attr "length_immediate" "0")
22103    (set_attr "length_address" "0")
22104    (set_attr "length" "135")
22105    (set_attr "memory" "store")
22106    (set_attr "modrm" "0")
22107    (set_attr "mode" "DI")])
22108
22109 ;; 3Dnow! instructions
22110
22111 (define_insn "addv2sf3"
22112   [(set (match_operand:V2SF 0 "register_operand" "=y")
22113         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22114                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22115   "TARGET_3DNOW"
22116   "pfadd\\t{%2, %0|%0, %2}"
22117   [(set_attr "type" "mmxadd")
22118    (set_attr "mode" "V2SF")])
22119
22120 (define_insn "subv2sf3"
22121   [(set (match_operand:V2SF 0 "register_operand" "=y")
22122         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22123                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22124   "TARGET_3DNOW"
22125   "pfsub\\t{%2, %0|%0, %2}"
22126   [(set_attr "type" "mmxadd")
22127    (set_attr "mode" "V2SF")])
22128
22129 (define_insn "subrv2sf3"
22130   [(set (match_operand:V2SF 0 "register_operand" "=y")
22131         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22132                     (match_operand:V2SF 1 "register_operand" "0")))]
22133   "TARGET_3DNOW"
22134   "pfsubr\\t{%2, %0|%0, %2}"
22135   [(set_attr "type" "mmxadd")
22136    (set_attr "mode" "V2SF")])
22137
22138 (define_insn "gtv2sf3"
22139   [(set (match_operand:V2SI 0 "register_operand" "=y")
22140         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22141                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22142  "TARGET_3DNOW"
22143   "pfcmpgt\\t{%2, %0|%0, %2}"
22144   [(set_attr "type" "mmxcmp")
22145    (set_attr "mode" "V2SF")])
22146
22147 (define_insn "gev2sf3"
22148   [(set (match_operand:V2SI 0 "register_operand" "=y")
22149         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22150                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22151   "TARGET_3DNOW"
22152   "pfcmpge\\t{%2, %0|%0, %2}"
22153   [(set_attr "type" "mmxcmp")
22154    (set_attr "mode" "V2SF")])
22155
22156 (define_insn "eqv2sf3"
22157   [(set (match_operand:V2SI 0 "register_operand" "=y")
22158         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22159                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22160   "TARGET_3DNOW"
22161   "pfcmpeq\\t{%2, %0|%0, %2}"
22162   [(set_attr "type" "mmxcmp")
22163    (set_attr "mode" "V2SF")])
22164
22165 (define_insn "pfmaxv2sf3"
22166   [(set (match_operand:V2SF 0 "register_operand" "=y")
22167         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22168                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22169   "TARGET_3DNOW"
22170   "pfmax\\t{%2, %0|%0, %2}"
22171   [(set_attr "type" "mmxadd")
22172    (set_attr "mode" "V2SF")])
22173
22174 (define_insn "pfminv2sf3"
22175   [(set (match_operand:V2SF 0 "register_operand" "=y")
22176         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22177                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22178   "TARGET_3DNOW"
22179   "pfmin\\t{%2, %0|%0, %2}"
22180   [(set_attr "type" "mmxadd")
22181    (set_attr "mode" "V2SF")])
22182
22183 (define_insn "mulv2sf3"
22184   [(set (match_operand:V2SF 0 "register_operand" "=y")
22185         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22186                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22187   "TARGET_3DNOW"
22188   "pfmul\\t{%2, %0|%0, %2}"
22189   [(set_attr "type" "mmxmul")
22190    (set_attr "mode" "V2SF")])
22191
22192 (define_insn "femms"
22193   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22194    (clobber (reg:XF 8))
22195    (clobber (reg:XF 9))
22196    (clobber (reg:XF 10))
22197    (clobber (reg:XF 11))
22198    (clobber (reg:XF 12))
22199    (clobber (reg:XF 13))
22200    (clobber (reg:XF 14))
22201    (clobber (reg:XF 15))
22202    (clobber (reg:DI 29))
22203    (clobber (reg:DI 30))
22204    (clobber (reg:DI 31))
22205    (clobber (reg:DI 32))
22206    (clobber (reg:DI 33))
22207    (clobber (reg:DI 34))
22208    (clobber (reg:DI 35))
22209    (clobber (reg:DI 36))]
22210   "TARGET_3DNOW"
22211   "femms"
22212   [(set_attr "type" "mmx")
22213    (set_attr "memory" "none")]) 
22214
22215 (define_insn "pf2id"
22216   [(set (match_operand:V2SI 0 "register_operand" "=y")
22217         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22218   "TARGET_3DNOW"
22219   "pf2id\\t{%1, %0|%0, %1}"
22220   [(set_attr "type" "mmxcvt")
22221    (set_attr "mode" "V2SF")])
22222
22223 (define_insn "pf2iw"
22224   [(set (match_operand:V2SI 0 "register_operand" "=y")
22225         (sign_extend:V2SI
22226            (ss_truncate:V2HI
22227               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22228   "TARGET_3DNOW_A"
22229   "pf2iw\\t{%1, %0|%0, %1}"
22230   [(set_attr "type" "mmxcvt")
22231    (set_attr "mode" "V2SF")])
22232
22233 (define_insn "pfacc"
22234   [(set (match_operand:V2SF 0 "register_operand" "=y")
22235         (vec_concat:V2SF
22236            (plus:SF
22237               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22238                              (parallel [(const_int  0)]))
22239               (vec_select:SF (match_dup 1)
22240                              (parallel [(const_int 1)])))
22241            (plus:SF
22242               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22243                              (parallel [(const_int  0)]))
22244               (vec_select:SF (match_dup 2)
22245                              (parallel [(const_int 1)])))))]
22246   "TARGET_3DNOW"
22247   "pfacc\\t{%2, %0|%0, %2}"
22248   [(set_attr "type" "mmxadd")
22249    (set_attr "mode" "V2SF")])
22250
22251 (define_insn "pfnacc"
22252   [(set (match_operand:V2SF 0 "register_operand" "=y")
22253         (vec_concat:V2SF
22254            (minus:SF
22255               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22256                              (parallel [(const_int 0)]))
22257               (vec_select:SF (match_dup 1)
22258                              (parallel [(const_int 1)])))
22259            (minus:SF
22260               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22261                              (parallel [(const_int  0)]))
22262               (vec_select:SF (match_dup 2)
22263                              (parallel [(const_int 1)])))))]
22264   "TARGET_3DNOW_A"
22265   "pfnacc\\t{%2, %0|%0, %2}"
22266   [(set_attr "type" "mmxadd")
22267    (set_attr "mode" "V2SF")])
22268
22269 (define_insn "pfpnacc"
22270   [(set (match_operand:V2SF 0 "register_operand" "=y")
22271         (vec_concat:V2SF
22272            (minus:SF
22273               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22274                              (parallel [(const_int 0)]))
22275               (vec_select:SF (match_dup 1)
22276                              (parallel [(const_int 1)])))
22277            (plus:SF
22278               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22279                              (parallel [(const_int 0)]))
22280               (vec_select:SF (match_dup 2)
22281                              (parallel [(const_int 1)])))))]
22282   "TARGET_3DNOW_A"
22283   "pfpnacc\\t{%2, %0|%0, %2}"
22284   [(set_attr "type" "mmxadd")
22285    (set_attr "mode" "V2SF")])
22286
22287 (define_insn "pi2fw"
22288   [(set (match_operand:V2SF 0 "register_operand" "=y")
22289         (float:V2SF
22290            (vec_concat:V2SI
22291               (sign_extend:SI
22292                  (truncate:HI
22293                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22294                                    (parallel [(const_int 0)]))))
22295               (sign_extend:SI
22296                  (truncate:HI
22297                     (vec_select:SI (match_dup 1)
22298                                    (parallel [(const_int  1)])))))))]
22299   "TARGET_3DNOW_A"
22300   "pi2fw\\t{%1, %0|%0, %1}"
22301   [(set_attr "type" "mmxcvt")
22302    (set_attr "mode" "V2SF")])
22303
22304 (define_insn "floatv2si2"
22305   [(set (match_operand:V2SF 0 "register_operand" "=y")
22306         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22307   "TARGET_3DNOW"
22308   "pi2fd\\t{%1, %0|%0, %1}"
22309   [(set_attr "type" "mmxcvt")
22310    (set_attr "mode" "V2SF")])
22311
22312 ;; This insn is identical to pavgb in operation, but the opcode is
22313 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22314
22315 (define_insn "pavgusb"
22316  [(set (match_operand:V8QI 0 "register_operand" "=y")
22317        (unspec:V8QI
22318           [(match_operand:V8QI 1 "register_operand" "0")
22319            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22320           UNSPEC_PAVGUSB))]
22321   "TARGET_3DNOW"
22322   "pavgusb\\t{%2, %0|%0, %2}"
22323   [(set_attr "type" "mmxshft")
22324    (set_attr "mode" "TI")])
22325
22326 ;; 3DNow reciprocal and sqrt
22327  
22328 (define_insn "pfrcpv2sf2"
22329   [(set (match_operand:V2SF 0 "register_operand" "=y")
22330         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22331         UNSPEC_PFRCP))]
22332   "TARGET_3DNOW"
22333   "pfrcp\\t{%1, %0|%0, %1}"
22334   [(set_attr "type" "mmx")
22335    (set_attr "mode" "TI")])
22336
22337 (define_insn "pfrcpit1v2sf3"
22338   [(set (match_operand:V2SF 0 "register_operand" "=y")
22339         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22340                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22341                      UNSPEC_PFRCPIT1))]
22342   "TARGET_3DNOW"
22343   "pfrcpit1\\t{%2, %0|%0, %2}"
22344   [(set_attr "type" "mmx")
22345    (set_attr "mode" "TI")])
22346
22347 (define_insn "pfrcpit2v2sf3"
22348   [(set (match_operand:V2SF 0 "register_operand" "=y")
22349         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22350                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22351                      UNSPEC_PFRCPIT2))]
22352   "TARGET_3DNOW"
22353   "pfrcpit2\\t{%2, %0|%0, %2}"
22354   [(set_attr "type" "mmx")
22355    (set_attr "mode" "TI")])
22356
22357 (define_insn "pfrsqrtv2sf2"
22358   [(set (match_operand:V2SF 0 "register_operand" "=y")
22359         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22360                      UNSPEC_PFRSQRT))]
22361   "TARGET_3DNOW"
22362   "pfrsqrt\\t{%1, %0|%0, %1}"
22363   [(set_attr "type" "mmx")
22364    (set_attr "mode" "TI")])
22365                 
22366 (define_insn "pfrsqit1v2sf3"
22367   [(set (match_operand:V2SF 0 "register_operand" "=y")
22368         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22369                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22370                      UNSPEC_PFRSQIT1))]
22371   "TARGET_3DNOW"
22372   "pfrsqit1\\t{%2, %0|%0, %2}"
22373   [(set_attr "type" "mmx")
22374    (set_attr "mode" "TI")])
22375
22376 (define_insn "pmulhrwv4hi3"
22377   [(set (match_operand:V4HI 0 "register_operand" "=y")
22378         (truncate:V4HI
22379            (lshiftrt:V4SI
22380               (plus:V4SI
22381                  (mult:V4SI
22382                     (sign_extend:V4SI
22383                        (match_operand:V4HI 1 "register_operand" "0"))
22384                     (sign_extend:V4SI
22385                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22386                  (const_vector:V4SI [(const_int 32768)
22387                                      (const_int 32768)
22388                                      (const_int 32768)
22389                                      (const_int 32768)]))
22390               (const_int 16))))]
22391   "TARGET_3DNOW"
22392   "pmulhrw\\t{%2, %0|%0, %2}"
22393   [(set_attr "type" "mmxmul")
22394    (set_attr "mode" "TI")])
22395
22396 (define_insn "pswapdv2si2"
22397   [(set (match_operand:V2SI 0 "register_operand" "=y")
22398         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22399                          (parallel [(const_int 1) (const_int 0)])))]
22400   "TARGET_3DNOW_A"
22401   "pswapd\\t{%1, %0|%0, %1}"
22402   [(set_attr "type" "mmxcvt")
22403    (set_attr "mode" "TI")])
22404
22405 (define_insn "pswapdv2sf2"
22406   [(set (match_operand:V2SF 0 "register_operand" "=y")
22407         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22408                          (parallel [(const_int 1) (const_int 0)])))]
22409   "TARGET_3DNOW_A"
22410   "pswapd\\t{%1, %0|%0, %1}"
22411   [(set_attr "type" "mmxcvt")
22412    (set_attr "mode" "TI")])
22413
22414 (define_expand "prefetch"
22415   [(prefetch (match_operand 0 "address_operand" "")
22416              (match_operand:SI 1 "const_int_operand" "")
22417              (match_operand:SI 2 "const_int_operand" ""))]
22418   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22419 {
22420   int rw = INTVAL (operands[1]);
22421   int locality = INTVAL (operands[2]);
22422
22423   if (rw != 0 && rw != 1)
22424     abort ();
22425   if (locality < 0 || locality > 3)
22426     abort ();
22427   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22428     abort ();
22429
22430   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22431      suported by SSE counterpart or the SSE prefetch is not available
22432      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22433      of locality.  */
22434   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22435     operands[2] = GEN_INT (3);
22436   else
22437     operands[1] = const0_rtx;
22438 })
22439
22440 (define_insn "*prefetch_sse"
22441   [(prefetch (match_operand:SI 0 "address_operand" "p")
22442              (const_int 0)
22443              (match_operand:SI 1 "const_int_operand" ""))]
22444   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22445 {
22446   static const char * const patterns[4] = {
22447    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22448   };
22449
22450   int locality = INTVAL (operands[1]);
22451   if (locality < 0 || locality > 3)
22452     abort ();
22453
22454   return patterns[locality];  
22455 }
22456   [(set_attr "type" "sse")
22457    (set_attr "memory" "none")])
22458
22459 (define_insn "*prefetch_sse_rex"
22460   [(prefetch (match_operand:DI 0 "address_operand" "p")
22461              (const_int 0)
22462              (match_operand:SI 1 "const_int_operand" ""))]
22463   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22464 {
22465   static const char * const patterns[4] = {
22466    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22467   };
22468
22469   int locality = INTVAL (operands[1]);
22470   if (locality < 0 || locality > 3)
22471     abort ();
22472
22473   return patterns[locality];  
22474 }
22475   [(set_attr "type" "sse")
22476    (set_attr "memory" "none")])
22477
22478 (define_insn "*prefetch_3dnow"
22479   [(prefetch (match_operand:SI 0 "address_operand" "p")
22480              (match_operand:SI 1 "const_int_operand" "n")
22481              (const_int 3))]
22482   "TARGET_3DNOW && !TARGET_64BIT"
22483 {
22484   if (INTVAL (operands[1]) == 0)
22485     return "prefetch\t%a0";
22486   else
22487     return "prefetchw\t%a0";
22488 }
22489   [(set_attr "type" "mmx")
22490    (set_attr "memory" "none")])
22491
22492 (define_insn "*prefetch_3dnow_rex"
22493   [(prefetch (match_operand:DI 0 "address_operand" "p")
22494              (match_operand:SI 1 "const_int_operand" "n")
22495              (const_int 3))]
22496   "TARGET_3DNOW && TARGET_64BIT"
22497 {
22498   if (INTVAL (operands[1]) == 0)
22499     return "prefetch\t%a0";
22500   else
22501     return "prefetchw\t%a0";
22502 }
22503   [(set_attr "type" "mmx")
22504    (set_attr "memory" "none")])
22505
22506 ;; SSE2 support
22507
22508 (define_insn "addv2df3"
22509   [(set (match_operand:V2DF 0 "register_operand" "=x")
22510         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22511                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22512   "TARGET_SSE2"
22513   "addpd\t{%2, %0|%0, %2}"
22514   [(set_attr "type" "sseadd")
22515    (set_attr "mode" "V2DF")])
22516
22517 (define_insn "vmaddv2df3"
22518   [(set (match_operand:V2DF 0 "register_operand" "=x")
22519         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22520                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22521                         (match_dup 1)
22522                         (const_int 1)))]
22523   "TARGET_SSE2"
22524   "addsd\t{%2, %0|%0, %2}"
22525   [(set_attr "type" "sseadd")
22526    (set_attr "mode" "DF")])
22527
22528 (define_insn "subv2df3"
22529   [(set (match_operand:V2DF 0 "register_operand" "=x")
22530         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22531                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22532   "TARGET_SSE2"
22533   "subpd\t{%2, %0|%0, %2}"
22534   [(set_attr "type" "sseadd")
22535    (set_attr "mode" "V2DF")])
22536
22537 (define_insn "vmsubv2df3"
22538   [(set (match_operand:V2DF 0 "register_operand" "=x")
22539         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22540                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22541                         (match_dup 1)
22542                         (const_int 1)))]
22543   "TARGET_SSE2"
22544   "subsd\t{%2, %0|%0, %2}"
22545   [(set_attr "type" "sseadd")
22546    (set_attr "mode" "DF")])
22547
22548 (define_insn "mulv2df3"
22549   [(set (match_operand:V2DF 0 "register_operand" "=x")
22550         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22551                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22552   "TARGET_SSE2"
22553   "mulpd\t{%2, %0|%0, %2}"
22554   [(set_attr "type" "ssemul")
22555    (set_attr "mode" "V2DF")])
22556
22557 (define_insn "vmmulv2df3"
22558   [(set (match_operand:V2DF 0 "register_operand" "=x")
22559         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22560                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22561                         (match_dup 1)
22562                         (const_int 1)))]
22563   "TARGET_SSE2"
22564   "mulsd\t{%2, %0|%0, %2}"
22565   [(set_attr "type" "ssemul")
22566    (set_attr "mode" "DF")])
22567
22568 (define_insn "divv2df3"
22569   [(set (match_operand:V2DF 0 "register_operand" "=x")
22570         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22571                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22572   "TARGET_SSE2"
22573   "divpd\t{%2, %0|%0, %2}"
22574   [(set_attr "type" "ssediv")
22575    (set_attr "mode" "V2DF")])
22576
22577 (define_insn "vmdivv2df3"
22578   [(set (match_operand:V2DF 0 "register_operand" "=x")
22579         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22580                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22581                         (match_dup 1)
22582                         (const_int 1)))]
22583   "TARGET_SSE2"
22584   "divsd\t{%2, %0|%0, %2}"
22585   [(set_attr "type" "ssediv")
22586    (set_attr "mode" "DF")])
22587
22588 ;; SSE min/max
22589
22590 (define_insn "smaxv2df3"
22591   [(set (match_operand:V2DF 0 "register_operand" "=x")
22592         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22593                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22594   "TARGET_SSE2"
22595   "maxpd\t{%2, %0|%0, %2}"
22596   [(set_attr "type" "sseadd")
22597    (set_attr "mode" "V2DF")])
22598
22599 (define_insn "vmsmaxv2df3"
22600   [(set (match_operand:V2DF 0 "register_operand" "=x")
22601         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22602                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22603                         (match_dup 1)
22604                         (const_int 1)))]
22605   "TARGET_SSE2"
22606   "maxsd\t{%2, %0|%0, %2}"
22607   [(set_attr "type" "sseadd")
22608    (set_attr "mode" "DF")])
22609
22610 (define_insn "sminv2df3"
22611   [(set (match_operand:V2DF 0 "register_operand" "=x")
22612         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22613                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22614   "TARGET_SSE2"
22615   "minpd\t{%2, %0|%0, %2}"
22616   [(set_attr "type" "sseadd")
22617    (set_attr "mode" "V2DF")])
22618
22619 (define_insn "vmsminv2df3"
22620   [(set (match_operand:V2DF 0 "register_operand" "=x")
22621         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22622                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22623                         (match_dup 1)
22624                         (const_int 1)))]
22625   "TARGET_SSE2"
22626   "minsd\t{%2, %0|%0, %2}"
22627   [(set_attr "type" "sseadd")
22628    (set_attr "mode" "DF")])
22629 ;; SSE2 square root.  There doesn't appear to be an extension for the
22630 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22631
22632 (define_insn "sqrtv2df2"
22633   [(set (match_operand:V2DF 0 "register_operand" "=x")
22634         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22635   "TARGET_SSE2"
22636   "sqrtpd\t{%1, %0|%0, %1}"
22637   [(set_attr "type" "sse")
22638    (set_attr "mode" "V2DF")])
22639
22640 (define_insn "vmsqrtv2df2"
22641   [(set (match_operand:V2DF 0 "register_operand" "=x")
22642         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22643                         (match_operand:V2DF 2 "register_operand" "0")
22644                         (const_int 1)))]
22645   "TARGET_SSE2"
22646   "sqrtsd\t{%1, %0|%0, %1}"
22647   [(set_attr "type" "sse")
22648    (set_attr "mode" "SF")])
22649
22650 ;; SSE mask-generating compares
22651
22652 (define_insn "maskcmpv2df3"
22653   [(set (match_operand:V2DI 0 "register_operand" "=x")
22654         (match_operator:V2DI 3 "sse_comparison_operator"
22655                              [(match_operand:V2DF 1 "register_operand" "0")
22656                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22657   "TARGET_SSE2"
22658   "cmp%D3pd\t{%2, %0|%0, %2}"
22659   [(set_attr "type" "ssecmp")
22660    (set_attr "mode" "V2DF")])
22661
22662 (define_insn "maskncmpv2df3"
22663   [(set (match_operand:V2DI 0 "register_operand" "=x")
22664         (not:V2DI
22665          (match_operator:V2DI 3 "sse_comparison_operator"
22666                               [(match_operand:V2DF 1 "register_operand" "0")
22667                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22668   "TARGET_SSE2"
22669 {
22670   if (GET_CODE (operands[3]) == UNORDERED)
22671     return "cmpordps\t{%2, %0|%0, %2}";
22672   else
22673     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22674 }
22675   [(set_attr "type" "ssecmp")
22676    (set_attr "mode" "V2DF")])
22677
22678 (define_insn "vmmaskcmpv2df3"
22679   [(set (match_operand:V2DI 0 "register_operand" "=x")
22680         (vec_merge:V2DI
22681          (match_operator:V2DI 3 "sse_comparison_operator"
22682                               [(match_operand:V2DF 1 "register_operand" "0")
22683                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22684          (subreg:V2DI (match_dup 1) 0)
22685          (const_int 1)))]
22686   "TARGET_SSE2"
22687   "cmp%D3sd\t{%2, %0|%0, %2}"
22688   [(set_attr "type" "ssecmp")
22689    (set_attr "mode" "DF")])
22690
22691 (define_insn "vmmaskncmpv2df3"
22692   [(set (match_operand:V2DI 0 "register_operand" "=x")
22693         (vec_merge:V2DI
22694          (not:V2DI
22695           (match_operator:V2DI 3 "sse_comparison_operator"
22696                                [(match_operand:V2DF 1 "register_operand" "0")
22697                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22698          (subreg:V2DI (match_dup 1) 0)
22699          (const_int 1)))]
22700   "TARGET_SSE2"
22701 {
22702   if (GET_CODE (operands[3]) == UNORDERED)
22703     return "cmpordsd\t{%2, %0|%0, %2}";
22704   else
22705     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22706 }
22707   [(set_attr "type" "ssecmp")
22708    (set_attr "mode" "DF")])
22709
22710 (define_insn "sse2_comi"
22711   [(set (reg:CCFP FLAGS_REG)
22712         (compare:CCFP (vec_select:DF
22713                        (match_operand:V2DF 0 "register_operand" "x")
22714                        (parallel [(const_int 0)]))
22715                       (vec_select:DF
22716                        (match_operand:V2DF 1 "register_operand" "x")
22717                        (parallel [(const_int 0)]))))]
22718   "TARGET_SSE2"
22719   "comisd\t{%1, %0|%0, %1}"
22720   [(set_attr "type" "ssecomi")
22721    (set_attr "mode" "DF")])
22722
22723 (define_insn "sse2_ucomi"
22724   [(set (reg:CCFPU FLAGS_REG)
22725         (compare:CCFPU (vec_select:DF
22726                          (match_operand:V2DF 0 "register_operand" "x")
22727                          (parallel [(const_int 0)]))
22728                         (vec_select:DF
22729                          (match_operand:V2DF 1 "register_operand" "x")
22730                          (parallel [(const_int 0)]))))]
22731   "TARGET_SSE2"
22732   "ucomisd\t{%1, %0|%0, %1}"
22733   [(set_attr "type" "ssecomi")
22734    (set_attr "mode" "DF")])
22735
22736 ;; SSE Strange Moves.
22737
22738 (define_insn "sse2_movmskpd"
22739   [(set (match_operand:SI 0 "register_operand" "=r")
22740         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22741                    UNSPEC_MOVMSK))]
22742   "TARGET_SSE2"
22743   "movmskpd\t{%1, %0|%0, %1}"
22744   [(set_attr "type" "ssecvt")
22745    (set_attr "mode" "V2DF")])
22746
22747 (define_insn "sse2_pmovmskb"
22748   [(set (match_operand:SI 0 "register_operand" "=r")
22749         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22750                    UNSPEC_MOVMSK))]
22751   "TARGET_SSE2"
22752   "pmovmskb\t{%1, %0|%0, %1}"
22753   [(set_attr "type" "ssecvt")
22754    (set_attr "mode" "V2DF")])
22755
22756 (define_insn "sse2_maskmovdqu"
22757   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22758         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22759                        (match_operand:V16QI 2 "register_operand" "x")]
22760                       UNSPEC_MASKMOV))]
22761   "TARGET_SSE2"
22762   ;; @@@ check ordering of operands in intel/nonintel syntax
22763   "maskmovdqu\t{%2, %1|%1, %2}"
22764   [(set_attr "type" "ssecvt")
22765    (set_attr "mode" "TI")])
22766
22767 (define_insn "sse2_maskmovdqu_rex64"
22768   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22769         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22770                        (match_operand:V16QI 2 "register_operand" "x")]
22771                       UNSPEC_MASKMOV))]
22772   "TARGET_SSE2"
22773   ;; @@@ check ordering of operands in intel/nonintel syntax
22774   "maskmovdqu\t{%2, %1|%1, %2}"
22775   [(set_attr "type" "ssecvt")
22776    (set_attr "mode" "TI")])
22777
22778 (define_insn "sse2_movntv2df"
22779   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22780         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22781                      UNSPEC_MOVNT))]
22782   "TARGET_SSE2"
22783   "movntpd\t{%1, %0|%0, %1}"
22784   [(set_attr "type" "ssecvt")
22785    (set_attr "mode" "V2DF")])
22786
22787 (define_insn "sse2_movntv2di"
22788   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22789         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22790                      UNSPEC_MOVNT))]
22791   "TARGET_SSE2"
22792   "movntdq\t{%1, %0|%0, %1}"
22793   [(set_attr "type" "ssecvt")
22794    (set_attr "mode" "TI")])
22795
22796 (define_insn "sse2_movntsi"
22797   [(set (match_operand:SI 0 "memory_operand" "=m")
22798         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22799                    UNSPEC_MOVNT))]
22800   "TARGET_SSE2"
22801   "movnti\t{%1, %0|%0, %1}"
22802   [(set_attr "type" "ssecvt")
22803    (set_attr "mode" "V2DF")])
22804
22805 ;; SSE <-> integer/MMX conversions
22806
22807 ;; Conversions between SI and SF
22808
22809 (define_insn "cvtdq2ps"
22810   [(set (match_operand:V4SF 0 "register_operand" "=x")
22811         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22812   "TARGET_SSE2"
22813   "cvtdq2ps\t{%1, %0|%0, %1}"
22814   [(set_attr "type" "ssecvt")
22815    (set_attr "mode" "V2DF")])
22816
22817 (define_insn "cvtps2dq"
22818   [(set (match_operand:V4SI 0 "register_operand" "=x")
22819         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22820   "TARGET_SSE2"
22821   "cvtps2dq\t{%1, %0|%0, %1}"
22822   [(set_attr "type" "ssecvt")
22823    (set_attr "mode" "TI")])
22824
22825 (define_insn "cvttps2dq"
22826   [(set (match_operand:V4SI 0 "register_operand" "=x")
22827         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22828                      UNSPEC_FIX))]
22829   "TARGET_SSE2"
22830   "cvttps2dq\t{%1, %0|%0, %1}"
22831   [(set_attr "type" "ssecvt")
22832    (set_attr "mode" "TI")])
22833
22834 ;; Conversions between SI and DF
22835
22836 (define_insn "cvtdq2pd"
22837   [(set (match_operand:V2DF 0 "register_operand" "=x")
22838         (float:V2DF (vec_select:V2SI
22839                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22840                      (parallel
22841                       [(const_int 0)
22842                        (const_int 1)]))))]
22843   "TARGET_SSE2"
22844   "cvtdq2pd\t{%1, %0|%0, %1}"
22845   [(set_attr "type" "ssecvt")
22846    (set_attr "mode" "V2DF")])
22847
22848 (define_insn "cvtpd2dq"
22849   [(set (match_operand:V4SI 0 "register_operand" "=x")
22850         (vec_concat:V4SI
22851          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22852          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22853   "TARGET_SSE2"
22854   "cvtpd2dq\t{%1, %0|%0, %1}"
22855   [(set_attr "type" "ssecvt")
22856    (set_attr "mode" "TI")])
22857
22858 (define_insn "cvttpd2dq"
22859   [(set (match_operand:V4SI 0 "register_operand" "=x")
22860         (vec_concat:V4SI
22861          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22862                       UNSPEC_FIX)
22863          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22864   "TARGET_SSE2"
22865   "cvttpd2dq\t{%1, %0|%0, %1}"
22866   [(set_attr "type" "ssecvt")
22867    (set_attr "mode" "TI")])
22868
22869 (define_insn "cvtpd2pi"
22870   [(set (match_operand:V2SI 0 "register_operand" "=y")
22871         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22872   "TARGET_SSE2"
22873   "cvtpd2pi\t{%1, %0|%0, %1}"
22874   [(set_attr "type" "ssecvt")
22875    (set_attr "mode" "TI")])
22876
22877 (define_insn "cvttpd2pi"
22878   [(set (match_operand:V2SI 0 "register_operand" "=y")
22879         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22880                      UNSPEC_FIX))]
22881   "TARGET_SSE2"
22882   "cvttpd2pi\t{%1, %0|%0, %1}"
22883   [(set_attr "type" "ssecvt")
22884    (set_attr "mode" "TI")])
22885
22886 (define_insn "cvtpi2pd"
22887   [(set (match_operand:V2DF 0 "register_operand" "=x")
22888         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22889   "TARGET_SSE2"
22890   "cvtpi2pd\t{%1, %0|%0, %1}"
22891   [(set_attr "type" "ssecvt")
22892    (set_attr "mode" "TI")])
22893
22894 ;; Conversions between SI and DF
22895
22896 (define_insn "cvtsd2si"
22897   [(set (match_operand:SI 0 "register_operand" "=r,r")
22898         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22899                                (parallel [(const_int 0)]))))]
22900   "TARGET_SSE2"
22901   "cvtsd2si\t{%1, %0|%0, %1}"
22902   [(set_attr "type" "sseicvt")
22903    (set_attr "athlon_decode" "double,vector")
22904    (set_attr "mode" "SI")])
22905
22906 (define_insn "cvtsd2siq"
22907   [(set (match_operand:DI 0 "register_operand" "=r,r")
22908         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22909                                (parallel [(const_int 0)]))))]
22910   "TARGET_SSE2 && TARGET_64BIT"
22911   "cvtsd2siq\t{%1, %0|%0, %1}"
22912   [(set_attr "type" "sseicvt")
22913    (set_attr "athlon_decode" "double,vector")
22914    (set_attr "mode" "DI")])
22915
22916 (define_insn "cvttsd2si"
22917   [(set (match_operand:SI 0 "register_operand" "=r,r")
22918         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22919                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22920   "TARGET_SSE2"
22921   "cvttsd2si\t{%1, %0|%0, %1}"
22922   [(set_attr "type" "sseicvt")
22923    (set_attr "mode" "SI")
22924    (set_attr "athlon_decode" "double,vector")])
22925
22926 (define_insn "cvttsd2siq"
22927   [(set (match_operand:DI 0 "register_operand" "=r,r")
22928         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22929                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22930   "TARGET_SSE2 && TARGET_64BIT"
22931   "cvttsd2siq\t{%1, %0|%0, %1}"
22932   [(set_attr "type" "sseicvt")
22933    (set_attr "mode" "DI")
22934    (set_attr "athlon_decode" "double,vector")])
22935
22936 (define_insn "cvtsi2sd"
22937   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22938         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22939                         (vec_duplicate:V2DF
22940                           (float:DF
22941                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22942                         (const_int 2)))]
22943   "TARGET_SSE2"
22944   "cvtsi2sd\t{%2, %0|%0, %2}"
22945   [(set_attr "type" "sseicvt")
22946    (set_attr "mode" "DF")
22947    (set_attr "athlon_decode" "double,direct")])
22948
22949 (define_insn "cvtsi2sdq"
22950   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22951         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22952                         (vec_duplicate:V2DF
22953                           (float:DF
22954                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22955                         (const_int 2)))]
22956   "TARGET_SSE2 && TARGET_64BIT"
22957   "cvtsi2sdq\t{%2, %0|%0, %2}"
22958   [(set_attr "type" "sseicvt")
22959    (set_attr "mode" "DF")
22960    (set_attr "athlon_decode" "double,direct")])
22961
22962 ;; Conversions between SF and DF
22963
22964 (define_insn "cvtsd2ss"
22965   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22966         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22967                         (vec_duplicate:V4SF
22968                           (float_truncate:V2SF
22969                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22970                         (const_int 14)))]
22971   "TARGET_SSE2"
22972   "cvtsd2ss\t{%2, %0|%0, %2}"
22973   [(set_attr "type" "ssecvt")
22974    (set_attr "athlon_decode" "vector,double")
22975    (set_attr "mode" "SF")])
22976
22977 (define_insn "cvtss2sd"
22978   [(set (match_operand:V2DF 0 "register_operand" "=x")
22979         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22980                         (float_extend:V2DF
22981                           (vec_select:V2SF
22982                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22983                             (parallel [(const_int 0)
22984                                        (const_int 1)])))
22985                         (const_int 2)))]
22986   "TARGET_SSE2"
22987   "cvtss2sd\t{%2, %0|%0, %2}"
22988   [(set_attr "type" "ssecvt")
22989    (set_attr "mode" "DF")])
22990
22991 (define_insn "cvtpd2ps"
22992   [(set (match_operand:V4SF 0 "register_operand" "=x")
22993         (subreg:V4SF
22994           (vec_concat:V4SI
22995             (subreg:V2SI (float_truncate:V2SF
22996                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22997             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22998   "TARGET_SSE2"
22999   "cvtpd2ps\t{%1, %0|%0, %1}"
23000   [(set_attr "type" "ssecvt")
23001    (set_attr "mode" "V4SF")])
23002
23003 (define_insn "cvtps2pd"
23004   [(set (match_operand:V2DF 0 "register_operand" "=x")
23005         (float_extend:V2DF
23006           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23007                            (parallel [(const_int 0)
23008                                       (const_int 1)]))))]
23009   "TARGET_SSE2"
23010   "cvtps2pd\t{%1, %0|%0, %1}"
23011   [(set_attr "type" "ssecvt")
23012    (set_attr "mode" "V2DF")])
23013
23014 ;; SSE2 variants of MMX insns
23015
23016 ;; MMX arithmetic
23017
23018 (define_insn "addv16qi3"
23019   [(set (match_operand:V16QI 0 "register_operand" "=x")
23020         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23021                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23022   "TARGET_SSE2"
23023   "paddb\t{%2, %0|%0, %2}"
23024   [(set_attr "type" "sseiadd")
23025    (set_attr "mode" "TI")])
23026
23027 (define_insn "addv8hi3"
23028   [(set (match_operand:V8HI 0 "register_operand" "=x")
23029         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23030                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23031   "TARGET_SSE2"
23032   "paddw\t{%2, %0|%0, %2}"
23033   [(set_attr "type" "sseiadd")
23034    (set_attr "mode" "TI")])
23035
23036 (define_insn "addv4si3"
23037   [(set (match_operand:V4SI 0 "register_operand" "=x")
23038         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23039                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23040   "TARGET_SSE2"
23041   "paddd\t{%2, %0|%0, %2}"
23042   [(set_attr "type" "sseiadd")
23043    (set_attr "mode" "TI")])
23044
23045 (define_insn "addv2di3"
23046   [(set (match_operand:V2DI 0 "register_operand" "=x")
23047         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23048                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23049   "TARGET_SSE2"
23050   "paddq\t{%2, %0|%0, %2}"
23051   [(set_attr "type" "sseiadd")
23052    (set_attr "mode" "TI")])
23053
23054 (define_insn "ssaddv16qi3"
23055   [(set (match_operand:V16QI 0 "register_operand" "=x")
23056         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23057                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23058   "TARGET_SSE2"
23059   "paddsb\t{%2, %0|%0, %2}"
23060   [(set_attr "type" "sseiadd")
23061    (set_attr "mode" "TI")])
23062
23063 (define_insn "ssaddv8hi3"
23064   [(set (match_operand:V8HI 0 "register_operand" "=x")
23065         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23066                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23067   "TARGET_SSE2"
23068   "paddsw\t{%2, %0|%0, %2}"
23069   [(set_attr "type" "sseiadd")
23070    (set_attr "mode" "TI")])
23071
23072 (define_insn "usaddv16qi3"
23073   [(set (match_operand:V16QI 0 "register_operand" "=x")
23074         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23075                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23076   "TARGET_SSE2"
23077   "paddusb\t{%2, %0|%0, %2}"
23078   [(set_attr "type" "sseiadd")
23079    (set_attr "mode" "TI")])
23080
23081 (define_insn "usaddv8hi3"
23082   [(set (match_operand:V8HI 0 "register_operand" "=x")
23083         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23084                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23085   "TARGET_SSE2"
23086   "paddusw\t{%2, %0|%0, %2}"
23087   [(set_attr "type" "sseiadd")
23088    (set_attr "mode" "TI")])
23089
23090 (define_insn "subv16qi3"
23091   [(set (match_operand:V16QI 0 "register_operand" "=x")
23092         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23093                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23094   "TARGET_SSE2"
23095   "psubb\t{%2, %0|%0, %2}"
23096   [(set_attr "type" "sseiadd")
23097    (set_attr "mode" "TI")])
23098
23099 (define_insn "subv8hi3"
23100   [(set (match_operand:V8HI 0 "register_operand" "=x")
23101         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23102                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23103   "TARGET_SSE2"
23104   "psubw\t{%2, %0|%0, %2}"
23105   [(set_attr "type" "sseiadd")
23106    (set_attr "mode" "TI")])
23107
23108 (define_insn "subv4si3"
23109   [(set (match_operand:V4SI 0 "register_operand" "=x")
23110         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23111                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23112   "TARGET_SSE2"
23113   "psubd\t{%2, %0|%0, %2}"
23114   [(set_attr "type" "sseiadd")
23115    (set_attr "mode" "TI")])
23116
23117 (define_insn "subv2di3"
23118   [(set (match_operand:V2DI 0 "register_operand" "=x")
23119         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23120                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23121   "TARGET_SSE2"
23122   "psubq\t{%2, %0|%0, %2}"
23123   [(set_attr "type" "sseiadd")
23124    (set_attr "mode" "TI")])
23125
23126 (define_insn "sssubv16qi3"
23127   [(set (match_operand:V16QI 0 "register_operand" "=x")
23128         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23129                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23130   "TARGET_SSE2"
23131   "psubsb\t{%2, %0|%0, %2}"
23132   [(set_attr "type" "sseiadd")
23133    (set_attr "mode" "TI")])
23134
23135 (define_insn "sssubv8hi3"
23136   [(set (match_operand:V8HI 0 "register_operand" "=x")
23137         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23138                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23139   "TARGET_SSE2"
23140   "psubsw\t{%2, %0|%0, %2}"
23141   [(set_attr "type" "sseiadd")
23142    (set_attr "mode" "TI")])
23143
23144 (define_insn "ussubv16qi3"
23145   [(set (match_operand:V16QI 0 "register_operand" "=x")
23146         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23147                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23148   "TARGET_SSE2"
23149   "psubusb\t{%2, %0|%0, %2}"
23150   [(set_attr "type" "sseiadd")
23151    (set_attr "mode" "TI")])
23152
23153 (define_insn "ussubv8hi3"
23154   [(set (match_operand:V8HI 0 "register_operand" "=x")
23155         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23156                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23157   "TARGET_SSE2"
23158   "psubusw\t{%2, %0|%0, %2}"
23159   [(set_attr "type" "sseiadd")
23160    (set_attr "mode" "TI")])
23161
23162 (define_insn "mulv8hi3"
23163   [(set (match_operand:V8HI 0 "register_operand" "=x")
23164         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23165                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23166   "TARGET_SSE2"
23167   "pmullw\t{%2, %0|%0, %2}"
23168   [(set_attr "type" "sseimul")
23169    (set_attr "mode" "TI")])
23170
23171 (define_insn "smulv8hi3_highpart"
23172   [(set (match_operand:V8HI 0 "register_operand" "=x")
23173         (truncate:V8HI
23174          (lshiftrt:V8SI
23175           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23176                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23177           (const_int 16))))]
23178   "TARGET_SSE2"
23179   "pmulhw\t{%2, %0|%0, %2}"
23180   [(set_attr "type" "sseimul")
23181    (set_attr "mode" "TI")])
23182
23183 (define_insn "umulv8hi3_highpart"
23184   [(set (match_operand:V8HI 0 "register_operand" "=x")
23185         (truncate:V8HI
23186          (lshiftrt:V8SI
23187           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23188                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23189           (const_int 16))))]
23190   "TARGET_SSE2"
23191   "pmulhuw\t{%2, %0|%0, %2}"
23192   [(set_attr "type" "sseimul")
23193    (set_attr "mode" "TI")])
23194
23195 (define_insn "sse2_umulsidi3"
23196   [(set (match_operand:DI 0 "register_operand" "=y")
23197         (mult:DI (zero_extend:DI (vec_select:SI
23198                                   (match_operand:V2SI 1 "register_operand" "0")
23199                                   (parallel [(const_int 0)])))
23200                  (zero_extend:DI (vec_select:SI
23201                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23202                                   (parallel [(const_int 0)])))))]
23203   "TARGET_SSE2"
23204   "pmuludq\t{%2, %0|%0, %2}"
23205   [(set_attr "type" "mmxmul")
23206    (set_attr "mode" "DI")])
23207
23208 (define_insn "sse2_umulv2siv2di3"
23209   [(set (match_operand:V2DI 0 "register_operand" "=x")
23210         (mult:V2DI (zero_extend:V2DI
23211                      (vec_select:V2SI
23212                        (match_operand:V4SI 1 "register_operand" "0")
23213                        (parallel [(const_int 0) (const_int 2)])))
23214                    (zero_extend:V2DI
23215                      (vec_select:V2SI
23216                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23217                        (parallel [(const_int 0) (const_int 2)])))))]
23218   "TARGET_SSE2"
23219   "pmuludq\t{%2, %0|%0, %2}"
23220   [(set_attr "type" "sseimul")
23221    (set_attr "mode" "TI")])
23222
23223 (define_insn "sse2_pmaddwd"
23224   [(set (match_operand:V4SI 0 "register_operand" "=x")
23225         (plus:V4SI
23226          (mult:V4SI
23227           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23228                                              (parallel [(const_int 0)
23229                                                         (const_int 2)
23230                                                         (const_int 4)
23231                                                         (const_int 6)])))
23232           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23233                                              (parallel [(const_int 0)
23234                                                         (const_int 2)
23235                                                         (const_int 4)
23236                                                         (const_int 6)]))))
23237          (mult:V4SI
23238           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23239                                              (parallel [(const_int 1)
23240                                                         (const_int 3)
23241                                                         (const_int 5)
23242                                                         (const_int 7)])))
23243           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23244                                              (parallel [(const_int 1)
23245                                                         (const_int 3)
23246                                                         (const_int 5)
23247                                                         (const_int 7)]))))))]
23248   "TARGET_SSE2"
23249   "pmaddwd\t{%2, %0|%0, %2}"
23250   [(set_attr "type" "sseiadd")
23251    (set_attr "mode" "TI")])
23252
23253 ;; Same as pxor, but don't show input operands so that we don't think
23254 ;; they are live.
23255 (define_insn "sse2_clrti"
23256   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23257   "TARGET_SSE2"
23258 {
23259   if (get_attr_mode (insn) == MODE_TI)
23260     return "pxor\t%0, %0";
23261   else
23262     return "xorps\t%0, %0";
23263 }
23264   [(set_attr "type" "ssemov")
23265    (set_attr "memory" "none")
23266    (set (attr "mode")
23267               (if_then_else
23268                 (ne (symbol_ref "optimize_size")
23269                     (const_int 0))
23270                 (const_string "V4SF")
23271                 (const_string "TI")))])
23272
23273 ;; MMX unsigned averages/sum of absolute differences
23274
23275 (define_insn "sse2_uavgv16qi3"
23276   [(set (match_operand:V16QI 0 "register_operand" "=x")
23277         (ashiftrt:V16QI
23278          (plus:V16QI (plus:V16QI
23279                      (match_operand:V16QI 1 "register_operand" "0")
23280                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23281                      (const_vector:V16QI [(const_int 1) (const_int 1)
23282                                           (const_int 1) (const_int 1)
23283                                           (const_int 1) (const_int 1)
23284                                           (const_int 1) (const_int 1)
23285                                           (const_int 1) (const_int 1)
23286                                           (const_int 1) (const_int 1)
23287                                           (const_int 1) (const_int 1)
23288                                           (const_int 1) (const_int 1)]))
23289          (const_int 1)))]
23290   "TARGET_SSE2"
23291   "pavgb\t{%2, %0|%0, %2}"
23292   [(set_attr "type" "sseiadd")
23293    (set_attr "mode" "TI")])
23294
23295 (define_insn "sse2_uavgv8hi3"
23296   [(set (match_operand:V8HI 0 "register_operand" "=x")
23297         (ashiftrt:V8HI
23298          (plus:V8HI (plus:V8HI
23299                      (match_operand:V8HI 1 "register_operand" "0")
23300                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23301                     (const_vector:V8HI [(const_int 1) (const_int 1)
23302                                         (const_int 1) (const_int 1)
23303                                         (const_int 1) (const_int 1)
23304                                         (const_int 1) (const_int 1)]))
23305          (const_int 1)))]
23306   "TARGET_SSE2"
23307   "pavgw\t{%2, %0|%0, %2}"
23308   [(set_attr "type" "sseiadd")
23309    (set_attr "mode" "TI")])
23310
23311 ;; @@@ this isn't the right representation.
23312 (define_insn "sse2_psadbw"
23313   [(set (match_operand:V2DI 0 "register_operand" "=x")
23314         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23315                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23316                      UNSPEC_PSADBW))]
23317   "TARGET_SSE2"
23318   "psadbw\t{%2, %0|%0, %2}"
23319   [(set_attr "type" "sseiadd")
23320    (set_attr "mode" "TI")])
23321
23322
23323 ;; MMX insert/extract/shuffle
23324
23325 (define_insn "sse2_pinsrw"
23326   [(set (match_operand:V8HI 0 "register_operand" "=x")
23327         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23328                         (vec_duplicate:V8HI
23329                          (truncate:HI
23330                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23331                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23332   "TARGET_SSE2"
23333   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23334   [(set_attr "type" "ssecvt")
23335    (set_attr "mode" "TI")])
23336
23337 (define_insn "sse2_pextrw"
23338   [(set (match_operand:SI 0 "register_operand" "=r")
23339         (zero_extend:SI
23340           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23341                          (parallel
23342                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23343   "TARGET_SSE2"
23344   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23345   [(set_attr "type" "ssecvt")
23346    (set_attr "mode" "TI")])
23347
23348 (define_insn "sse2_pshufd"
23349   [(set (match_operand:V4SI 0 "register_operand" "=x")
23350         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23351                       (match_operand:SI 2 "immediate_operand" "i")]
23352                      UNSPEC_SHUFFLE))]
23353   "TARGET_SSE2"
23354   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23355   [(set_attr "type" "ssecvt")
23356    (set_attr "mode" "TI")])
23357
23358 (define_insn "sse2_pshuflw"
23359   [(set (match_operand:V8HI 0 "register_operand" "=x")
23360         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23361                       (match_operand:SI 2 "immediate_operand" "i")]
23362                      UNSPEC_PSHUFLW))]
23363   "TARGET_SSE2"
23364   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23365   [(set_attr "type" "ssecvt")
23366    (set_attr "mode" "TI")])
23367
23368 (define_insn "sse2_pshufhw"
23369   [(set (match_operand:V8HI 0 "register_operand" "=x")
23370         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23371                       (match_operand:SI 2 "immediate_operand" "i")]
23372                      UNSPEC_PSHUFHW))]
23373   "TARGET_SSE2"
23374   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23375   [(set_attr "type" "ssecvt")
23376    (set_attr "mode" "TI")])
23377
23378 ;; MMX mask-generating comparisons
23379
23380 (define_insn "eqv16qi3"
23381   [(set (match_operand:V16QI 0 "register_operand" "=x")
23382         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23383                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23384   "TARGET_SSE2"
23385   "pcmpeqb\t{%2, %0|%0, %2}"
23386   [(set_attr "type" "ssecmp")
23387    (set_attr "mode" "TI")])
23388
23389 (define_insn "eqv8hi3"
23390   [(set (match_operand:V8HI 0 "register_operand" "=x")
23391         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23392                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23393   "TARGET_SSE2"
23394   "pcmpeqw\t{%2, %0|%0, %2}"
23395   [(set_attr "type" "ssecmp")
23396    (set_attr "mode" "TI")])
23397
23398 (define_insn "eqv4si3"
23399   [(set (match_operand:V4SI 0 "register_operand" "=x")
23400         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23401                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23402   "TARGET_SSE2"
23403   "pcmpeqd\t{%2, %0|%0, %2}"
23404   [(set_attr "type" "ssecmp")
23405    (set_attr "mode" "TI")])
23406
23407 (define_insn "gtv16qi3"
23408   [(set (match_operand:V16QI 0 "register_operand" "=x")
23409         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23410                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23411   "TARGET_SSE2"
23412   "pcmpgtb\t{%2, %0|%0, %2}"
23413   [(set_attr "type" "ssecmp")
23414    (set_attr "mode" "TI")])
23415
23416 (define_insn "gtv8hi3"
23417   [(set (match_operand:V8HI 0 "register_operand" "=x")
23418         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23419                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23420   "TARGET_SSE2"
23421   "pcmpgtw\t{%2, %0|%0, %2}"
23422   [(set_attr "type" "ssecmp")
23423    (set_attr "mode" "TI")])
23424
23425 (define_insn "gtv4si3"
23426   [(set (match_operand:V4SI 0 "register_operand" "=x")
23427         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23428                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23429   "TARGET_SSE2"
23430   "pcmpgtd\t{%2, %0|%0, %2}"
23431   [(set_attr "type" "ssecmp")
23432    (set_attr "mode" "TI")])
23433
23434
23435 ;; MMX max/min insns
23436
23437 (define_insn "umaxv16qi3"
23438   [(set (match_operand:V16QI 0 "register_operand" "=x")
23439         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23440                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23441   "TARGET_SSE2"
23442   "pmaxub\t{%2, %0|%0, %2}"
23443   [(set_attr "type" "sseiadd")
23444    (set_attr "mode" "TI")])
23445
23446 (define_insn "smaxv8hi3"
23447   [(set (match_operand:V8HI 0 "register_operand" "=x")
23448         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23449                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23450   "TARGET_SSE2"
23451   "pmaxsw\t{%2, %0|%0, %2}"
23452   [(set_attr "type" "sseiadd")
23453    (set_attr "mode" "TI")])
23454
23455 (define_insn "uminv16qi3"
23456   [(set (match_operand:V16QI 0 "register_operand" "=x")
23457         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23458                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23459   "TARGET_SSE2"
23460   "pminub\t{%2, %0|%0, %2}"
23461   [(set_attr "type" "sseiadd")
23462    (set_attr "mode" "TI")])
23463
23464 (define_insn "sminv8hi3"
23465   [(set (match_operand:V8HI 0 "register_operand" "=x")
23466         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23467                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23468   "TARGET_SSE2"
23469   "pminsw\t{%2, %0|%0, %2}"
23470   [(set_attr "type" "sseiadd")
23471    (set_attr "mode" "TI")])
23472
23473
23474 ;; MMX shifts
23475
23476 (define_insn "ashrv8hi3"
23477   [(set (match_operand:V8HI 0 "register_operand" "=x")
23478         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23479                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23480   "TARGET_SSE2"
23481   "psraw\t{%2, %0|%0, %2}"
23482   [(set_attr "type" "sseishft")
23483    (set_attr "mode" "TI")])
23484
23485 (define_insn "ashrv4si3"
23486   [(set (match_operand:V4SI 0 "register_operand" "=x")
23487         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23488                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23489   "TARGET_SSE2"
23490   "psrad\t{%2, %0|%0, %2}"
23491   [(set_attr "type" "sseishft")
23492    (set_attr "mode" "TI")])
23493
23494 (define_insn "lshrv8hi3"
23495   [(set (match_operand:V8HI 0 "register_operand" "=x")
23496         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23497                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23498   "TARGET_SSE2"
23499   "psrlw\t{%2, %0|%0, %2}"
23500   [(set_attr "type" "sseishft")
23501    (set_attr "mode" "TI")])
23502
23503 (define_insn "lshrv4si3"
23504   [(set (match_operand:V4SI 0 "register_operand" "=x")
23505         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23506                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23507   "TARGET_SSE2"
23508   "psrld\t{%2, %0|%0, %2}"
23509   [(set_attr "type" "sseishft")
23510    (set_attr "mode" "TI")])
23511
23512 (define_insn "lshrv2di3"
23513   [(set (match_operand:V2DI 0 "register_operand" "=x")
23514         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23515                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23516   "TARGET_SSE2"
23517   "psrlq\t{%2, %0|%0, %2}"
23518   [(set_attr "type" "sseishft")
23519    (set_attr "mode" "TI")])
23520
23521 (define_insn "ashlv8hi3"
23522   [(set (match_operand:V8HI 0 "register_operand" "=x")
23523         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23524                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23525   "TARGET_SSE2"
23526   "psllw\t{%2, %0|%0, %2}"
23527   [(set_attr "type" "sseishft")
23528    (set_attr "mode" "TI")])
23529
23530 (define_insn "ashlv4si3"
23531   [(set (match_operand:V4SI 0 "register_operand" "=x")
23532         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23533                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23534   "TARGET_SSE2"
23535   "pslld\t{%2, %0|%0, %2}"
23536   [(set_attr "type" "sseishft")
23537    (set_attr "mode" "TI")])
23538
23539 (define_insn "ashlv2di3"
23540   [(set (match_operand:V2DI 0 "register_operand" "=x")
23541         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23542                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23543   "TARGET_SSE2"
23544   "psllq\t{%2, %0|%0, %2}"
23545   [(set_attr "type" "sseishft")
23546    (set_attr "mode" "TI")])
23547
23548 (define_insn "ashrv8hi3_ti"
23549   [(set (match_operand:V8HI 0 "register_operand" "=x")
23550         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23551                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23552   "TARGET_SSE2"
23553   "psraw\t{%2, %0|%0, %2}"
23554   [(set_attr "type" "sseishft")
23555    (set_attr "mode" "TI")])
23556
23557 (define_insn "ashrv4si3_ti"
23558   [(set (match_operand:V4SI 0 "register_operand" "=x")
23559         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23560                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23561   "TARGET_SSE2"
23562   "psrad\t{%2, %0|%0, %2}"
23563   [(set_attr "type" "sseishft")
23564    (set_attr "mode" "TI")])
23565
23566 (define_insn "lshrv8hi3_ti"
23567   [(set (match_operand:V8HI 0 "register_operand" "=x")
23568         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23569                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23570   "TARGET_SSE2"
23571   "psrlw\t{%2, %0|%0, %2}"
23572   [(set_attr "type" "sseishft")
23573    (set_attr "mode" "TI")])
23574
23575 (define_insn "lshrv4si3_ti"
23576   [(set (match_operand:V4SI 0 "register_operand" "=x")
23577         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23578                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23579   "TARGET_SSE2"
23580   "psrld\t{%2, %0|%0, %2}"
23581   [(set_attr "type" "sseishft")
23582    (set_attr "mode" "TI")])
23583
23584 (define_insn "lshrv2di3_ti"
23585   [(set (match_operand:V2DI 0 "register_operand" "=x")
23586         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23587                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23588   "TARGET_SSE2"
23589   "psrlq\t{%2, %0|%0, %2}"
23590   [(set_attr "type" "sseishft")
23591    (set_attr "mode" "TI")])
23592
23593 (define_insn "ashlv8hi3_ti"
23594   [(set (match_operand:V8HI 0 "register_operand" "=x")
23595         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23596                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23597   "TARGET_SSE2"
23598   "psllw\t{%2, %0|%0, %2}"
23599   [(set_attr "type" "sseishft")
23600    (set_attr "mode" "TI")])
23601
23602 (define_insn "ashlv4si3_ti"
23603   [(set (match_operand:V4SI 0 "register_operand" "=x")
23604         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23605                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23606   "TARGET_SSE2"
23607   "pslld\t{%2, %0|%0, %2}"
23608   [(set_attr "type" "sseishft")
23609    (set_attr "mode" "TI")])
23610
23611 (define_insn "ashlv2di3_ti"
23612   [(set (match_operand:V2DI 0 "register_operand" "=x")
23613         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23614                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23615   "TARGET_SSE2"
23616   "psllq\t{%2, %0|%0, %2}"
23617   [(set_attr "type" "sseishft")
23618    (set_attr "mode" "TI")])
23619
23620 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23621 ;; we wouldn't need here it since we never generate TImode arithmetic.
23622
23623 ;; There has to be some kind of prize for the weirdest new instruction...
23624 (define_insn "sse2_ashlti3"
23625   [(set (match_operand:TI 0 "register_operand" "=x")
23626         (unspec:TI
23627          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23628                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23629                                (const_int 8)))] UNSPEC_NOP))]
23630   "TARGET_SSE2"
23631   "pslldq\t{%2, %0|%0, %2}"
23632   [(set_attr "type" "sseishft")
23633    (set_attr "mode" "TI")])
23634
23635 (define_insn "sse2_lshrti3"
23636   [(set (match_operand:TI 0 "register_operand" "=x")
23637         (unspec:TI
23638          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23639                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23640                                 (const_int 8)))] UNSPEC_NOP))]
23641   "TARGET_SSE2"
23642   "psrldq\t{%2, %0|%0, %2}"
23643   [(set_attr "type" "sseishft")
23644    (set_attr "mode" "TI")])
23645
23646 ;; SSE unpack
23647
23648 (define_insn "sse2_unpckhpd"
23649   [(set (match_operand:V2DF 0 "register_operand" "=x")
23650         (vec_concat:V2DF
23651          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23652                         (parallel [(const_int 1)]))
23653          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23654                         (parallel [(const_int 1)]))))]
23655   "TARGET_SSE2"
23656   "unpckhpd\t{%2, %0|%0, %2}"
23657   [(set_attr "type" "ssecvt")
23658    (set_attr "mode" "V2DF")])
23659
23660 (define_insn "sse2_unpcklpd"
23661   [(set (match_operand:V2DF 0 "register_operand" "=x")
23662         (vec_concat:V2DF
23663          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23664                         (parallel [(const_int 0)]))
23665          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23666                         (parallel [(const_int 0)]))))]
23667   "TARGET_SSE2"
23668   "unpcklpd\t{%2, %0|%0, %2}"
23669   [(set_attr "type" "ssecvt")
23670    (set_attr "mode" "V2DF")])
23671
23672 ;; MMX pack/unpack insns.
23673
23674 (define_insn "sse2_packsswb"
23675   [(set (match_operand:V16QI 0 "register_operand" "=x")
23676         (vec_concat:V16QI
23677          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23678          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23679   "TARGET_SSE2"
23680   "packsswb\t{%2, %0|%0, %2}"
23681   [(set_attr "type" "ssecvt")
23682    (set_attr "mode" "TI")])
23683
23684 (define_insn "sse2_packssdw"
23685   [(set (match_operand:V8HI 0 "register_operand" "=x")
23686         (vec_concat:V8HI
23687          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23688          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23689   "TARGET_SSE2"
23690   "packssdw\t{%2, %0|%0, %2}"
23691   [(set_attr "type" "ssecvt")
23692    (set_attr "mode" "TI")])
23693
23694 (define_insn "sse2_packuswb"
23695   [(set (match_operand:V16QI 0 "register_operand" "=x")
23696         (vec_concat:V16QI
23697          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23698          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23699   "TARGET_SSE2"
23700   "packuswb\t{%2, %0|%0, %2}"
23701   [(set_attr "type" "ssecvt")
23702    (set_attr "mode" "TI")])
23703
23704 (define_insn "sse2_punpckhbw"
23705   [(set (match_operand:V16QI 0 "register_operand" "=x")
23706         (vec_merge:V16QI
23707          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23708                            (parallel [(const_int 8) (const_int 0)
23709                                       (const_int 9) (const_int 1)
23710                                       (const_int 10) (const_int 2)
23711                                       (const_int 11) (const_int 3)
23712                                       (const_int 12) (const_int 4)
23713                                       (const_int 13) (const_int 5)
23714                                       (const_int 14) (const_int 6)
23715                                       (const_int 15) (const_int 7)]))
23716          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23717                            (parallel [(const_int 0) (const_int 8)
23718                                       (const_int 1) (const_int 9)
23719                                       (const_int 2) (const_int 10)
23720                                       (const_int 3) (const_int 11)
23721                                       (const_int 4) (const_int 12)
23722                                       (const_int 5) (const_int 13)
23723                                       (const_int 6) (const_int 14)
23724                                       (const_int 7) (const_int 15)]))
23725          (const_int 21845)))]
23726   "TARGET_SSE2"
23727   "punpckhbw\t{%2, %0|%0, %2}"
23728   [(set_attr "type" "ssecvt")
23729    (set_attr "mode" "TI")])
23730
23731 (define_insn "sse2_punpckhwd"
23732   [(set (match_operand:V8HI 0 "register_operand" "=x")
23733         (vec_merge:V8HI
23734          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23735                           (parallel [(const_int 4) (const_int 0)
23736                                      (const_int 5) (const_int 1)
23737                                      (const_int 6) (const_int 2)
23738                                      (const_int 7) (const_int 3)]))
23739          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23740                           (parallel [(const_int 0) (const_int 4)
23741                                      (const_int 1) (const_int 5)
23742                                      (const_int 2) (const_int 6)
23743                                      (const_int 3) (const_int 7)]))
23744          (const_int 85)))]
23745   "TARGET_SSE2"
23746   "punpckhwd\t{%2, %0|%0, %2}"
23747   [(set_attr "type" "ssecvt")
23748    (set_attr "mode" "TI")])
23749
23750 (define_insn "sse2_punpckhdq"
23751   [(set (match_operand:V4SI 0 "register_operand" "=x")
23752         (vec_merge:V4SI
23753          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23754                           (parallel [(const_int 2) (const_int 0)
23755                                      (const_int 3) (const_int 1)]))
23756          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23757                           (parallel [(const_int 0) (const_int 2)
23758                                      (const_int 1) (const_int 3)]))
23759          (const_int 5)))]
23760   "TARGET_SSE2"
23761   "punpckhdq\t{%2, %0|%0, %2}"
23762   [(set_attr "type" "ssecvt")
23763    (set_attr "mode" "TI")])
23764
23765 (define_insn "sse2_punpcklbw"
23766   [(set (match_operand:V16QI 0 "register_operand" "=x")
23767         (vec_merge:V16QI
23768          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23769                            (parallel [(const_int 0) (const_int 8)
23770                                       (const_int 1) (const_int 9)
23771                                       (const_int 2) (const_int 10)
23772                                       (const_int 3) (const_int 11)
23773                                       (const_int 4) (const_int 12)
23774                                       (const_int 5) (const_int 13)
23775                                       (const_int 6) (const_int 14)
23776                                       (const_int 7) (const_int 15)]))
23777          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23778                            (parallel [(const_int 8) (const_int 0)
23779                                       (const_int 9) (const_int 1)
23780                                       (const_int 10) (const_int 2)
23781                                       (const_int 11) (const_int 3)
23782                                       (const_int 12) (const_int 4)
23783                                       (const_int 13) (const_int 5)
23784                                       (const_int 14) (const_int 6)
23785                                       (const_int 15) (const_int 7)]))
23786          (const_int 21845)))]
23787   "TARGET_SSE2"
23788   "punpcklbw\t{%2, %0|%0, %2}"
23789   [(set_attr "type" "ssecvt")
23790    (set_attr "mode" "TI")])
23791
23792 (define_insn "sse2_punpcklwd"
23793   [(set (match_operand:V8HI 0 "register_operand" "=x")
23794         (vec_merge:V8HI
23795          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23796                           (parallel [(const_int 0) (const_int 4)
23797                                      (const_int 1) (const_int 5)
23798                                      (const_int 2) (const_int 6)
23799                                      (const_int 3) (const_int 7)]))
23800          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23801                           (parallel [(const_int 4) (const_int 0)
23802                                      (const_int 5) (const_int 1)
23803                                      (const_int 6) (const_int 2)
23804                                      (const_int 7) (const_int 3)]))
23805          (const_int 85)))]
23806   "TARGET_SSE2"
23807   "punpcklwd\t{%2, %0|%0, %2}"
23808   [(set_attr "type" "ssecvt")
23809    (set_attr "mode" "TI")])
23810
23811 (define_insn "sse2_punpckldq"
23812   [(set (match_operand:V4SI 0 "register_operand" "=x")
23813         (vec_merge:V4SI
23814          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23815                           (parallel [(const_int 0) (const_int 2)
23816                                      (const_int 1) (const_int 3)]))
23817          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23818                           (parallel [(const_int 2) (const_int 0)
23819                                      (const_int 3) (const_int 1)]))
23820          (const_int 5)))]
23821   "TARGET_SSE2"
23822   "punpckldq\t{%2, %0|%0, %2}"
23823   [(set_attr "type" "ssecvt")
23824    (set_attr "mode" "TI")])
23825
23826 (define_insn "sse2_punpcklqdq"
23827   [(set (match_operand:V2DI 0 "register_operand" "=x")
23828         (vec_merge:V2DI
23829          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23830                           (parallel [(const_int 1)
23831                                      (const_int 0)]))
23832          (match_operand:V2DI 1 "register_operand" "0")
23833          (const_int 1)))]
23834   "TARGET_SSE2"
23835   "punpcklqdq\t{%2, %0|%0, %2}"
23836   [(set_attr "type" "ssecvt")
23837    (set_attr "mode" "TI")])
23838
23839 (define_insn "sse2_punpckhqdq"
23840   [(set (match_operand:V2DI 0 "register_operand" "=x")
23841         (vec_merge:V2DI
23842          (match_operand:V2DI 1 "register_operand" "0")
23843          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23844                           (parallel [(const_int 1)
23845                                      (const_int 0)]))
23846          (const_int 1)))]
23847   "TARGET_SSE2"
23848   "punpckhqdq\t{%2, %0|%0, %2}"
23849   [(set_attr "type" "ssecvt")
23850    (set_attr "mode" "TI")])
23851
23852 ;; SSE2 moves
23853
23854 (define_insn "sse2_movapd"
23855   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23856         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23857                      UNSPEC_MOVA))]
23858   "TARGET_SSE2
23859    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23860   "movapd\t{%1, %0|%0, %1}"
23861   [(set_attr "type" "ssemov")
23862    (set_attr "mode" "V2DF")])
23863
23864 (define_insn "sse2_movupd"
23865   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23866         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23867                      UNSPEC_MOVU))]
23868   "TARGET_SSE2
23869    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23870   "movupd\t{%1, %0|%0, %1}"
23871   [(set_attr "type" "ssecvt")
23872    (set_attr "mode" "V2DF")])
23873
23874 (define_insn "sse2_movdqa"
23875   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23876         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23877                        UNSPEC_MOVA))]
23878   "TARGET_SSE2
23879    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23880   "movdqa\t{%1, %0|%0, %1}"
23881   [(set_attr "type" "ssemov")
23882    (set_attr "mode" "TI")])
23883
23884 (define_insn "sse2_movdqu"
23885   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23886         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23887                        UNSPEC_MOVU))]
23888   "TARGET_SSE2
23889    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23890   "movdqu\t{%1, %0|%0, %1}"
23891   [(set_attr "type" "ssecvt")
23892    (set_attr "mode" "TI")])
23893
23894 (define_insn "sse2_movdq2q"
23895   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23896         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23897                        (parallel [(const_int 0)])))]
23898   "TARGET_SSE2 && !TARGET_64BIT"
23899   "@
23900    movq\t{%1, %0|%0, %1}
23901    movdq2q\t{%1, %0|%0, %1}"
23902   [(set_attr "type" "ssecvt")
23903    (set_attr "mode" "TI")])
23904
23905 (define_insn "sse2_movdq2q_rex64"
23906   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23907         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23908                        (parallel [(const_int 0)])))]
23909   "TARGET_SSE2 && TARGET_64BIT"
23910   "@
23911    movq\t{%1, %0|%0, %1}
23912    movdq2q\t{%1, %0|%0, %1}
23913    movd\t{%1, %0|%0, %1}"
23914   [(set_attr "type" "ssecvt")
23915    (set_attr "mode" "TI")])
23916
23917 (define_insn "sse2_movq2dq"
23918   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23919         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23920                          (const_int 0)))]
23921   "TARGET_SSE2 && !TARGET_64BIT"
23922   "@
23923    movq\t{%1, %0|%0, %1}
23924    movq2dq\t{%1, %0|%0, %1}"
23925   [(set_attr "type" "ssecvt,ssemov")
23926    (set_attr "mode" "TI")])
23927
23928 (define_insn "sse2_movq2dq_rex64"
23929   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23930         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23931                          (const_int 0)))]
23932   "TARGET_SSE2 && TARGET_64BIT"
23933   "@
23934    movq\t{%1, %0|%0, %1}
23935    movq2dq\t{%1, %0|%0, %1}
23936    movd\t{%1, %0|%0, %1}"
23937   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23938    (set_attr "mode" "TI")])
23939
23940 (define_insn "sse2_movq"
23941   [(set (match_operand:V2DI 0 "register_operand" "=x")
23942         (vec_concat:V2DI (vec_select:DI
23943                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23944                           (parallel [(const_int 0)]))
23945                          (const_int 0)))]
23946   "TARGET_SSE2"
23947   "movq\t{%1, %0|%0, %1}"
23948   [(set_attr "type" "ssemov")
23949    (set_attr "mode" "TI")])
23950
23951 (define_insn "sse2_loadd"
23952   [(set (match_operand:V4SI 0 "register_operand" "=x")
23953         (vec_merge:V4SI
23954          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23955          (const_vector:V4SI [(const_int 0)
23956                              (const_int 0)
23957                              (const_int 0)
23958                              (const_int 0)])
23959          (const_int 1)))]
23960   "TARGET_SSE2"
23961   "movd\t{%1, %0|%0, %1}"
23962   [(set_attr "type" "ssemov")
23963    (set_attr "mode" "TI")])
23964
23965 (define_insn "sse2_stored"
23966   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23967         (vec_select:SI
23968          (match_operand:V4SI 1 "register_operand" "x")
23969          (parallel [(const_int 0)])))]
23970   "TARGET_SSE2"
23971   "movd\t{%1, %0|%0, %1}"
23972   [(set_attr "type" "ssemov")
23973    (set_attr "mode" "TI")])
23974
23975 (define_insn "sse2_movhpd"
23976   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23977         (vec_merge:V2DF
23978          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23979          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23980          (const_int 1)))]
23981   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23982   "movhpd\t{%2, %0|%0, %2}"
23983   [(set_attr "type" "ssecvt")
23984    (set_attr "mode" "V2DF")])
23985
23986 (define_expand "sse2_loadsd"
23987   [(match_operand:V2DF 0 "register_operand" "")
23988    (match_operand:DF 1 "memory_operand" "")]
23989   "TARGET_SSE2"
23990 {
23991   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23992                                 CONST0_RTX (V2DFmode)));
23993   DONE;
23994 })
23995
23996 (define_insn "sse2_loadsd_1"
23997   [(set (match_operand:V2DF 0 "register_operand" "=x")
23998         (vec_merge:V2DF
23999          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24000          (match_operand:V2DF 2 "const0_operand" "X")
24001          (const_int 1)))]
24002   "TARGET_SSE2"
24003   "movsd\t{%1, %0|%0, %1}"
24004   [(set_attr "type" "ssecvt")
24005    (set_attr "mode" "DF")])
24006
24007 (define_insn "sse2_movsd"
24008   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24009         (vec_merge:V2DF
24010          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24011          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24012          (const_int 2)))]
24013   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24014   "@movsd\t{%2, %0|%0, %2}
24015     movlpd\t{%2, %0|%0, %2}
24016     movlpd\t{%2, %0|%0, %2}"
24017   [(set_attr "type" "ssecvt")
24018    (set_attr "mode" "DF,V2DF,V2DF")])
24019
24020 (define_insn "sse2_storesd"
24021   [(set (match_operand:DF 0 "memory_operand" "=m")
24022         (vec_select:DF
24023          (match_operand:V2DF 1 "register_operand" "x")
24024          (parallel [(const_int 0)])))]
24025   "TARGET_SSE2"
24026   "movsd\t{%1, %0|%0, %1}"
24027   [(set_attr "type" "ssecvt")
24028    (set_attr "mode" "DF")])
24029
24030 (define_insn "sse2_shufpd"
24031   [(set (match_operand:V2DF 0 "register_operand" "=x")
24032         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24033                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24034                       (match_operand:SI 3 "immediate_operand" "i")]
24035                      UNSPEC_SHUFFLE))]
24036   "TARGET_SSE2"
24037   ;; @@@ check operand order for intel/nonintel syntax
24038   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24039   [(set_attr "type" "ssecvt")
24040    (set_attr "mode" "V2DF")])
24041
24042 (define_insn "sse2_clflush"
24043   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24044                     UNSPECV_CLFLUSH)]
24045   "TARGET_SSE2"
24046   "clflush\t%a0"
24047   [(set_attr "type" "sse")
24048    (set_attr "memory" "unknown")])
24049
24050 (define_expand "sse2_mfence"
24051   [(set (match_dup 0)
24052         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24053   "TARGET_SSE2"
24054 {
24055   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24056   MEM_VOLATILE_P (operands[0]) = 1;
24057 })
24058
24059 (define_insn "*mfence_insn"
24060   [(set (match_operand:BLK 0 "" "")
24061         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24062   "TARGET_SSE2"
24063   "mfence"
24064   [(set_attr "type" "sse")
24065    (set_attr "memory" "unknown")])
24066
24067 (define_expand "sse2_lfence"
24068   [(set (match_dup 0)
24069         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24070   "TARGET_SSE2"
24071 {
24072   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24073   MEM_VOLATILE_P (operands[0]) = 1;
24074 })
24075
24076 (define_insn "*lfence_insn"
24077   [(set (match_operand:BLK 0 "" "")
24078         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24079   "TARGET_SSE2"
24080   "lfence"
24081   [(set_attr "type" "sse")
24082    (set_attr "memory" "unknown")])
24083
24084 ;; SSE3
24085
24086 (define_insn "mwait"
24087   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24088                      (match_operand:SI 1 "register_operand" "c")]
24089                     UNSPECV_MWAIT)]
24090   "TARGET_SSE3"
24091   "mwait\t%0, %1"
24092   [(set_attr "length" "3")])
24093
24094 (define_insn "monitor"
24095   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24096                      (match_operand:SI 1 "register_operand" "c")
24097                      (match_operand:SI 2 "register_operand" "d")]
24098                     UNSPECV_MONITOR)]
24099   "TARGET_SSE3"
24100   "monitor\t%0, %1, %2"
24101   [(set_attr "length" "3")])
24102
24103 ;; SSE3 arithmetic
24104
24105 (define_insn "addsubv4sf3"
24106   [(set (match_operand:V4SF 0 "register_operand" "=x")
24107         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24108                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24109                      UNSPEC_ADDSUB))]
24110   "TARGET_SSE3"
24111   "addsubps\t{%2, %0|%0, %2}"
24112   [(set_attr "type" "sseadd")
24113    (set_attr "mode" "V4SF")])
24114
24115 (define_insn "addsubv2df3"
24116   [(set (match_operand:V2DF 0 "register_operand" "=x")
24117         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24118                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24119                      UNSPEC_ADDSUB))]
24120   "TARGET_SSE3"
24121   "addsubpd\t{%2, %0|%0, %2}"
24122   [(set_attr "type" "sseadd")
24123    (set_attr "mode" "V2DF")])
24124
24125 (define_insn "haddv4sf3"
24126   [(set (match_operand:V4SF 0 "register_operand" "=x")
24127         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24128                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24129                      UNSPEC_HADD))]
24130   "TARGET_SSE3"
24131   "haddps\t{%2, %0|%0, %2}"
24132   [(set_attr "type" "sseadd")
24133    (set_attr "mode" "V4SF")])
24134
24135 (define_insn "haddv2df3"
24136   [(set (match_operand:V2DF 0 "register_operand" "=x")
24137         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24138                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24139                      UNSPEC_HADD))]
24140   "TARGET_SSE3"
24141   "haddpd\t{%2, %0|%0, %2}"
24142   [(set_attr "type" "sseadd")
24143    (set_attr "mode" "V2DF")])
24144
24145 (define_insn "hsubv4sf3"
24146   [(set (match_operand:V4SF 0 "register_operand" "=x")
24147         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24148                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24149                      UNSPEC_HSUB))]
24150   "TARGET_SSE3"
24151   "hsubps\t{%2, %0|%0, %2}"
24152   [(set_attr "type" "sseadd")
24153    (set_attr "mode" "V4SF")])
24154
24155 (define_insn "hsubv2df3"
24156   [(set (match_operand:V2DF 0 "register_operand" "=x")
24157         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24158                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24159                      UNSPEC_HSUB))]
24160   "TARGET_SSE3"
24161   "hsubpd\t{%2, %0|%0, %2}"
24162   [(set_attr "type" "sseadd")
24163    (set_attr "mode" "V2DF")])
24164
24165 (define_insn "movshdup"
24166   [(set (match_operand:V4SF 0 "register_operand" "=x")
24167         (unspec:V4SF
24168          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24169   "TARGET_SSE3"
24170   "movshdup\t{%1, %0|%0, %1}"
24171   [(set_attr "type" "sse")
24172    (set_attr "mode" "V4SF")])
24173
24174 (define_insn "movsldup"
24175   [(set (match_operand:V4SF 0 "register_operand" "=x")
24176         (unspec:V4SF
24177          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24178   "TARGET_SSE3"
24179   "movsldup\t{%1, %0|%0, %1}"
24180   [(set_attr "type" "sse")
24181    (set_attr "mode" "V4SF")])
24182
24183 (define_insn "lddqu"
24184   [(set (match_operand:V16QI 0 "register_operand" "=x")
24185         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24186                        UNSPEC_LDQQU))]
24187   "TARGET_SSE3"
24188   "lddqu\t{%1, %0|%0, %1}"
24189   [(set_attr "type" "ssecvt")
24190    (set_attr "mode" "TI")])
24191
24192 (define_insn "loadddup"
24193   [(set (match_operand:V2DF 0 "register_operand" "=x")
24194         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24195   "TARGET_SSE3"
24196   "movddup\t{%1, %0|%0, %1}"
24197   [(set_attr "type" "ssecvt")
24198    (set_attr "mode" "DF")])
24199
24200 (define_insn "movddup"
24201   [(set (match_operand:V2DF 0 "register_operand" "=x")
24202         (vec_duplicate:V2DF
24203          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24204                         (parallel [(const_int 0)]))))]
24205   "TARGET_SSE3"
24206   "movddup\t{%1, %0|%0, %1}"
24207   [(set_attr "type" "ssecvt")
24208    (set_attr "mode" "DF")])